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.0.tar.gz (350.0 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.0-py3-none-any.whl (32.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: skillmd_to_mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 350.0 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.0.tar.gz
Algorithm Hash digest
SHA256 710c7fd25a88ec80610295b909d21126fd4a27a6e89fbf4cf2a35cd3c2c98e7f
MD5 1b1e9e5285dc9f36a1dbcfbbf5157cf0
BLAKE2b-256 b5599452e61184be8a1a8800f3fddb43f2e32cc40346780e5a36b96593af254d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: skillmd_to_mcp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 32.3 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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1fcef8040f4e449e9e54b82a92f7931651edc7c4b039c076072c13a6ad4f208d
MD5 2bc4a777966c6b11a221ed7a0ad399e0
BLAKE2b-256 187753df71441152d7b0ebc2bc658c1c8d62ac747f5862bc4981e997fc114f08

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