MCP Python SDK 2.0 removed the low-level Server decorator API
(@app.list_tools() / @app.call_tool() / app.get_capabilities()), so the
server crashed at startup with:
AttributeError: 'Server' object has no attribute 'list_tools'
The released PyPI package weknora-mcp==1.0.1 declared 'mcp>=1.0.0' with
no upper bound, so uvx resolved to the latest 2.0.0 and the plugin's
weknora MCP server could no longer connect.
Fix: rewrite the server on top of the mcp 2.x high-level MCPServer API
(formerly FastMCP), and cap the dependency at 'mcp>=2,<3'.
- weknora_mcp_server.py: replace @app.list_tools()/@app.call_tool() with
28 @mcp.tool() function-signature tools (input schema auto-generated
from type hints, descriptions from docstrings, plain return values
serialized by the framework). Transports use run_stdio_async() /
sse_app() / streamable_http_app(). WeKnoraClient business logic is
unchanged.
- deps: mcp>=2,<3 in pyproject.toml / requirements.txt / setup.py;
commit uv.lock pinning mcp 2.0.0.
- version bump to 1.1.0 (pyproject, setup, __init__, main --version,
server_version).
- check_imports.py: validate MCPServer / ToolError / mcp_types imports.
- ci(.github/workflows/mcp-server.yml): publish on merge to main +
manual dispatch, not only on tags; add PyPI version-dedup check so
re-runs on an unchanged version stay green (absorbed from PR #2399).
Verified: stdio initialize + tools/list returns all 28 tools; no
list_tools AttributeError; tool dispatch + error wrapping confirmed.
Co-authored-by: wizardchen <wizardchen@tencent.com>
WeKnora MCP Server still uses v1 low-level Server decorators such as
@app.list_tools(). MCP SDK 2.0 removed those APIs, so fresh installs
could fail at startup with AttributeError. Cap the dependency at <2 and
require >=1.28 for Streamable HTTP transport support.
* fix(mcp-server): route diagnostics to stderr to fix stdio protocol crash
Entry scripts (run_server.py, main.py, run.py) printed diagnostics to
stdout via bare print(). Under the stdio transport (the default and the
path used by all MCP clients per MCP_CONFIG.md: `uv run run_server.py`),
stdout is the JSON-RPC channel, so the plain-text lines emitted before
the initialize handshake corrupted the protocol stream. Strict MCP clients
(Claude Desktop / Cursor / ZCode / VS Code Copilot) treated this as a
fatal protocol error and reported the server as failed-to-start.
Redirect all diagnostic print() to sys.stderr (per MCP spec, only
JSON-RPC may use stdout). weknora_mcp_server.py already routes through
logging (stderr) and is unchanged.
Verified against a live backend (initialize -> tools/list (28 tools) ->
tools/call list_knowledge_bases); stdout first byte is now '{' with all
diagnostics on stderr.
* chore(mcp-server): publish package name as weknora-mcp
Rename the PyPI distribution name from weknora-mcp-server to weknora-mcp
(tools used: pyproject [project].name + setup.py name). The installed
console-script commands (weknora-mcp-server, weknora-server) and the
Python module (weknora_mcp_server) are unchanged for backward compatibility.
* fix(mcp-server): include upload_paths in wheel + bump to 1.0.1
The 1.0.0 wheel was missing upload_paths.py: it was absent from the
[tool.setuptools] py-modules list (and setup.py py_modules), so setuptools
never packed it. weknora_mcp_server.py line 26 does
`from upload_paths import resolve_upload_file_path, set_active_transport`,
so any path that fully imports the module — i.e. the MCP client initialize
handshake — crashed with ModuleNotFoundError. `--version` survived only
because argparse exits before that import runs.
Fix: add 'upload_paths' to py-modules (pyproject.toml + setup.py) and bump
to 1.0.1 (1.0.0 is immutable on PyPI). Also sync the user-facing version
strings (__version__, server_version, main --version) to 1.0.1.
* ci(mcp-server): add workflow.yml to build & publish to PyPI via OIDC
Adds .github/workflows/workflow.yml adapted from annopick/tuomin's ci.yml:
- test: matrix Python 3.10–3.13 (matches requires-python >=3.10), runs the
flat test_*.py suite in mcp-server/
- build: on mcp-server-v* tags, builds sdist + wheel via uv build, and
guards against the 1.0.0 regression by asserting upload_paths.py is in
the wheel before publishing
- publish: PyPI Trusted Publishing (OIDC, id-token: write) to weknora-mcp,
no API token needed
Publishing is gated on tags named mcp-server-v* to decouple from the Go
release workflow that already targets v* tags.
* fix(mcp-server): route diagnostics to stderr and fix packaging/CI
Prevent MCP stdio startup crashes by sending entry-script diagnostics to
stderr, package upload_paths in the wheel, and add unittest-based CI with
stdout purity regression tests.
---------
Co-authored-by: wizardchen <wizardchen@tencent.com>