Repository navigation
MCP Integration
Brian Weisberg edited this page Feb 14, 2026
·
1 revision
Tooli apps can serve as Model Context Protocol tool servers with zero extra code. Each CLI command becomes an MCP tool, preserving type information, descriptions, and behavioral annotations.
# Export MCP tool definitions as JSON
mytool mcp export
# Start MCP server over stdio
mytool mcp serve --transport stdio
# Start MCP server over HTTP
mytool mcp serve --transport http --port 8080Tooli generates MCP tool definitions from the same source as CLI commands:
@app.command() decorated function
│
├──→ CLI command (Typer/Click)
├──→ JSON Schema (Pydantic)
└──→ MCP tool definition
├── name: app_name.command_name
├── description: from docstring
├── inputSchema: from JSON Schema
└── annotations: from @app.command() metadata
from tooli.mcp.export import export_mcp_tools
app = Tooli(name="file-tools", version="1.0.0")
@app.command(annotations=ReadOnly | Idempotent)
def find_files(pattern: str) -> list[dict]:
"""Find files matching a glob pattern."""
...
tools = export_mcp_tools(app)
# Returns list of MCP-compatible tool definitionsTooli command annotations map to MCP tool annotations:
| Tooli Annotation | MCP Hint |
|---|---|
ReadOnly |
readOnlyHint: true |
Destructive |
destructiveHint: true |
Idempotent |
idempotentHint: true |
OpenWorld |
openWorldHint: true |
The stdio transport follows the MCP specification: JSON-RPC messages over stdin/stdout. During MCP mode, strict stdout discipline is enforced — zero logging to stdout, all diagnostics go to stderr.
# Configure in Claude Desktop
{
"mcpServers": {
"file-tools": {
"command": "mytool",
"args": ["mcp", "serve", "--transport", "stdio"]
}
}
}ToolError exceptions become MCP error responses with isError: true. The structured error fields (code, message, suggestion) are preserved in the MCP response.
HTTP/SSE transport (Issue #18) allows remote MCP access:
mytool mcp serve --transport http --host 0.0.0.0 --port 8080