Creating Your First Tool

This guide walks through the full lifecycle of an MCPBox tool — from asking your LLM to build something, to approving it, to using it.

The Tool Lifecycle

LLM creates tool (draft) → LLM requests approval →
Admin approves → LLM tests it → LLM starts server → Tool is live

By default, tools must be approved before they can be tested. This ensures the admin controls what code runs in the sandbox. If you prefer to let the LLM test tools before approval, change the Tool Approval Mode to auto_approve in Settings.

Step-by-Step Example

Ask your LLM something it can’t do yet. For example:

“Is Claude having issues right now? Build a tool to check.”

The LLM will use the mcpbox_* management tools to:

1. Create a Server

mcpbox_create_server(name="news", description="News and status tools")

Servers are containers that group related tools together.

2. Write the Tool Code

mcpbox_create_tool(
  server_id="<uuid>",
  name="claude_status",
  description="Check Anthropic service status",
  python_code='''
async def main() -> dict:
    """Check the Anthropic status page."""
    resp = await http.get("https://status.anthropic.com/api/v2/status.json")
    data = resp.json()
    return {
        "status": data["status"]["description"],
        "indicator": data["status"]["indicator"]
    }
'''
)

The tool is created in draft status — it can’t be used yet.

3. Request Approval

mcpbox_request_publish(
  tool_id="<uuid>",
  notes="Fetches Anthropic status page. Read-only HTTP request."
)

The tool moves to pending_review status.

4. Admin Approves

Open the MCPBox admin UI at http://localhost:3000 and go to the Approvals page. You’ll see the pending tool with:

  • Tool name and description
  • The full Python source code
  • The LLM’s notes explaining what the tool does

Review the code and click Approve (or Reject with a reason).

Approvals Page The Approvals page showing pending, needs-submission, and approved tools.

5. Test the Code

mcpbox_test_code(tool_id="<uuid>")

Now that the tool is approved, the LLM can test it in the sandbox. This runs the code and returns the result. If the test fails, the LLM can update the code — but note that code changes reset the approval status back to pending_review, requiring another approval before testing again.

6. Start the Server

mcpbox_start_server(server_id="<uuid>")

7. Use the Tool

The tool is now available. The LLM (or any connected MCP client) can call claude_status directly:

claude_status()
→ {"status": "All Systems Operational", "indicator": "none"}

The tool persists across sessions. Next time anyone asks about Claude’s status, the LLM just calls it — no rebuilding needed.

What’s Available in Tool Code

Every tool is an async def main() function with these globals:

Global Description
http SSRF-protected HTTP client (await http.get(url), http.post(url, json=...))
json The json module
datetime The datetime module
arguments Dict of input arguments
secrets Read-only dict of server secrets (e.g., secrets["API_KEY"])

Parameters of main() become the tool’s input schema automatically. Return values become the tool’s output.

Additional Python modules can be imported if they’re on the allowed list. Need a module that’s not allowed? The LLM can request it with mcpbox_request_module, and you approve it in the admin UI.

Next Steps