Skip to content

发布 0.2.1:补回已发布源码并适配 mcp 2.x - #1

Merged
lxyd-ai merged 3 commits into
mainfrom
cursor/pin-mcp-lt2-0.2.1-8062
Sep 26, 2026
Merged

lxyd-ai merged 3 commits into
mainfrom
cursor/pin-mcp-lt2-0.2.1-8062

Conversation

@lxyd-ai

@lxyd-ai lxyd-ai commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator

合并这个 PR 不会自动发布。 仓库里没有发布 workflow。发到 PyPI、打 tag 都要人工单独批准。本 PR 没有发布、没有打 tag、没有改 workflow,也不要合并进自动发布流程。

做了什么

uvx uno-mcp-stdio 在 PyPI 0.2.0 上会启动即崩:'Server' object has no attribute 'list_tools'。原因是依赖 mcp>=1.0.0 没有上限,现在会装到 mcp 2.2.0,而 2.0 起低层 Server 删掉了装饰器。

main 停在 0.1.9,缺少已发布 0.2.0 的 Link 模式(PendingAuthSession、--link)。如果只在 main 上改依赖,0.2.1 会丢掉这套认证。因此先按 PyPI sdist 补回源码,再把协议层改到 mcp 2.x。

最终依赖:mcp>=2.2,<3。包版本与 __version__ 都是 0.2.1(__version__ 原先是 0.1.3)。仓库没有 uv.lock,没有新增。

中间曾经有一个把依赖锁成 mcp>=1.0,<2 的 commit(fda6197)。按新方案用后续 commit 9aa6ab6 改成适配 2.x,没有 force push。

Commit

  1. f04c04e 按 PyPI 已发布 0.2.0 sdist 补回源码
  2. fda6197 一度锁 mcp<2(已被下一提交覆盖)
  3. 9aa6ab6 适配 mcp 2.x,依赖改为 mcp>=2.2,<3

HEAD:9aa6ab602ea8ee0d4609be54cb0fb54c34f62a88

0.2.0 源码核对

从 https://pypi.org/pypi/uno-mcp-stdio/0.2.0/json 下载:

  • sdist uno_mcp_stdio-0.2.0.tar.gz sha256 504e87ac579f9d3abc55e1813a7dc517c8f95b5674bbf6071027bea8e0751096
  • wheel uno_mcp_stdio-0.2.0-py3-none-any.whl sha256 4d11c7cb2fc970f2ad5de9cc749055f47d3507f9eafbb6ccccf16a3a02f7d03f

用 sdist 覆盖有差异的 pyproject.toml、src/uno_mcp_stdio/auth/token_manager.py、config.py、main.py、stdio_server.py。没有引入 PKG-INFO。README、claude.md、.gitignore 与 sdist 本来就一致。

commit 1 当时,工作区 src/uno_mcp_stdio/**/*.py 与 0.2.0 wheel 内同名文件 sha256 全部一致(之后的 0.2.1 只改了 __init__.py 的版本号和 stdio_server.py):

文件 sha256
uno_mcp_stdio/__init__.py 6f4d81980da27eecf177420a443da3406011bdc48754886a3185b26feb85ff43
uno_mcp_stdio/auth/__init__.py 8dc6f8ceb8940107fc2e7e4639e9bb76a1170a51022e46ca0a792dd3de494627
uno_mcp_stdio/auth/callback_server.py 6de1021f35991314dc958dbfcdc91ff213b56f4a3c6949959e95e9a8dbe074b6
uno_mcp_stdio/auth/token_manager.py 704464be2e78979b6b73c3b8cb79015da7c07034e087dc954eceb4b2e5191986
uno_mcp_stdio/config.py bfde0941411b2ea29d78ba1dac4ca17b3385ad17958fa655b2fae3fad11d66cb
uno_mcp_stdio/gateway/__init__.py c988edfe0a6cb18583405b3db7d8e64438bee5f3d5375a924dde728d88d55c47
uno_mcp_stdio/gateway/proxy.py 29a7c20a7459bb97d7db184e21776c90d9364d972bb3d019caa02ff295acd242
uno_mcp_stdio/main.py 0abaed75200fb9bbf3772d0fdef7213cafe7e62a30aa0488d68bcc3a9c43576b
uno_mcp_stdio/stdio_server.py 4b0e73128e6d0a90a932d4bf0daa4b50832e3cafe56702e8136c0703e8db031e

为什么下限是 2.2

对照官方文档(迁移指南 v2.2.0 的 docs/migration.md、v2.0.0 release、v2.2.0 release)和 2.0.0 / 2.1.0 / 2.2.0 的 wheel:

本包改用的低层 API 在 2.0.0(2026-07-28) 就已落地,见迁移指南 “Lowlevel Server: decorator-based handlers replaced with constructor on_* params”:

  • @server.list_tools() / @server.call_tool() 删除,改为 Server(..., on_list_tools=, on_call_tool=)
  • 回调签名变为 (ctx: ServerRequestContext, params) -> ListToolsResult | CallToolResult,不再自动把 list[Tool] / list[TextContent] 包成结果
  • server.request_context 删除,会话在 ctx.session
  • Tool.input_schema 等字段改为 snake_case(构造时仍接受旧的 camelCase 关键字)
  • stdio_server()、create_initialization_options(notification_options=NotificationOptions(...))、server.run(read, write, init_options) 的调用形状保留
  • ctx.session.send_tool_list_changed() 仍在

钉在 2.2 而不是 2.0: 当前 PyPI 稳定版就是 2.2.0(2026-09-07)。这一版用 PR #3470 把 JSONRPCMessage / ServerNotification 从 RootModel 换成普通 union + TypeAdapter(v2.2.0 release notes,以及迁移指南 “Replace RootModel by union types”)。stdio_server() 的入站校验走的就是这套类型。2.0/2.1 仍是 RootModel。我们在 2.2.0 上完成握手、tools/list 和 Link 模式验证,所以下限取已验证且线类型已切到 union 的 2.2。

上限 <3: 迁移指南自己的示例就是 mcp>=2,<3。避免下一个大版本再像这次一样,无上限把 uvx 装崩。

本包没有用 ClientSession、SDK 的 HTTP 客户端或 FastMCP(2.x 改名为 MCPServer)。Gateway 仍用我们自己声明的 httpx:mcp 2 改依赖 httpx2,不再代为安装 httpx(迁移指南 “httpx and httpx-sse replaced by httpx2”)。没有做 1.x 装饰器垫片。

验证

干净环境,未传入用户 key。pytest tests/test_stdio_handlers.py:6 passed(mcp 2.2.0)。

构建与解析到的 mcp

$ uv build
Successfully built dist/uno_mcp_stdio-0.2.1.tar.gz
Successfully built dist/uno_mcp_stdio-0.2.1-py3-none-any.whl

$ uvx --isolated --from dist/uno_mcp_stdio-0.2.1-py3-none-any.whl \
    python -c 'import importlib.metadata as m; print("mcp", m.version("mcp")); print("uno", m.version("uno-mcp-stdio"))'
mcp 2.2.0
uno 0.2.1

PyPI 上 mcp 的最新稳定版就是 2.2.0。

initialize + tools/list + 工具调用

通过 stdio 依次发送 initialize(protocolVersion 2025-11-25)、notifications/initialized、tools/list。

protocol 2025-11-25
serverInfo {'name': 'uno-mcp-stdio', 'version': '0.2.1'}
capabilities {"experimental": {}, "tools": {"listChanged": true}}
tool_count 8
tool_names ['uno_auth', 'uno_search_tools', 'uno_call_tool', 'uno_connect_server', 'uno_rate_server', 'uno_get_credits', 'uno_skills_search', 'uno_skills_fetch']

工具调用:

  • uno_skills_search,参数 {"query":"mcp"}。这是列表里的搜索类工具,但 不是免登录的:进程内返回 {"error":"authentication_required","message":"需要认证,请先调用 uno_auth 工具"}。用包内只读 token 直连 gateway 的 tools/call 也是 HTTP 401、Unauthorized. OAuth authentication required.(7 个远程工具都一样)。未打印 token。
  • 实际打通的免登录、无副作用调用是 uno_auth / action=status:isError false,{"status":"not_authenticated","message":"当前未登录"}。这是本进程内的状态查询,不会发起登录。

Link 模式

uvx --isolated --from <0.2.1 wheel> uno-mcp-stdio --link,握手后调用 uno_auth action=login,在拿到链接后结束,没有完成登录。

status link_generated
message 请复制以下链接到浏览器完成认证
auth_url_origin https://mcpmarket.cn/oauth/authorize
auth_url_has_query True
pending_session_exists True
pending_keys ['client_id', 'code_challenge', 'code_verifier', 'created_at', 'redirect_uri', 'state']

授权链接的 query 和 pending 文件内容没有写入本 PR。

对照:0.2.0 + mcp 2.2.0

$ uvx --isolated --from uno_mcp_stdio-0.2.0-py3-none-any.whl \
    python -c 'import importlib.metadata as m; print("mcp", m.version("mcp")); print("uno", m.version("uno-mcp-stdio"))'
mcp 2.2.0
uno 0.2.0

$ uvx --isolated --from uno_mcp_stdio-0.2.0-py3-none-any.whl uno-mcp-stdio </dev/null
exit=1
stderr: [UnoStdio] 错误: 'Server' object has no attribute 'list_tools'
Open in Web Open in Cursor 

cursoragent and others added 3 commits September 26, 2026 09:25
main 停在 0.1.9,缺少已发布 0.2.0 的 Link 模式认证实现。
用 PyPI sdist 覆盖 pyproject.toml 与 4 个有差异的源码文件,
避免后续 0.2.1 丢掉 PendingAuthSession 与链接模式。

Co-authored-by: Agentrix <lxyd-ai@users.noreply.github.com>
mcp>=1.0.0 无上限时会装到 mcp 2.x,Server 不再提供 list_tools。
依赖改为 mcp>=1.0,<2,包版本与 __version__ 升到 0.2.1,并补 CHANGELOG。

Co-authored-by: Agentrix <lxyd-ai@users.noreply.github.com>
低层 Server 改为 on_list_tools/on_call_tool,返回完整结果类型,
通知改走 ctx.session。依赖定为 mcp>=2.2,<3。

Co-authored-by: Agentrix <lxyd-ai@users.noreply.github.com>
@lxyd-ai
lxyd-ai merged commit 398eba4 into main Sep 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants