Skip to main content

Convert any MCP server into an Agent Skill

Project description

mcp-skill

Turn any MCP server into a typed Python SDK.

Compile MCP tools into code.

mcp-skill introspects an MCP server and generates a Python class where each tool becomes a typed async method.

Before and After

Before

Agents call MCP tools through the model loop — one round-trip per tool call:

llm.call_tool("web_search_preview", {"query": "..."})
# → model decides next step → calls another tool → model decides again → ...

After

Agents call tools directly in code:

result = await app.web_search_preview(
    objective="find latest news",
    search_queries=["topic X 2026"]
)
# Agent processes result in code — no round-trip back to model

How It Works

┌─────────────┐      ┌───────────────┐      ┌────────────────────┐
│  MCP Server  │─────▶│  mcp-skill    │─────▶│  Generated Skill   │
│  (any URL)   │      │  CLI          │      │                    │
│              │      │               │      │  app.py            │
│  Tools:      │      │  1. Connect   │      │  ├─ Typed class    │
│  - search    │      │  2. Introspec │      │  ├─ Async methods  │
│  - fetch     │      │  3. Map types │      │  ├─ Auth + storage │
│  - ...       │      │  4. Generate  │      │  └─ JSON parsing   │
│              │      │  5. Validate  │      │                    │
└─────────────┘      └───────────────┘      │  SKILL.md          │
                                             │  └─ Agent docs     │
                                             └────────────────────┘
  1. Connects to the MCP server using fastmcp
  2. Introspects all available tools via list_tools()
  3. Converts each tool's JSON Schema into Python type annotations
  4. Generates a typed App class where each MCP tool becomes an async method
  5. Validates the output with ast.parseruffty
  6. Generates SKILL.md with tool documentation and usage examples for agents

Motivation

MCP servers give agents access to tools, but every tool call round-trips through the model — request tool, execute, full result back into context, decide next step. For large payloads or sequential calls, this burns tokens and adds latency.

Programmatic Tool Calling fixes this: the agent writes code that calls tools directly, without model round-trips per invocation. Fetch, filter, aggregate — all in one code block.

mcp-skill makes this possible by compiling any MCP server into a plain Python class. Each tool becomes a typed async method. The agent just writes Python.

from parallel_search.app import ParallelApp

app = ParallelApp(auth="sk-...")
result = await app.web_search_preview(
    objective="find latest news on topic X",
    search_queries=["topic X 2026"]
)

Setup

# Install with uv
uv pip install -e .

# Or use directly
uv run mcp-skill create --url https://your-mcp-server.com/mcp --auth api-key

Requires uv and Python 3.10+.

Usage

# Interactive mode — prompts for URL, auth type, etc.
mcp-skill create

# Non-interactive mode
mcp-skill create \
  --url https://search-mcp.parallel.ai/mcp \
  --auth api-key \
  --api-key YOUR_KEY \
  --name parallel-search \
  --non-interactive

Generated Output

The skill lands in .agents/skills/<name>/ as a Python package:

.agents/skills/parallel_search/
├── __init__.py
├── app.py          # Typed Python class wrapping the MCP server
└── SKILL.md        # Agent-facing docs, dependencies, and usage

Here's what the generated app.py looks like:

class ParallelApp:

    def __init__(self, url: str = "https://...", auth=None) -> None:
        ...

    async def web_search_preview(
        self,
        objective: str,
        search_queries: list[str],
    ) -> dict[str, Any]:
        """Search the web with multiple queries in parallel."""
        ...

    async def fetch_url(
        self,
        url: str,
        max_length: int = None,
    ) -> dict[str, Any]:
        """Fetch and extract content from a URL."""
        ...

    def list_tools(self):
        return [self.web_search_preview, self.fetch_url]

Each method connects to the MCP server, calls the underlying tool, and returns parsed JSON. Auth credentials are persisted to disk (~/.mcp-skill/<name>/) after first use — provide once, reuse automatically.

Who Is This For?

Developers building:

  • MCP-based agents that need direct tool access without model round-trips
  • Automation systems using MCP tools as programmatic building blocks
  • Code-execution agents using Programmatic Tool Calling

Current Limitations

  • Auth: Supports API key (Bearer or custom header), OAuth, and none — no mTLS or complex auth flows
  • Runtime dependency: Generated code depends on fastmcp for MCP client connections
  • Connection per call: Each method creates a new MCP client connection (no pooling)
  • Tools only: MCP resources and prompts not yet supported

Task List

Tracked improvements based on real-world usage:

  • Fix output directory path — Changed from .agents/skill/<name> to .agents/skills/<name>
  • Add dependency info to SKILL.md — Dependencies listed with uv and pip install commands
  • Generate __init__.py — Skill directory is a proper Python package
  • Post-generation validationast.parseruff checkty check with uvx fallback
  • Package-style imports — Moved app.py to skill root; import via from <skill>.app import <Class>
  • Persistent token storage — Disk-backed credential storage at ~/.mcp-skill/<name>/
  • Unified auth signature — All auth types use auth=None in __init__
  • Sanitize skill names — Hyphens/dots converted to underscores for valid Python identifiers
  • Support MCP resources and prompts — Currently only tools are introspected and generated

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_skill-0.2.0.tar.gz (172.5 kB view details)

Uploaded Source

Built Distribution

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

mcp_skill-0.2.0-py3-none-any.whl (18.1 kB view details)

Uploaded Python 3

File details

Details for the file mcp_skill-0.2.0.tar.gz.

File metadata

  • Download URL: mcp_skill-0.2.0.tar.gz
  • Upload date:
  • Size: 172.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for mcp_skill-0.2.0.tar.gz
Algorithm Hash digest
SHA256 9b27b9e319fab917ec077733626416f0c0691e5baa43e39bc9d607c093b927c8
MD5 50a438aa9b74f83e09044c46878a92a4
BLAKE2b-256 e1c68f23b196359f41579a866ab90841b103c38309a411cd0e93c899de192f3f

See more details on using hashes here.

File details

Details for the file mcp_skill-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: mcp_skill-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 18.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for mcp_skill-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 56fd06bf340954a8396715a80a283267456de7a0386564cac9b8fa4c63bd8986
MD5 77bd11e10117b2f83a3c34953478d8e0
BLAKE2b-256 3e81156fcdd7ed73ce44e5f636589ee6033b14b7198021d1573966dc71722be0

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