Files
cad-agent/mcp_bridge/protocol.py
T

67 lines
2.4 KiB
Python
Raw Normal View History

"""MCP 协议常量与纯函数。
本模块**不含任何 IO**,只做版本协商、信封构造与方法路由判定,便于单独测试。
"""
from . import __version__ as SERVER_VERSION
# 本桥支持的协议版本,从新到旧。initialize 时按客户端请求协商。
PROTOCOL_VERSIONS = ("2025-06-18", "2025-03-26", "2024-11-05")
DEFAULT_VERSION = PROTOCOL_VERSIONS[0]
SERVER_NAME = "cad-mcp-bridge"
# classify() 的四种路由结果
LOCAL = "local" # 由桥自己应答(基座没有实现)
FORWARD = "forward" # 原样转发给 CAD 基座
NOTIFY = "notify" # 通知,按规范不回包
UNKNOWN = "unknown" # 未知方法,回 -32601
_LOCAL_METHODS = frozenset({"initialize", "ping"})
_FORWARD_METHODS = frozenset({"tools/list", "tools/call"})
def negotiate_version(requested):
"""协议版本协商:客户端请求的版本受支持则回显,否则回本桥支持的最新版本。
依据 MCP 规范:服务端支持的版本必须原样返回;不支持时回退到自己支持的版本,
由客户端决定是否继续。
"""
return requested if requested in PROTOCOL_VERSIONS else DEFAULT_VERSION
def classify(method):
"""把方法名映射到路由动作。"""
if method in _LOCAL_METHODS:
return LOCAL
if method in _FORWARD_METHODS:
return FORWARD
if method.startswith("notifications/"):
return NOTIFY
return UNKNOWN
def ok(msg_id, result):
"""构造 JSON-RPC 成功响应。"""
return {"jsonrpc": "2.0", "id": msg_id, "result": result}
def err(msg_id, code, message):
"""构造 JSON-RPC 错误响应。"""
return {"jsonrpc": "2.0", "id": msg_id, "error": {"code": code, "message": message}}
def initialize_result(params):
"""合成 initialize 的 result(基座未实现生命周期,由桥代答)。"""
requested = ""
if isinstance(params, dict):
requested = params.get("protocolVersion") or ""
return {
"protocolVersion": negotiate_version(requested),
"capabilities": {"tools": {"listChanged": False}},
"serverInfo": {"name": SERVER_NAME, "version": SERVER_VERSION},
"instructions": (
"本服务器通过 stdio 桥接本机 AutoCAD 的 cad_mcp_frame 基座。"
"工具仅在 CAD 已启动且已加载插件时可用;未启动时调用会返回连接错误。"
),
}