Skip to main content
Glama

create_tool

Generates and verifies a new Python MCP tool server when no existing tool can perform a task, then mounts it so its tools become callable.

Instructions

Create a new tool when none of your current tools can do what the task needs (a web API, live data, a computation). Write a complete Python MCP tool server script (MCPServer); AutoTool verifies it in a guarded subprocess, injects only the credentials it declares, and mounts it: its tools appear in your tool list (or call them through run_tool). If verification fails you get the error; fix the code and call create_tool again with the same name.

The script MUST follow this contract:

  • It is one self-contained file that runs as python <file>.py and serves MCP over stdio.

  • It uses from mcp.server.mcpserver import MCPServer and creates mcp = MCPServer("<tool_name>").

  • Every tool is a function decorated with @mcp.tool() with full type annotations and a docstring that explains what it does and each parameter. Prefer simple parameter types (str, int, float, bool) with sensible defaults. Return a str (plain text or json.dumps(...) of the result).

  • The file ends with: if name == "main": mcp.run()

  • Only import the standard library, httpx2, pydantic and mcp.

  • Use httpx2 with an explicit timeout of at most 10 seconds for network calls. Use public APIs, or APIs whose credentials the prompt lists as available environment variables. Never hard-code credentials.

  • Credentials: read each one with os.environ["NAME"] and declare every name you read at module level, e.g. REQUIRED_ENV = ["NAME"]. Only declared names are injected into the process. Send keys in headers when the API allows it; never return, log or put key values in error messages.

  • Make every external API base URL overridable through an environment variable named <SERVICE>_API_BASE (e.g. HN_API_BASE), defaulting to the real public URL.

  • Report failures the caller should see (an HTTP error status, nothing found) by raising ToolError("...") from mcp.server.mcpserver.exceptions, with a clear message that names the service and status. Let unexpected errors raise: they fail the call, and the traceback reaches the verification harness. Never return an error as a normal string, and never swallow exceptions.

  • No subprocesses, no filesystem writes, no eval/exec.

  • Keep the tool fast: bound fan-out (e.g. concurrent requests for at most ~30 items).

No credentials are available: only use public, keyless APIs and do not declare REQUIRED_ENV.

Structural reference:

import os

import httpx2
from mcp.server.mcpserver import MCPServer
from mcp.server.mcpserver.exceptions import ToolError

mcp = MCPServer("example_tool")
API_BASE = os.environ.get("EXAMPLE_API_BASE", "https://api.example.com")


@mcp.tool()
def get_thing(thing_id: int, verbose: bool = False) -> str:
    """Fetch a thing by id.

    Args:
        thing_id: Numeric id of the thing.
        verbose: Include extra fields.
    """
    with httpx2.Client(timeout=10) as client:
        resp = client.get(f"{API_BASE}/things/{thing_id}")
    if resp.status_code != 200:
        raise ToolError(f"Example API returned HTTP {resp.status_code} for thing {thing_id}")
    return resp.text


if __name__ == "__main__":
    mcp.run()

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
codeYesComplete Python source of the MCPServer tool script.
nameYessnake_case module name ending in _tool, e.g. 'weather_tool'.
test_toolNoTool to smoke-test (default: the first one).
test_argumentsNoSafe, realistic arguments for the smoke test.

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.1.0

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and does so thoroughly: guarded subprocess verification, credential injection limited to declared REQUIRED_ENV names, secret-handling rules, error-surfacing via ToolError vs. uncaught tracebacks, and sandbox prohibitions. This is exactly the behavioral context an agent needs before writing a script.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Long, but appropriately so for a code-generation contract: it front-loads the when-to-use sentence, then organizes requirements as a scannable bullet list plus a structural reference. The example script restates some contract points, a minor duplication.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema or annotations exist, yet the description covers the full lifecycle: script contract, allowed imports, credential declaration/injection, base-URL overridability, error reporting, sandbox limits, and performance bounds. Nothing needed to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so baseline is 3. The description goes beyond the schema by tying the name parameter to the retry workflow ("call create_tool again with the same name") and elaborating the code contract in detail.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Create a new tool") and immediately defines the scope and trigger ("when none of your current tools can do what the task needs"). It clearly distinguishes itself from the sibling run_tool, which it names as the invocation path for the resulting tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use it (no existing tool can perform the task) and what the alternative is (invoke mounted tools directly or via run_tool). It also gives recovery guidance: on verification failure, fix the code and call again with the same name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools