MCP工具编译SDK

将MCP服务器工具编译为类型化Python SDK,支持异步方法调用,适用于需要直接工具访问的自动化系统和代码执行代理。

  • by manojbajaj95
  • Python
  • 本地部署
  • 7 星标
  • 更新于
在 GitHub 查看 manojbajaj95/mcp-skill

使用说明

mcp技能

将任何MCP服务器转换为类型化的Python SDK。

将MCP工具编译成代码。

mcp-skill 内省MCP服务器并生成一个Python类,其中每个工具都成为一个类型化的异步方法。

前后

之前

代理通过模型循环调用MCP工具——每次工具调用一次往返:

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

之后

代理直接在代码中调用工具:

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

运作原理

┌─────────────┐      ┌───────────────┐      ┌────────────────────┐
│  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. 使用连接到MCP服务器 fastmcp
  2. 通过以下方式反思所有可用工具 list_tools()
  3. 将每个工具的JSON模式转换为Python类型的注释
  4. 生成类型化 App 类,其中每个MCP工具都成为 async 方法
  5. 使用验证输出 ast.parse → ruff → ty
  6. 产生 SKILL.md 带有代理工具文档和使用示例

动机

MCP服务器允许代理访问工具,但每个工具调用都会在模型中往返——请求工具、执行、将完整结果返回上下文,决定下一步。对于大型有效载荷或连续调用,这会燃烧令牌并增加延迟。

编程工具调用 修复了这个问题:代理编写直接调用工具的代码,而无需每次调用模型往返。获取、过滤、聚合——所有这些都在一个代码块中。

mcp技能 通过将任何MCP服务器编译为普通Python类,可以实现这一点。每个工具都变成一个类型化的异步方法。代理只编写Python。

有关为什么MCP与CLI是错误的框架的更深入解释,请参阅 MCP与CLI是错误的问题.

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"]
)

设置

# Install with uv
uv pip install -e .

# Or use directly without installing globally
uvx --from . mcp-skill create --url https://your-mcp-server.com/mcp --auth api-key

需要 紫外线 Python 3.10+。

发布工作流

发布由以下人员管理 release-please,仅考虑以下承诺 main 遵循常规承诺格式。

使用以下提交主题:

feat: add CLI command to inspect generated apps
fix: handle auth recovery when cached credentials are stale
chore: update release workflow docs

版本碰撞行为:

  • feat: 创建次要版本
  • fix: 创建补丁发布
  • feat!: 或一个 BREAKING CHANGE: 页脚创建主要版本

最佳实践:

  • 更喜欢壁球合并,这样公关头衔就变成了承诺 main
  • 以常规承诺格式编写PR标题
  • 保持主题行简短明了
  • 当更改需要额外的上下文时,添加一个简短的正文

可选的本地执法 pre-commit:

uv tool install pre-commit
pre-commit install
pre-commit install --hook-type commit-msg

此回购包括 commit-msg 钩住 .pre-commit-config.yaml 在创建非传统提交主题之前拒绝它们。

如果release说一个commit“无法解析”,请将一个新的常规commit推送到 main 并重新运行工作流。

用法

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

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

发现现有应用程序

将CLI用作两个版本控制的本地目录 skills/ 应用程序和生成 .agents/skills/ 应用程序。

# List every discovered app
uvx --from . mcp-skill list-apps

# List callable functions for a specific app
uvx --from . mcp-skill list-functions notion

# Inspect a specific function's signature and docstring
uvx --from . mcp-skill inspect notion notion_search

使用Python中的应用程序

找到所需的应用程序和方法后,从异步Python调用它:

import asyncio
from sentry.app import SentryApp


async def main():
    sentry = SentryApp()
    user = await sentry.whoami()
    print(user)


asyncio.run(main())

所有生成的工具包装都是 async.小心使用 await 在async函数内部。如果你跳过 await,您将得到一个协程对象,而不是实际结果。

生成的输出

技能落地 .agents/skills/<name>/ 作为Python包:

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

以下是生成的内容 app.py 看起来像:

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]

每个方法都连接到MCP服务器,调用底层工具,并返回解析后的JSON。身份验证凭据将持久化到 ~/.mcp-skill/auth/ 首次使用后,由服务器URL键入,因此凭据在重新启动时会自动保留。

这是给谁的?

开发商建筑:

  • 基于MCP的代理 无需模型往返,即可直接访问工具
  • 自动化系统 使用MCP工具作为编程构建块
  • 代码执行代理 使用 编程工具调用

当前限制

  • 认证:支持API密钥(承载或自定义标头)、OAuth(包括动态客户端注册或预先注册的PKCE client_id),没有——没有mTLS
  • 运行时依赖关系:生成的代码取决于 fastmcp 用于MCP客户端连接
  • 每次通话的连接:每种方法都会创建一个新的MCP客户端连接(无池)
  • 仅限工具:尚不支持MCP资源和提示

任务清单

根据实际使用情况跟踪改进:

  • [x] 修复输出目录路径 --更改自 .agents/skill/<name> 到 .agents/skills/<name>
  • [x] 将依赖关系信息添加到SKILL.md --列出的依赖关系 uv 和 pip 安装命令
  • [x] 生成 __init__.py --Skill目录是一个合适的Python包
  • [x] 生成后验证 — ast.parse → ruff check → ty check 随着 uvx 后备方案
  • [x] 包装样式导入 --已移动 app.py 技能根;进口方式 from <skill>.app import <Class>
  • [x] 持久令牌存储 --FileTree支持的凭据存储位于 ~/.mcp-skill/auth/,按服务器URL键入
  • [x] 统一身份验证签名 --所有身份验证类型都使用 auth=None 在 __init__
  • [x] 消毒技能名称 --连字符/点转换为下划线以获得有效的Python标识符
  • [x] 异步cli --CLI命令通过以下方式完全异步 asyncclick
  • [x] 本地应用程序发现 — mcp-skill list-apps, mcp-skill list-functions <app>,以及 mcp-skill inspect <app> <function>
  • [ ] 支持MCP资源和提示 --目前,只有工具是经过反思和生成的