mirror of
https://github.com/Tencent/WeKnora.git
synced 2026-08-29 02:04:30 +08:00
400bbbf717
* 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>
52 lines
1.5 KiB
Python
52 lines
1.5 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
WeKnora MCP Server 便捷启动脚本
|
|
|
|
这是一个简化的启动脚本,提供最基本的功能。
|
|
对于更多选项,请使用 main.py
|
|
|
|
注意:在 stdio 传输下,stdout 是 JSON-RPC 通道,所有诊断/提示信息必须写入
|
|
stderr,否则会破坏 MCP 协议流导致客户端判定"启动失败"。本脚本所有 print
|
|
均通过 stderr 输出。
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def main():
|
|
"""简单的启动函数"""
|
|
# 添加当前目录到 Python 路径
|
|
current_dir = Path(__file__).parent.absolute()
|
|
if str(current_dir) not in sys.path:
|
|
sys.path.insert(0, str(current_dir))
|
|
|
|
# 检查环境变量
|
|
base_url = os.getenv("WEKNORA_BASE_URL", "http://localhost:8080/api/v1")
|
|
api_key = os.getenv("WEKNORA_API_KEY", "")
|
|
|
|
print("WeKnora MCP Server", file=sys.stderr)
|
|
print(f"Base URL: {base_url}", file=sys.stderr)
|
|
print(f"API Key: {'已设置' if api_key else '未设置'}", file=sys.stderr)
|
|
print("-" * 40, file=sys.stderr)
|
|
|
|
try:
|
|
# 导入并运行
|
|
from main import sync_main
|
|
|
|
sync_main()
|
|
except ImportError:
|
|
print("错误: 无法导入必要模块", file=sys.stderr)
|
|
print("请确保运行: pip install -r requirements.txt", file=sys.stderr)
|
|
sys.exit(1)
|
|
except KeyboardInterrupt:
|
|
print("\n服务器已停止", file=sys.stderr)
|
|
except Exception as e:
|
|
print(f"错误: {e}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|