Skip to main content

Generate MCP servers from plain-English skill descriptions

Project description

skill-to-mcp

Turn a plain-English skill description into a working MCP server in seconds.

Python License: MIT Tests PyPI version Python Versions PyPI Downloads Coverage

skill-to-mcp demo

skill-to-mcp is a CLI code generator that reads a SKILL.md file — a plain-English description of a tool — and scaffolds a complete, runnable MCP (Model Context Protocol) server with:

  • ✅ Correct JSON-RPC schema (tool_name, description, inputSchema, outputSchema)
  • ✅ Pydantic v2 models for type-safe input/output
  • ✅ MCP server boilerplate (stdio or HTTP SSE transport)
  • pyproject.toml ready for pip install
  • ✅ Auto-generated README.md with usage instructions

📖 Leggi in Italiano


Why?

Describing a tool in Markdown is more readable, versionable, and composable than hand-writing JSON-RPC schemas. skill-to-mcp bridges the gap between "I know what my tool does" and "I have a working MCP server."

Read the full motivation: SKILL.md might be a better abstraction than function calling


Apify Actor

Run skill-to-mcp on the Apify platform:

docker build -t skill-to-mcp .
docker run -e DEEPSEEK_API_KEY=sk-... skill-to-mcp

The Apify Actor accepts the same inputs as the CLI via a web form: Skill Description (required), LLM Model, MCP Transport, Generate Example Implementation, and API Key.

Output is pushed to the Apify Dataset and a ZIP archive of all generated files is saved to the key-value store.

The Actor builds directly from this git repository via .actor/actor.json and the root Dockerfile (entry point: python -m skill_to_mcp.actor).

📖 Apify Actor documentation


Quick Start

1. Install

pip install skillmd-to-mcp

2. Set your API key

export DEEPSEEK_API_KEY="sk-your-key-here"

Get a key at platform.deepseek.com. Cost per generation: < $0.001 with DeepSeek.

OpenAI fallback: If you have an OpenAI key, set OPENAI_API_KEY instead. The CLI automatically tries both: DEEPSEEK_API_KEY first, then OPENAI_API_KEY.

3. Create a SKILL.md

# webpage-reader

Fetches a web page given a URL and returns:
- title: the page title
- description: the meta description
- body_text: visible text stripped of HTML
- links: list of the first 10 internal links

## Input

- url: string, required
- max_links: integer, default 10

4. Generate the MCP server

skill-to-mcp generate SKILL.md

Output:

output/
└── webpage-reader/
    ├── server.py          # MCP server, runnable immediately
    ├── models.py          # Pydantic v2 input/output models
    ├── handler.py         # Tool logic (stub — implement here)
    ├── pyproject.toml     # Dependencies and metadata
    └── README.md          # Installation and usage guide

5. Implement & Run

cd output/webpage-reader
pip install -e .
# Edit handler.py to add your business logic
python server.py

CLI Reference

skill-to-mcp generate SKILL.md [OPTIONS]

Arguments

Argument Description
SKILL.md Path to the skill description file

Options

Option Short Default Description
--output-dir -o ./output Output directory for generated files
--model -m deepseek-v4-flash LLM model for schema inference
--api-key -k $DEEPSEEK_API_KEY or $OPENAI_API_KEY API key for the LLM provider. Falls back to OPENAI_API_KEY if DEEPSEEK_API_KEY is not set
--transport -t stdio MCP transport: stdio or sse
--dry-run false Show inferred schema without generating files
--prompt-file -p Custom system prompt for LLM inference
--with-example-impl false Generate a working handler implementation via LLM
--templates-dir Custom Jinja2 templates directory
--verbose -v false Enable debug logging

Batch Processing

Process multiple SKILL.md files at once:

skill-to-mcp generate tool1.md tool2.md tool3.md -o ./my-tools
skill-to-mcp generate *.md --with-example-impl

Examples

# Basic usage
skill-to-mcp generate SKILL.md

# Preview the inferred schema (no files written)
skill-to-mcp generate SKILL.md --dry-run

# Use SSE transport for HTTP-based MCP hosts
skill-to-mcp generate SKILL.md --transport sse

# Custom output directory
skill-to-mcp generate SKILL.md -o ./my-mcp-tools

# Use a specific model
skill-to-mcp generate SKILL.md -m deepseek-v4-flash

# Custom LLM prompt
skill-to-mcp generate SKILL.md --prompt-file my_prompt.txt

# Verbose output for debugging
skill-to-mcp generate SKILL.md -v

Architecture

flowchart LR
    A[SKILL.md] --> B[parser.py]
    B --> C[llm.py]
    C --> D[DeepSeek API]
    D --> E[validator.py]
    E -->|valid| F[renderer.py]
    E -->|invalid + retry| C
    F --> G[templates/]
    G --> H[output/]

Pipeline

  1. parser.py — Reads SKILL.md, extracts title and sections
  2. llm.py — Calls DeepSeek API (OpenAI-compatible) to infer JSON Schema
  3. validator.py — Validates schema (types, snake_case, required fields)
  4. renderer.py — Applies Jinja2 templates to generate Python code
  5. cli.py — Typer-based CLI with Rich output

LLM Prompt

The system prompt is transparent and overridable. View the default in config.py or customize with --prompt-file.


MCP Host Configuration

Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "my-tool": {
      "command": "python",
      "args": ["path/to/output/my-tool/server.py"]
    }
  }
}

Cursor IDE

Add to .cursor/mcp.json:

{
  "mcpServers": {
    "my-tool": {
      "command": "python",
      "args": ["path/to/output/my-tool/server.py"]
    }
  }
}

SSE Transport

For HTTP-based MCP hosts:

skill-to-mcp generate SKILL.md --transport sse
cd output/my-tool && python server.py
# MCP endpoint: http://127.0.0.1:8000/sse

Development

Setup

git clone https://github.com/YOUR_USERNAME/skill-to-mcp
cd skill-to-mcp
pip install -e ".[dev]"

Run Tests

# All tests (99 total)
pytest tests/ -v

# End-to-end only
pytest tests/test_e2e.py -v

# With real API (requires DEEPSEEK_API_KEY)
DEEPSEEK_API_KEY="sk-..." skill-to-mcp generate tests/fixtures/simple_skill.md --dry-run

Code Quality

ruff check skill_to_mcp/ tests/

Tech Stack

Component Technology
CLI Framework Typer
Templates Jinja2
LLM SDK OpenAI Python (DeepSeek-compatible)
Validation Pydantic v2
MCP SDK modelcontextprotocol/python-sdk
Output Rich
Testing pytest + pytest-mock
Linting ruff

FAQ

Do I need to understand MCP protocol internals?

No. The generated server handles JSON-RPC, tool discovery, and schema validation. You only need to implement handler.py.

What if the LLM produces a wrong schema?

The validator catches type errors, invalid names, and missing fields. Retry is automatic (up to 3 attempts). Use --dry-run to preview before generating.

Can I use OpenAI instead of DeepSeek?

Yes. The CLI automatically falls back to OPENAI_API_KEY if DEEPSEEK_API_KEY is not set.

export OPENAI_API_KEY="sk-..."
skill-to-mcp generate SKILL.md --model gpt-4o-mini

Any OpenAI-compatible endpoint works (OpenAI, DeepSeek, OpenRouter, Together AI, etc.).

What Python version do I need?

Python 3.10+ for the CLI. The generated MCP servers also require Python 3.10+.

Is this production-ready?

This is an MVP (v0.1.0). The generated code is correct and runnable, but you should review and test the generated handler before deploying.

How much does each generation cost?

~$0.001 per generation with DeepSeek V4 Flash. The prompt is ~300 tokens and the response is ~200 tokens.

Is the --with-example-impl handler production-ready?

The LLM-generated handler is a starting point. It may contain bugs (e.g., referencing local variables instead of input.field). Always review and test the generated code before deploying. The prompt has been tuned to minimize common LLM mistakes, but human review is recommended.


Roadmap

  • --with-example-impl flag for LLM-generated handler implementations
  • TypeScript/Go output support
  • Batch processing (multiple SKILL.md files)
  • Hosted registry at registry.skill-to-mcp.dev
  • skill-to-mcp publish command
  • Smithery integration
  • Custom template directories (--templates-dir)

Contributing

Pull requests are welcome! See project_state.md for current status and next steps.

  1. Fork the repo
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Run tests (pytest tests/ -v)
  4. Commit your changes
  5. Push and open a PR

License

MIT — see LICENSE.


Built with ❤️ for MCP developers. If this saved you time, ⭐ the repo!

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

skillmd_to_mcp-0.1.1.tar.gz (350.1 kB view details)

Uploaded Source

Built Distribution

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

skillmd_to_mcp-0.1.1-py3-none-any.whl (32.4 kB view details)

Uploaded Python 3

File details

Details for the file skillmd_to_mcp-0.1.1.tar.gz.

File metadata

  • Download URL: skillmd_to_mcp-0.1.1.tar.gz
  • Upload date:
  • Size: 350.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for skillmd_to_mcp-0.1.1.tar.gz
Algorithm Hash digest
SHA256 9e80466703895d452585a3b5e4a992b31b79ee750cda074bbb140cc85089c04c
MD5 ed5f76056c6512fa8af16848b6830d80
BLAKE2b-256 f708d524de8c97040934eb3350759ea174fbe273885293858bb9b6ec0d6098c4

See more details on using hashes here.

File details

Details for the file skillmd_to_mcp-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: skillmd_to_mcp-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 32.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for skillmd_to_mcp-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 500e5f3b66b9e5fe14e94ec15c86fca9f98f0aa5129a5d0160e87b4ea157e73f
MD5 223b06cd570e74780980e666cab42875
BLAKE2b-256 77afde6250c076562522fe95afc3eb79090eb48e45e8b2936a36c01cb65f7f22

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