Skip to main content

Generate discoverable code from MCP servers for agent tool usage

Project description

mcp-coded-tools

PyPI version Python Versions License: MIT CI

Generate discoverable code from MCP servers for AI agent tool usage.

Why?

The Model Context Protocol (MCP) lets AI agents connect to external tools and data. However, as Anthropic's engineering post explains, loading hundreds or thousands of tool definitions directly into an agent's context window is inefficient:

  • Tool definitions consume excessive tokens (100K+ tokens for large tool sets)
  • Intermediate results flow through the context window repeatedly
  • Agents become slower and more expensive at scale

The solution: Present MCP servers as code APIs that agents can discover and use through a filesystem interface. This approach reduces token usage by up to 98.7% while enabling more powerful agent workflows.

The problem: Manually writing wrapper code for each MCP tool is tedious.

mcp-coded-tools: Automatically generate discoverable Python code from any MCP server.

Installation

pip install mcp-coded-tools

Quick Start

CLI Usage

# Generate code from popular MCP servers
mcp-coded-tools generate \
  --command "npx -y @modelcontextprotocol/server-github" \
  --output ./servers \
  --server-name github

# Generate from multiple servers for complete workflows
mcp-coded-tools generate \
  --command "npx -y @modelcontextprotocol/server-github" \
  --command "npx -y @modelcontextprotocol/server-postgres" \
  --command "python slack_mcp_server.py" \
  --output ./servers

# Watch mode for development (auto-regenerate on changes)
mcp-coded-tools generate \
  --command "python ./my_mcp_server.py" \
  --output ./tools \
  --watch

๐Ÿ’ก See POPULAR_MCP_SERVERS.md for 50+ popular servers and real-world use cases!

๐Ÿ’ก See WATCH_MODE.md for auto-regeneration during development!

Python API

import asyncio
from mcp-coded-tools import MCPCodeGenerator

async def main():
    generator = MCPCodeGenerator()

    # Connect to MCP server and generate code
    await generator.connect_and_scan([
        "npx", "-y", "@modelcontextprotocol/server-gdrive"
    ])

    generator.generate_code(
        output_dir="./servers",
        server_name="google_drive"
    )

    print("โœ“ Generated discoverable code!")

asyncio.run(main())

What Gets Generated

servers/
โ”œโ”€โ”€ google_drive/
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ get_document.py
โ”‚   โ”œโ”€โ”€ list_files.py
โ”‚   โ””โ”€โ”€ ...
โ”œโ”€โ”€ salesforce/
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ update_record.py
โ”‚   โ””โ”€โ”€ ...
โ””โ”€โ”€ _client.py

Each tool becomes a typed Python function:

# servers/google_drive/get_document.py
from typing import Optional, Dict, Any
from .._client import call_mcp_tool

async def get_document(
    document_id: str,
    fields: Optional[str] = None
) -> Dict[str, Any]:
    """
    Retrieves a document from Google Drive
    """
    return await call_mcp_tool(
        'gdrive_getDocument',
        {'documentId': document_id, 'fields': fields}
    )

Agent Usage

Agents discover tools by exploring the filesystem:

# Agent lists available servers
import os
servers = os.listdir('./servers')
# ['google_drive', 'salesforce', ...]

# Agent reads a specific tool
with open('./servers/google_drive/get_document.py') as f:
    tool_def = f.read()
    # Understands parameters, types, description

# Agent writes code to use tools
import servers.google_drive as gdrive
import servers.salesforce as sf

async def sync_meeting_notes():
    doc = await gdrive.get_document(document_id="abc123")
    
    await sf.update_record(
        object_type="Lead",
        record_id="xyz789",
        data={"Notes": doc['content']}
    )

Features

  • โœ… Automatic code generation from any MCP server
  • โœ… Type hints for better IDE support and agent understanding
  • โœ… Docstrings extracted from MCP tool descriptions
  • โœ… Multiple servers with automatic namespace separation
  • โœ… CLI and Python API for flexibility
  • โœ… Error handling with detailed logging
  • โœ… Async support for concurrent tool execution

Configuration

Server Discovery

By default, tool names are analyzed to extract server prefixes:

  • gdrive_getDocument โ†’ gdrive server
  • salesforce_updateRecord โ†’ salesforce server

Override with explicit server names:

generator.generate_code(
    output_dir="./servers",
    server_name="my_custom_name"
)

Custom Templates

Customize generated code using Jinja2 templates:

generator = MCPCodeGenerator(
    template_dir="./my_templates"
)

How It Works

  1. Connect: Establishes connection to MCP server via stdio, HTTP, or SSE
  2. Introspect: Queries server for all available tools using MCP protocol
  3. Parse: Extracts tool names, descriptions, and JSON schemas
  4. Generate: Creates typed Python functions with proper imports
  5. Organize: Structures code in discoverable filesystem hierarchy

Use Cases

๐Ÿข Enterprise Incident Response

Automate DevOps workflows across multiple systems:

mcp-coded-tools generate \
  --command "npx -y @modelcontextprotocol/server-postgres" \
  --command "npx -y @modelcontextprotocol/server-github" \
  --command "python slack_mcp_server.py" \
  --output ./devops_tools

Workflow: Query errors โ†’ Create issue โ†’ Notify team Token Savings: 98% (150K โ†’ 3K tokens) Cost Impact: $3.00 โ†’ $0.06 per incident

๐Ÿ“Š Data Analytics Pipeline

Process millions of rows without context pollution:

from data_tools.postgres import execute_query
from data_tools.slack import post_message

# Query 1M rows - stays in execution environment!
rows = await execute_query(
    query="SELECT * FROM transactions WHERE date > NOW() - INTERVAL '30 days'"
)

# Process data in code (never enters context)
import pandas as pd
df = pd.DataFrame(rows)
summary = df.groupby('user_id')['amount'].sum()

# Only summary goes to context
await post_message(
    channel='analytics',
    text=f"Processed {len(df):,} transactions, total: ${summary.sum():,.2f}"
)

Scale: Process TBs, not MBs ROI: $109M/year for 500 queries/day operation

๐Ÿค– Automated Code Review

Review PRs with AI assistance at scale:

mcp-coded-tools generate \
  --command "npx -y @modelcontextprotocol/server-github" \
  --command "npx -y @modelcontextprotocol/server-filesystem" \
  --command "npx -y @modelcontextprotocol/server-sequential-thinking" \
  --output ./code_review_tools

Impact: Review 1000s of PRs/day with consistent quality

๐Ÿ“š See examples/real_world_workflows.py for 5 complete production examples!

Development

# Clone repository
git clone https://github.com/bluman1/mcp-coded-tools.git
cd mcp-coded-tools

# Install in development mode
pip install -e ".[dev]"

# Run tests
pytest

# Format code
black src/ tests/
ruff check src/ tests/

# Type checking
mypy src/

Contributing

Contributions welcome! Please read CONTRIBUTING.md for guidelines.

License

MIT License - see LICENSE for details.

Credits

Inspired by Anthropic's engineering post on code execution with MCP.

Built by Michael Ogundare for the MCP community.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_coded_tools-0.1.0.tar.gz (22.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_coded_tools-0.1.0-py3-none-any.whl (17.8 kB view details)

Uploaded Python 3

File details

Details for the file mcp_coded_tools-0.1.0.tar.gz.

File metadata

  • Download URL: mcp_coded_tools-0.1.0.tar.gz
  • Upload date:
  • Size: 22.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.11

File hashes

Hashes for mcp_coded_tools-0.1.0.tar.gz
Algorithm Hash digest
SHA256 628c1aa44503d6d6adfec15090a70af1fd896d4fadb4c3a91ae2de7ee0ce319b
MD5 17f14bb26f5ada1583eb8ae1c6fe77db
BLAKE2b-256 6f77ea6aab7849e653e9a8dd89c1bf511c9b66e143aff1000d9f1687a595e7aa

See more details on using hashes here.

File details

Details for the file mcp_coded_tools-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for mcp_coded_tools-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 72d4a711e3047916baf3a78b72693851377c31de21ea384700ce92ada3b48fea
MD5 5f14358b00ace998efa9fa6c330ea6db
BLAKE2b-256 a7bd97160c1314d072c93d1c81e0379e2d079d5fcd6126b93c7fcec4922f04c5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page