Skip to main content
CodeCall exposes four meta-tools that replace direct tool access. This page documents the complete API for each tool with request/response schemas and examples.

codecall:search

Search for tools by natural language query using semantic embeddings.

Request Schema

{
  "tool": "codecall:search",
  "input": {
    "queries": ["string (required) - Natural language search queries"],
    "topK": "number (optional, default: 5) - Maximum results to return",
    "appIds": ["string (optional) - Limit to specific apps"],
    "excludeToolNames": ["string (optional) - Tool names to exclude"],
    "minRelevanceScore": "number (optional) - Minimum relevance score threshold"
  }
}

Response Schema

{
  "tools": [
    {
      "name": "string - Tool name (e.g., 'users:list')",
      "appId": "string - Owning app ID",
      "description": "string - Tool description",
      "relevanceScore": "number - Relevance score (0-1)",
      "matchedQueries": ["string - Queries that matched this tool"]
    }
  ],
  "totalAvailableTools": "number - Total tools in index",
  "warnings": ["string (optional) - Any warnings about the search"]
}

Examples

{
  "tool": "codecall:search",
  "input": {
    "queries": ["get user profile information"],
    "topK": 5
  }
}

Response Example

{
  "tools": [
    {
      "name": "users:getProfile",
      "appId": "user-service",
      "description": "Get user profile by ID with full details",
      "relevanceScore": 0.94,
      "matchedQueries": ["get user profile information"]
    },
    {
      "name": "users:list",
      "appId": "user-service",
      "description": "List all users with pagination and filtering",
      "relevanceScore": 0.78,
      "matchedQueries": ["get user profile information"]
    },
    {
      "name": "auth:whoami",
      "appId": "auth-service",
      "description": "Get current authenticated user info",
      "relevanceScore": 0.72,
      "matchedQueries": ["get user profile information"]
    }
  ],
  "totalAvailableTools": 156
}

Search Strategy

CodeCall supports two embedding strategies:
StrategyDescriptionBest For
tfidfTF-IDF text matching (default)Fast, no model loading, works offline
mlSemantic embeddings via VectoriaDBBetter relevance, requires model
CodeCallPlugin.init({
  embedding: {
    strategy: 'tfidf',  // or 'ml'
  },
});

codecall:describe

Get detailed schemas and documentation for specific tools.

Request Schema

{
  "tool": "codecall:describe",
  "input": {
    "toolNames": ["string (required) - Array of tool names to describe"]
  }
}

Response Schema

{
  "tools": [
    {
      "name": "string - Tool name",
      "appId": "string - Owning app ID",
      "description": "string - Full description",
      "inputSchema": { /* JSON Schema */ },
      "outputSchema": { /* JSON Schema or null */ },
      "annotations": {
        "destructiveHint": "boolean (optional)",
        "idempotentHint": "boolean (optional)",
        "openWorldHint": "boolean (optional)"
      },
      "examples": [
        {
          "description": "string - Example description",
          "input": { /* Example input arguments */ },
          "output": { /* Expected output */ }
        }
      ]
    }
  ],
  "notFound": ["string (optional) - Tool names that weren't found"]
}
examples returns up to 5 examples per tool. User-provided examples from the @Tool decorator take priority, with smart-generated examples filling remaining slots based on tool intent (create, list, get, update, delete, search).

Example

{
  "tool": "codecall:describe",
  "input": {
    "toolNames": ["users:list", "users:getById"]
  }
}

Security Note

codecall:describe will not return information about CodeCall meta-tools themselves. Attempting to describe codecall:execute returns the tool in notFound.

codecall:execute

Execute a JavaScript (AgentScript) plan that orchestrates multiple tools.

Request Schema

{
  "tool": "codecall:execute",
  "input": {
    "script": "string (required) - JavaScript code to execute",
    "context": { /* (optional) - Read-only context available as codecallContext */ },
    "allowedTools": ["string (optional) - Whitelist of allowed tool names"]
  }
}

Response Schema

Success:
{
  "status": "ok",
  "result": "any - Return value from script",
  "logs": ["string (optional) - Console output if enabled"]
}
Error Responses:
{
  "status": "syntax_error",
  "error": {
    "message": "Unexpected token at line 5",
    "location": {"line": 5, "column": 12}
  }
}
{
  "status": "illegal_access",
  "error": {
    "kind": "IllegalBuiltinAccess",
    "message": "Identifier 'eval' is not allowed in AgentScript"
  }
}
{
  "status": "runtime_error",
  "error": {
    "source": "script",
    "message": "Cannot read property 'name' of undefined",
    "name": "TypeError"
  }
}
{
  "status": "tool_error",
  "error": {
    "source": "tool",
    "toolName": "users:list",
    "message": "Rate limit exceeded",
    "code": "RATE_LIMIT"
  }
}
{
  "status": "timeout",
  "error": {
    "message": "Script execution timed out after 3500ms"
  }
}

Example

{
  "tool": "codecall:execute",
  "input": {
    "script": "const users = await callTool('users:list', { status: 'active' });\nconst admins = users.users.filter(u => u.role === 'admin');\nreturn { adminCount: admins.length, admins: admins.map(a => a.email) };"
  }
}

AgentScript Guide

For the complete scripting API (callTool, getTool, codecallContext, __safe_parallel), error handling patterns, and best practices, see the dedicated AgentScript guide.

codecall:invoke

Direct tool invocation without JavaScript execution. Useful for simple single-tool calls.

Request Schema

{
  "tool": "codecall:invoke",
  "input": {
    "tool": "string (required) - Tool name to invoke",
    "input": { /* (required) - Input to pass to the tool */ }
  }
}

Response Schema

Success:
{
  "status": "ok",
  "result": "any - Tool return value"
}
Error:
{
  "status": "error",
  "error": {
    "code": "string - Error code",
    "message": "string - Error message"
  }
}

Example

{
  "tool": "codecall:invoke",
  "input": {
  "tool": "users:getById",
  "input": {"id": "user-123"}
}
}

When to Use Invoke vs Execute

Use codecall:invokeUse codecall:execute
Single tool callMultiple tool calls
No data transformation neededFilter/join/transform results
Latency-sensitive (no VM overhead)Complex orchestration logic
Simple CRUD operationsConditional workflows

Error Codes Reference

Script Execution Errors

CodeStatusDescriptionRecovery
SYNTAX_ERRORsyntax_errorJavaScript syntax errorFix syntax at indicated location
VALIDATION_ERRORillegal_accessAST validation failedRemove blocked construct
SELF_REFERENCE_BLOCKEDillegal_accessTried to call codecall:* toolUse regular tools only
TOOL_NOT_FOUNDtool_errorTool doesn’t existCheck tool name spelling
ACCESS_DENIEDtool_errorTool not in allowedToolsAdd to allowlist
EXECUTION_ERRORruntime_errorRuntime error in scriptDebug script logic
TIMEOUTtimeoutExceeded time limitOptimize or increase timeout
TOOL_EXECUTION_ERRORtool_errorTool threw an errorCheck tool input

Error Handling

For error handling patterns including retry, fallback, and partial success strategies, see the AgentScript Guide.

Debugging Guide

Using console.log

// Enable in config
CodeCallPlugin.init({
  vm: { allowConsole: true }
});

// In script
const users = await callTool('users:list', { limit: 10 });
console.log('Fetched users:', users.length);

for (const user of users) {
  console.log('Processing:', user.id, user.email);
}

// Logs appear in response.logs array

Interpreting Error Messages

Cause: Loop ran more than maxIterations times Fix: Use pagination or filter data before looping
// Bad: looping over potentially large dataset
for (const item of items) { ... }

// Good: paginate or limit
const page = items.slice(0, 100);
for (const item of page) { ... }
Cause: Script called more than maxToolCalls tools Fix: Batch operations or use __safe_parallel
// Bad: one tool call per item
for (const id of ids) {
  await callTool('users:get', { id });
}

// Good: batch fetch
const users = await callTool('users:getBatch', { ids });
Cause: Script ran longer than timeoutMs Fix: Optimize, use less data, or increase timeout
// Check preset timeout
// locked_down: 2s, secure: 3.5s, balanced: 5s
CodeCallPlugin.init({
  vm: { preset: 'balanced', timeoutMs: 8000 }
});
Cause: Used a blocked identifier (eval, require, etc.) Fix: Use allowed alternatives
// Blocked
eval('code');
require('module');
setTimeout(fn, 100);

// Allowed
// Use callTool for external operations
await callTool('code:run', { script: 'code' });

Development Mode

For easier debugging during development:
CodeCallPlugin.init({
  vm: {
    preset: 'experimental',  // Longer timeouts, more iterations
    allowConsole: true,
  },
});

Testing Strategy

Unit Testing AgentScript

Use the Enclave library directly to test script execution in isolation:
import { Enclave } from '@enclave-vm/core';

describe('AgentScript', () => {
  let enclave: Enclave;

  beforeEach(() => {
    enclave = new Enclave();
  });

  afterEach(() => {
    enclave.dispose();
  });

  it('should execute basic script', async () => {
    const result = await enclave.execute(`
      return 1 + 1;
    `);

    expect(result.success).toBe(true);
    expect(result.value).toBe(2);
  });

  it('should call tools', async () => {
    const mockToolHandler = jest.fn().mockResolvedValue({ users: [] });

    const result = await enclave.execute(`
      const data = await callTool('users:list', {});
      return data.users.length;
    `, { toolHandler: mockToolHandler });

    expect(mockToolHandler).toHaveBeenCalledWith('users:list', {});
    expect(result.value).toBe(0);
  });
});

Integration Testing

For end-to-end tests, set up a FrontMCP app with CodeCallPlugin and invoke the meta-tools through your MCP test client:
import { App, Tool, ToolContext } from '@frontmcp/sdk';
import { CodeCallPlugin } from '@frontmcp/plugins';

@App({ id: 'test-app', plugins: [CodeCallPlugin.init()] })
class TestApp {
  @Tool({ name: 'users:list' })
  async listUsers(ctx: ToolContext) {
    return [
      { id: '1', name: 'Alice' },
      { id: '2', name: 'Bob' },
    ];
  }
}

// Use your MCP test client to call codecall:execute
// and verify the response status and result

Testing Security Rules

describe('Security', () => {
  it('should block eval', async () => {
    const result = await enclave.execute(`
      eval('1 + 1');
    `);

    expect(result.success).toBe(false);
    expect(result.error?.message).toContain('eval');
  });

  it('should enforce iteration limit', async () => {
    const result = await enclave.execute(`
      let i = 0;
      for (const x of Array(100000)) { i++; }
      return i;
    `, { config: { maxIterations: 1000 } });

    expect(result.success).toBe(false);
    expect(result.error?.message).toContain('iteration limit');
  });
});

CI/CD Integration

# .github/workflows/test.yml
name: Test CodeCall Scripts

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - run: npm ci
      - run: npm test

      # Run CodeCall-specific security tests
      - run: npm run test:security


AgentScript Guide

Complete scripting API, error handling, and best practices

Configuration

Configure meta-tool behavior and limits

Security Model

How scripts are validated and sandboxed

Examples & Recipes

Real-world patterns using the meta-tools