Skip to main content
This page covers all configuration options for the CodeCall plugin, from quick presets to fine-grained control.

Plugin Initialization

import { CodeCallPlugin } from '@frontmcp/plugins';

CodeCallPlugin.init({
  // Tool visibility mode
  mode: 'codecall_only' | 'codecall_opt_in' | 'metadata_driven',

  // VM/sandbox configuration
  vm: { /* ... */ },

  // Embedding/search configuration
  embedding: { /* ... */ },

  // Tool filtering
  includeTools: (tool) => boolean,

  // Direct invoke configuration
  directCalls: { /* ... */ },
});

Tool Visibility Modes

Control which tools appear in list_tools vs. CodeCall. Default mode. Hides all tools from list_tools, exposes via CodeCall.
CodeCallPlugin.init({
  mode: 'codecall_only',
});
Tool LocationBehavior
list_toolsOnly CodeCall meta-tools visible
CodeCallAll tools searchable and callable
OverrideSet visibleInListTools: true per tool
Best for: Large toolsets (20+), OpenAPI adapters, clean client experience.

codecall_opt_in

Tools must explicitly opt into CodeCall. All tools visible in list_tools by default.
CodeCallPlugin.init({
  mode: 'codecall_opt_in',
});
Tool LocationBehavior
list_toolsAll tools visible (default MCP behavior)
CodeCallOnly tools with enabledInCodeCall: true
Best for: Gradual migration, mixed direct/CodeCall access.

metadata_driven

Full control via per-tool metadata. No global assumptions.
CodeCallPlugin.init({
  mode: 'metadata_driven',
});
Tool LocationBehavior
list_toolsBased on visibleInListTools (default: true)
CodeCallBased on enabledInCodeCall (default: false)
Best for: Small toolsets, fine-grained control.

Per-Tool Metadata

Control individual tool behavior with the codecall metadata field:
@Tool({
  name: 'users:list',
  description: 'List all users',
  codecall: {
    // Is this tool searchable and callable via CodeCall?
    enabledInCodeCall: true,  // default depends on mode

    // Is this tool visible in standard list_tools?
    visibleInListTools: false,  // default depends on mode

    // App ID for multi-app filtering (auto-detected if not set)
    appId: 'user-service',
  },
})

Metadata by Mode

ModeenabledInCodeCall defaultvisibleInListTools default
codecall_onlytruefalse
codecall_opt_infalsetrue
metadata_drivenfalsetrue

Common Patterns

codecall: {
  enabledInCodeCall: true,
  visibleInListTools: false,
}
Use for: Most tools in codecall_only mode.
codecall: {
  enabledInCodeCall: true,
  visibleInListTools: true,
}
Use for: Core tools that should be directly accessible AND in CodeCall.
codecall: {
  enabledInCodeCall: false,
  visibleInListTools: true,
}
Use for: Admin tools, destructive operations, tools requiring human review.
codecall: {
  enabledInCodeCall: false,
  visibleInListTools: true,
}
Applied automatically to codecall:search, codecall:describe, etc.

Global Tool Filtering

Filter tools globally with includeTools:
CodeCallPlugin.init({
  mode: 'codecall_only',

  // Only include tools matching this filter
  includeTools: (tool) => {
    // Exclude admin tools
    if (tool.name.startsWith('admin:')) return false;

    // Exclude destructive tools
    if (tool.metadata?.annotations?.destructiveHint) return false;

    // Include everything else
    return true;
  },
});
The filter receives a ToolEntry with:
interface ToolEntry {
  name: string;
  fullName: string;
  metadata?: {
    description?: string;
    annotations?: {
      destructiveHint?: boolean;
      idempotentHint?: boolean;
      readOnlyHint?: boolean;
    };
    codecall?: {
      enabledInCodeCall?: boolean;
      visibleInListTools?: boolean;
      appId?: string;
    };
  };
  owner?: { id: string };
}

VM Configuration

Configure the JavaScript sandbox:
CodeCallPlugin.init({
  vm: {
    // Use a preset (recommended)
    preset: 'secure',

    // Or override individual settings
    timeoutMs: 5000,
    maxIterations: 10000,
    allowConsole: true,

    // Blocked identifiers (in addition to preset)
    disabledBuiltins: ['eval', 'Function'],
    disabledGlobals: ['process', 'require'],
  },
});

VM Presets

PresetTimeoutMax IterationsConsoleUse Case
locked_down2s2,000NoUltra-sensitive environments
secure3.5s5,000YesProduction default
balanced5s10,000YesComplex workflows
experimental10s20,000YesDevelopment only

Preset Details

{
  preset: 'locked_down',
  timeoutMs: 2000,
  maxIterations: 2000,
  allowConsole: false,
  allowLoops: false,  // Only for-of allowed
  disabledBuiltins: ['eval', 'Function', 'AsyncFunction'],
  disabledGlobals: [
    'require', 'process', 'fetch',
    'setTimeout', 'setInterval', 'setImmediate',
    'global', 'globalThis'
  ],
}
When to use: Healthcare, finance, PII processing, compliance-heavy environments.

Worker Pool Configuration (Advanced)

For OS-level memory isolation, configure the Worker Pool adapter:
CodeCallPlugin.init({
  vm: {
    preset: 'secure',
    adapter: 'worker_threads',  // Enable Worker Pool

    workerPool: {
      minWorkers: 2,              // Minimum warm workers
      maxWorkers: 8,              // Maximum concurrent workers
      memoryLimitPerWorker: 128 * 1024 * 1024,  // 128MB per worker
      maxExecutionsPerWorker: 500,  // Recycle after N executions
      maxMessagesPerSecond: 500,    // Rate limit per worker
      maxPendingToolCalls: 50,      // Max concurrent tool calls
      idleTimeoutMs: 30000,         // Release idle workers after 30s
      queueTimeoutMs: 20000,        // Max queue wait time
      maxQueueSize: 50,             // Max pending executions
    },
  },
});

Worker Pool Presets by Security Level

ConfigSTRICTSECURESTANDARDPERMISSIVE
minWorkers2224
maxWorkers481632
memoryLimitPerWorker64MB128MB256MB512MB
maxExecutionsPerWorker1005001,0005,000
maxMessagesPerSecond1005001,0005,000
maxPendingToolCalls10501001,000
maxQueueSize2050100500
maxMessageSizeBytes1MB4MB16MB64MB

Reference Sidecar Configuration (Pass-by-Reference)

The Reference Sidecar handles large data transfer between scripts and tools. Instead of passing full data through the VM, large values are stored externally with reference IDs.
CodeCallPlugin.init({
  vm: {
    preset: 'secure',

    sidecar: {
      maxTotalSize: 64 * 1024 * 1024,     // 64MB total storage
      maxReferenceSize: 16 * 1024 * 1024,  // 16MB per reference
      extractionThreshold: 256 * 1024,     // Extract strings > 256KB
      maxResolvedSize: 32 * 1024 * 1024,   // 32MB max when resolving
      maxReferenceCount: 100,              // Max 100 references
      maxResolutionDepth: 10,              // Max nesting depth
      allowComposites: false,              // Block reference concatenation
    },
  },
});

Sidecar Presets by Security Level

ConfigSTRICTSECURESTANDARDPERMISSIVE
maxTotalSize16MB64MB256MB1GB
maxReferenceSize4MB16MB64MB256MB
extractionThreshold64KB256KB1MB4MB
maxResolvedSize8MB32MB128MB512MB
maxReferenceCount501005001,000
maxResolutionDepth5102050
allowCompositesNoNoYesYes

How Pass-by-Reference Works

Benefits:
  • Scripts don’t need to handle large data in memory
  • VM stays lightweight and secure
  • Tool results can exceed VM memory limits
  • Reference IDs are opaque strings (no data leakage)

Embedding Configuration

Configure how tools are indexed for search:
CodeCallPlugin.init({
  embedding: {
    // Search strategy
    strategy: 'tfidf' | 'embedding',

    // TF-IDF specific
    similarityThreshold: 0.3,

    // Embedding specific (requires VectoriaDB)
    modelName: 'Xenova/all-MiniLM-L6-v2',
    cacheDir: './.cache/transformers',
  },
});

Strategy Comparison

StrategySpeedRelevanceSetupBest For
tfidf⚡ FastGoodNoneMost use cases, offline
embeddingSlowerBetterModel downloadLarge toolsets (100+)

TF-IDF Configuration

embedding: {
  strategy: 'tfidf',
  similarityThreshold: 0.3,  // Minimum score to include in results
}
TF-IDF extracts searchable text from:
  • Tool name (tokenized: users:listusers, list)
  • Description (weighted 3x)
  • Key terms from description (4+ characters, no stop words)

Embedding Configuration

embedding: {
  strategy: 'embedding',
  modelName: 'Xenova/all-MiniLM-L6-v2',  // Default
  cacheDir: './.cache/transformers',
  useHNSW: true,  // For large toolsets (1000+)
}
Embedding strategy uses VectoriaDB internally. The model (~22MB) is downloaded on first use and cached locally.

Tool Search Tuning

Fine-tune how codecall:search finds and ranks tools:
CodeCallPlugin.init({
  embedding: {
    strategy: 'tfidf',

    search: {
      // Term weighting (higher = more important)
      weights: {
        name: 2.0,         // Tool name matches
        description: 3.0,  // Description matches (most important)
        tags: 2.0,         // Tag matches
      },

      // Stop words to ignore during tokenization
      stopWords: ['the', 'a', 'an', 'is', 'are', 'to', 'for'],

      // Minimum score to include in results
      minScore: 0.25,

      // Maximum results to return
      maxResults: 10,
    },
  },
});

Scoring Mechanics

When a user searches for “list users”, the scoring works:
Tool: users:list
- Name match "users" + "list": 2.0 × 2 = 4.0
- Description "List all users in the system": 3.0 × 3 = 9.0
- Tags ["users", "list", "admin"]: 2.0 × 2 = 4.0
- Total: 17.0 (normalized)

Optimizing for Large Toolsets (100+)

For large toolsets, consider these optimizations:
CodeCallPlugin.init({
  embedding: {
    strategy: 'embedding',  // Better semantic matching

    search: {
      // Pre-filter by namespace before semantic search
      prefixFilter: true,

      // Use approximate nearest neighbor for speed
      useHNSW: true,
      hnswEfConstruction: 200,  // Index quality
      hnswEfSearch: 100,        // Search quality vs speed

      // Batch indexing for startup performance
      batchSize: 100,
    },
  },
});

Direct Invocation

Configure the codecall:invoke meta-tool for direct tool calls without VM overhead:
CodeCallPlugin.init({
  directCalls: {
    // Enable/disable codecall:invoke
    enabled: true,

    // Optional: restrict to specific tools
    allowedTools: ['users:getById', 'billing:getInvoice'],

    // Optional: timeout for direct calls (default: 30s)
    timeoutMs: 30000,
  },
});

When to Use Direct Invoke

Use codecall:invokeUse codecall:execute
Single tool, no transformationMulti-tool orchestration
Latency-critical pathsData filtering/joining
Simple CRUD operationsConditional logic
Known tool nameDynamic tool selection

Performance Comparison

codecall:invoke (direct)
├─ Parse input: ~0.1ms
├─ Tool lookup: ~0.1ms
├─ Tool execution: ~varies
└─ Total overhead: ~0.2ms

codecall:execute (VM)
├─ Pre-scan: ~0.5ms
├─ AST validation: ~1-2ms
├─ Code transformation: ~0.5ms
├─ AI scoring: ~1ms (if enabled)
├─ VM execution: ~1-2ms
├─ Tool execution: ~varies
└─ Total overhead: ~4-6ms

Error Response Format

{
  "status": "error",
  "error": {
    "code": "TOOL_NOT_FOUND",
    "message": "Tool 'users:delete' is not in the allowed list",
    "tool": "users:delete",
    "allowedTools": ["users:getById", "billing:getInvoice"]
  }
}

Security Considerations

Direct invocation bypasses the AI Scoring Gate. Only enable for tools you trust completely.
  • allowedTools: Always specify an explicit allowlist in production
  • No script execution: Direct calls cannot run arbitrary code
  • Same tool access rules: Tool Access Control (whitelist/blacklist) still applies
  • Audit logging: Direct calls are logged the same as scripted calls

Complete Configuration Example

import { App } from '@frontmcp/sdk';
import { CodeCallPlugin } from '@frontmcp/plugins';

@App({
  id: 'my-app',
  plugins: [
    CodeCallPlugin.init({
      // Hide all tools, expose via CodeCall
      mode: 'codecall_only',

      // Filter out admin and destructive tools
      includeTools: (tool) => {
        if (tool.name.startsWith('admin:')) return false;
        if (tool.metadata?.annotations?.destructiveHint) return false;
        return true;
      },

      // Secure sandbox with custom timeout
      vm: {
        preset: 'secure',
        timeoutMs: 5000,  // 5 second timeout
        allowConsole: true,
      },

      // Fast TF-IDF search
      embedding: {
        strategy: 'tfidf',
        similarityThreshold: 0.25,
      },

      // Enable direct invocation for simple calls
      directCalls: {
        enabled: true,
        allowedTools: ['users:getById', 'health:ping'],
      },
    }),
  ],
})
export default class MyApp {}

Environment Variables

Override configuration via environment variables:
VariableOverridesExample
CODECALL_VM_TIMEOUTvm.timeoutMs5000
CODECALL_VM_PRESETvm.presetsecure
CODECALL_EMBEDDING_STRATEGYembedding.strategytfidf
CODECALL_MODEmodecodecall_only
CODECALL_VM_TIMEOUT=10000 CODECALL_MODE=codecall_opt_in npm start

Migration Guide

From Direct Tools to CodeCall

1

Add CodeCallPlugin

plugins: [
  CodeCallPlugin.init({ mode: 'metadata_driven' }),
]
2

Mark Tools for CodeCall

@Tool({
  codecall: { enabledInCodeCall: true, visibleInListTools: true },
})
3

Test Both Access Methods

Verify tools work via both direct calls and CodeCall.
4

Switch to codecall_only

CodeCallPlugin.init({ mode: 'codecall_only' })
5

Remove Direct Visibility

codecall: { enabledInCodeCall: true, visibleInListTools: false }