Search

Search the documentation

Protobox

Tools

Create custom functions your AI clients can call over MCP — API lookups, data transforms, code

Tools

A tool lets your AI client act — look up an order, fetch a record, run a calculation — instead of just talking. Define a tool once in Protobox and it's available over MCP to every connected client.

A tool is a name, a description, a JSON Schema for its inputs, and an execution target. Protobox handles the rest: input validation, execution, secret injection, error handling, and execution logging.

Tool Types

TypeExecution TargetBest For
httpCalls an external API endpointCRM lookups, payment APIs, order management
javascriptRuns your code in a sandboxData transforms, calculations, conditional logic
codeRuns a Python or JavaScript workerHeavier logic with an explicit entry point

Creating Tools

A tool definition is JSON. The shape is:

{
  "name": "lookup_order",
  "description": "Look up a customer order by order ID",
  "type": "http",
  "inputSchema": {
    "type": "object",
    "properties": {
      "order_id": {
        "type": "string",
        "description": "The order ID to look up"
      }
    },
    "required": ["order_id"]
  },
  "configuration": {
    "http": {
      "method": "GET",
      "url": "https://api.yourshop.com/orders/{{order_id}}",
      "headers": {
        "Authorization": "Bearer {{secret:shop_api_key}}"
      }
    }
  },
  "isEnabled": true,
  "tags": ["orders"]
}

Create it in the dashboard (Build → Tools → Add tool), register your own connector from the CLI, or POST the JSON definition:

# Register your own API as tools from an OpenAPI 3.x spec
protobox tools add-api --spec ./yourshop-openapi.json --name "Shop API"

# Or register a code connector from a JS or Python file
protobox tools add-code --file ./calculate-shipping.js
curl -X POST "https://platform.protobox.ai/api/v1/tools" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "lookup_order",
    "description": "Look up a customer order by order ID",
    "type": "http",
    "inputSchema": {
      "type": "object",
      "properties": {
        "order_id": { "type": "string", "description": "The order ID to look up" }
      },
      "required": ["order_id"]
    },
    "configuration": {
      "http": {
        "method": "GET",
        "url": "https://api.yourshop.com/orders/{{order_id}}",
        "headers": { "Authorization": "Bearer {{secret:shop_api_key}}" }
      }
    }
  }'

Run the tool directly to verify it works before exposing it:

protobox tools run lookup_order --args '{"order_id": "ORDER-12345"}'

Tools are addressed by name, and protobox tools run exits non-zero when the call fails — it doubles as a smoke check in scripts and CI. Simple arguments can also be passed as repeatable -a key=value flags.

Enabled tools are available on your workspace's MCP endpoint. For a focused set, add the tool to a toolset:

protobox toolsets add <toolset> lookup_order

HTTP Tools

The most common type. An http tool calls an external API when the client invokes it.

Template Variables

Use {{paramName}} in the URL, headers, or body template to inject input parameters from the tool call:

url:     https://api.yourshop.com/orders/{{order_id}}
headers: {"Authorization": "Bearer {{secret:shop_api_key}}"}
body:    {"email": "{{customer_email}}"}

Secrets

Never hardcode API keys in tool configs. Reference the secret store:

{{secret:shop_api_key}}

This resolves to an encrypted credential stored in Connect → Secrets at runtime. The value never appears in logs, tool configs, or MCP responses.

If you put an API key directly in a tool URL or header, it can appear in logs and tool definitions. Always use {{secret:name}} references.

JavaScript Tools

For logic that doesn't map to a simple API call — transforms, conditional routing, calculations — use a javascript tool. Your code runs in a sandbox and receives the inputs as args:

{
  "name": "calculate_shipping",
  "description": "Calculate shipping cost by weight and destination",
  "type": "javascript",
  "inputSchema": {
    "type": "object",
    "properties": {
      "weight": { "type": "number" },
      "destination": { "type": "string" }
    },
    "required": ["weight", "destination"]
  },
  "configuration": {
    "javascript": {
      "code": "const rate = args.destination.startsWith('US') ? 0.5 : 2.0;\nreturn { cost: args.weight * rate, currency: 'USD' };"
    }
  }
}

JavaScript tools are pure functions — inputs in, result out — running in an isolated sandbox.

How Clients Use Tools

The AI client decides when to call a tool based on the conversation and the tool's description:

What's the status of order ORDER-12345? callTool("lookup_order", {order_id: "ORDER-12345"}) GET /orders/ORDER-12345 {status: "shipped", tracking: "1Z999..."} Tool result Your order shipped! Tracking: 1Z999... User AI Client Protobox Your API

The client never sees the API URL, authentication, or response shape. It calls the tool by name and gets a result.

Manage Tools

# List tools (filter by app, or search names and descriptions)
protobox tools --app yourshop
protobox tools --search "order"

# Inspect a tool's schema, required args, and connection
protobox tools get lookup_order

# View recent executions with verdicts
protobox tools logs --tool <tool-id> --limit 20

# Unregister a custom connector
protobox tools remove <slug>

There is no CLI verb for editing a tool in place. To change the name or description a client sees, set a per-toolset override — protobox toolsets override <toolset> <tool> --name find_order --description "Find a customer order" — which applies live without touching the underlying tool. Enabling or disabling a connector's registration is an SDK operation (connectors.setRegistrationStatus).

Troubleshooting

What's Next

Toolsets

Group tools into collections scoped to specific clients

MCP

How tools are exposed to clients over MCP

Knowledge Base

Give clients searchable access to your documentation

SDK: Tools

Create and manage tools with @protoboxai/sdk

On this page