---
title: Configuration
sidebarTitle: Configuration
description: Complete configuration reference for CodeCall plugin - modes, VM presets, embedding strategies, and per-tool metadata.
icon: gear
keywords: ['frontmcp', 'mcp', 'model context protocol', 'plugin', 'plugins', 'extension', 'codecall', 'agentscript', 'code execution', 'configuration', 'typescript']
---

<img
  noZoom
  className="hidden dark:block blog-full-image"
  src="/assets/banners/codecall-plugin/code-call-options.dark.png"
  alt="CodeCall configuration options"
/>
<img
  noZoom
  className="block dark:hidden blog-full-image"
  src="/assets/banners/codecall-plugin/code-call-options.light.png"
  alt="CodeCall configuration options"
/>

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

---

## Plugin Initialization

```ts
import { CodeCallPlugin } from '@frontmcp/plugin-codecall';

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.

### `codecall_only` (Recommended)

**Default mode.** Hides all tools from `list_tools`, exposes via CodeCall.

```ts
CodeCallPlugin.init({
  mode: 'codecall_only',
});
```

| Tool Location | Behavior                                |
| ------------- | --------------------------------------- |
| `list_tools`  | Only CodeCall meta-tools visible        |
| CodeCall      | All tools searchable and callable       |
| Override      | Set `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.

```ts
CodeCallPlugin.init({
  mode: 'codecall_opt_in',
});
```

| Tool Location | Behavior                                  |
| ------------- | ----------------------------------------- |
| `list_tools`  | All tools visible (default MCP behavior)  |
| CodeCall      | Only tools with `enabledInCodeCall: true` |

**Best for:** Gradual migration, mixed direct/CodeCall access.

### `metadata_driven`

Full control via per-tool metadata. No global assumptions.

```ts
CodeCallPlugin.init({
  mode: 'metadata_driven',
});
```

| Tool Location | Behavior                                      |
| ------------- | --------------------------------------------- |
| `list_tools`  | Based on `visibleInListTools` (default: true) |
| CodeCall      | Based on `enabledInCodeCall` (default: false) |

**Best for:** Small toolsets, fine-grained control.

---

## Per-Tool Metadata

Control individual tool behavior with the `codecall` metadata field:

```ts
@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

| Mode              | `enabledInCodeCall` default | `visibleInListTools` default |
| ----------------- | --------------------------- | ---------------------------- |
| `codecall_only`   | `true`                      | `false`                      |
| `codecall_opt_in` | `false`                     | `true`                       |
| `metadata_driven` | `false`                     | `true`                       |

### Common Patterns

<AccordionGroup>
  <Accordion title="Hide from list_tools, available in CodeCall">
    ```ts
    codecall: {
      enabledInCodeCall: true,
      visibleInListTools: false,
    }
    ```
    Use for: Most tools in `codecall_only` mode.
  </Accordion>

  <Accordion title="Visible everywhere">
    ```ts
    codecall: {
      enabledInCodeCall: true,
      visibleInListTools: true,
    }
    ```
    Use for: Core tools that should be directly accessible AND in CodeCall.
  </Accordion>

  <Accordion title="Direct access only, no CodeCall">
    ```ts
    codecall: {
      enabledInCodeCall: false,
      visibleInListTools: true,
    }
    ```
    Use for: Admin tools, destructive operations, tools requiring human review.
  </Accordion>

  <Accordion title="CodeCall meta-tools only">
    ```ts
    codecall: {
      enabledInCodeCall: false,
      visibleInListTools: true,
    }
    ```
    Applied automatically to `codecall:search`, `codecall:describe`, etc.
  </Accordion>
</AccordionGroup>

---

## Global Tool Filtering

Filter tools globally with `includeTools`:

```ts
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:

```ts
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:

```ts
CodeCallPlugin.init({
  vm: {
    // Use a preset (recommended)
    preset: 'secure',

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

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

### VM Presets

| Preset         | Timeout | Max Steps      | Console | Use Case                     |
| -------------- | ------- | -------------- | ------- | ---------------------------- |
| `locked_down`  | 2s      | 2,000          | No      | Ultra-sensitive environments |
| `secure`       | 3.5s    | 5,000          | Yes     | **Production default**       |
| `balanced`     | 5s      | 10,000         | Yes     | Complex workflows            |
| `experimental` | 10s     | 20,000         | Yes     | Development only             |

### Preset Details

<Tabs>
  <Tab title="locked_down">
    ```ts
    {
      preset: 'locked_down',
      timeoutMs: 2000,
      maxSteps: 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.
  </Tab>

  <Tab title="secure">
    ```ts
    {
      preset: 'secure',
      timeoutMs: 3500,
      maxSteps: 5000,
      allowConsole: true,
      allowLoops: false,  // Only for-of allowed
      disabledBuiltins: ['eval', 'Function', 'AsyncFunction'],
      disabledGlobals: [
        'require', 'process', 'fetch',
        'setTimeout', 'setInterval', 'setImmediate',
        'global', 'globalThis'
      ],
    }
    ```
    **When to use:** Most production deployments.
  </Tab>

  <Tab title="balanced">
    ```ts
    {
      preset: 'balanced',
      timeoutMs: 5000,
      maxSteps: 10000,
      allowConsole: true,
      allowLoops: true,  // for, for-of, while allowed
      disabledBuiltins: ['eval', 'Function', 'AsyncFunction'],
      disabledGlobals: ['require', 'process', 'fetch'],
    }
    ```
    **When to use:** Complex data processing, trusted model access.
  </Tab>

  <Tab title="experimental">
    ```ts
    {
      preset: 'experimental',
      timeoutMs: 10000,
      maxSteps: 20000,
      allowConsole: true,
      allowLoops: true,
      disabledBuiltins: ['eval', 'Function', 'AsyncFunction'],
      disabledGlobals: ['require', 'process'],
    }
    ```
    **When to use:** Development, testing, trusted internal tools.
  </Tab>
</Tabs>

### 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.

```ts
CodeCallPlugin.init({
  vm: {
    preset: 'secure',
  },

  sidecar: {
    enabled: true,                       // opt-in (default: false)
    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
    allowComposites: false,              // Block reference concatenation
  },
});
```

#### Sidecar Presets by Security Level

| Config              | STRICT | SECURE | STANDARD | PERMISSIVE |
| ------------------- | ------ | ------ | -------- | ---------- |
| maxTotalSize        | 16MB   | 64MB   | 256MB    | 1GB        |
| maxReferenceSize    | 4MB    | 16MB   | 64MB     | 256MB      |
| extractionThreshold | 64KB   | 256KB  | 1MB      | 4MB        |
| maxResolvedSize     | 8MB    | 32MB   | 128MB    | 512MB      |
| allowComposites     | No     | No     | Yes      | Yes        |

#### How Pass-by-Reference Works

```mermaid
sequenceDiagram
    participant Script
    participant Sidecar
    participant Tool

    Tool->>Sidecar: Returns large result (500KB)
    Sidecar->>Sidecar: Store with ref ID
    Sidecar->>Script: Return __REF_abc123__
    Script->>Script: Process ref ID (not data)
    Script->>Tool: Call with __REF_abc123__
    Sidecar->>Tool: Resolve ref → actual data
```

**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:

```ts
CodeCallPlugin.init({
  embedding: {
    // Search strategy
    strategy: 'tfidf' | 'ml',

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

### Strategy Comparison

| Strategy | Speed   | Relevance | Setup          | Best For                |
| -------- | ------- | --------- | -------------- | ----------------------- |
| `tfidf`  | ⚡ Fast | Good      | None           | Most use cases, offline |
| `ml`     | Slower  | Better    | Model download | Large toolsets (100+)   |

### TF-IDF Configuration

```ts
embedding: {
  strategy: 'tfidf',
}
```

TF-IDF extracts searchable text from:

- Tool name (tokenized: `users:list` → `users`, `list`)
- Description (weighted 3x)
- Key terms from description (4+ characters, no stop words)

### ML Configuration

```ts
embedding: {
  strategy: 'ml',
  modelName: 'Xenova/all-MiniLM-L6-v2',  // Default
  cacheDir: './.cache/transformers',
  useHNSW: true,  // For large toolsets (1000+)
}
```

<Note>
  ML strategy uses [VectoriaDB](https://github.com/agentfront/vectoriadb) internally. The model (~22MB) is downloaded on first use and cached locally.
</Note>

---

## Direct Invocation

Configure the `codecall:invoke` meta-tool for direct tool calls without VM overhead:

```ts
CodeCallPlugin.init({
  directCalls: {
    // Enable/disable codecall:invoke
    enabled: true,

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

### When to Use Direct Invoke

| Use `codecall:invoke`          | Use `codecall:execute`   |
| ------------------------------ | ------------------------ |
| Single tool, no transformation | Multi-tool orchestration |
| Latency-critical paths         | Data filtering/joining   |
| Simple CRUD operations         | Conditional logic        |
| Known tool name                | Dynamic 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
├─ VM execution: ~1-2ms
├─ Tool execution: ~varies
└─ Total overhead: ~3-5ms
```

### Error Response Format

```json
{
  "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

<Warning>
  Direct invocation bypasses VM security validation. Only enable for tools you trust completely.
</Warning>

- **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

```ts
import { App } from '@frontmcp/sdk';
import { CodeCallPlugin } from '@frontmcp/plugin-codecall';

@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',
      },

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

---

## Migration Guide

### From Direct Tools to CodeCall

<Steps>
  <Step title="Add CodeCallPlugin">
    ```ts
    plugins: [
      CodeCallPlugin.init({ mode: 'metadata_driven' }),
    ]
    ```
  </Step>

  <Step title="Mark Tools for CodeCall">
    ```ts
    @Tool({
      codecall: { enabledInCodeCall: true, visibleInListTools: true },
    })
    ```
  </Step>

  <Step title="Test Both Access Methods">
    Verify tools work via both direct calls and CodeCall.
  </Step>

  <Step title="Switch to codecall_only">
    ```ts
    CodeCallPlugin.init({ mode: 'codecall_only' })
    ```
  </Step>

  <Step title="Remove Direct Visibility">
    ```ts
    codecall: { enabledInCodeCall: true, visibleInListTools: false }
    ```
  </Step>
</Steps>

---

## Related

<CardGroup cols={2}>
  <Card title="Security Model" icon="shield" href="/frontmcp/plugins/codecall/security">
    Security implications of configuration choices
  </Card>
  <Card title="Production &amp; Scaling" icon="server" href="/frontmcp/plugins/codecall/production">
    Performance tuning and monitoring
  </Card>
  <Card title="AgentScript Guide" icon="scroll" href="/frontmcp/plugins/codecall/agentscript">
    Scripting language reference and best practices
  </Card>
  <Card title="API Reference" icon="book" href="/frontmcp/plugins/codecall/api-reference">
    Complete meta-tool schemas and examples
  </Card>
</CardGroup>
