使用 gs-quant MCP 服务端与客户端让 LLM Agent 通过 Model Context Protocol 调用量化金融工具【免费下载链接】gs-quantPython toolkit for quantitative finance项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quantgs-quant 在仓库的 gs_quant/mcp 目录中内置了一套基于Model Context ProtocolMCP的服务器与客户端实现它将 gs_quant 的量化金融能力数据查询、用户信息、市场视图等封装为 MCP 工具供 LLM Agent 及其他 MCP 客户端消费。读完本文你将掌握如何安装、启动服务端、配置认证与工具过滤、通过 CLI 与交互式 REPL 调用工具以及如何在自定义包中注册自己的 MCP 工具。⚠️实验性功能该模块处于活跃开发中其 API、CLI 与配置在后续版本中可能发生变化请以当前仓库 gs_quant/mcp 的实际实现为准。一、模块概览一个入口、三种能力gs_quant.mcp包基于 FastMCP 构建同时提供服务端与客户端服务端自动发现工具tool auto-discovery支持基于标签tag的过滤并提供两种认证策略local与passthrough客户端支持一次性 CLI 子命令与交互式 REPL使用 streamable-HTTP 传输协议。两者都通过同一个命令行入口访问python -m gs_quant.mcp server|client|discover ...从源码看server与client是两个 Typer 子应用外加一个独立的discover-tools命令入口定义位于main.py。包的整体目录结构如下config.pyMcpServiceConfig/SSLConfig配置模型run.py基于 uvicorn 的run_mcp_server/run_mcp_server_async启动逻辑middleware.pyLocalUserAuthMiddleware与RemoteUserAuthMiddleware两种认证中间件dependencies.pydepends_user_profile、depends_user_session依赖注入tools/内置工具包users、data、marketview与 registry.py 工具注册表client.py客户端 URL 构建、认证头透传、参数解析与 REPL 实现session_utils.py从 HTTP 请求中提取凭据、构造GsSession的工具函数。二、安装使用本模块需要Python 3.10并安装可选的mcp依赖pip install gs-quant[mcp]如果是在其他项目中使用 uv 管理依赖uv add gs-quant[mcp]该 extra 依赖会带入 FastMCP、uvicorn、typer、rich、prompt_toolkit、pydantic 等运行库。三、快速开始先启动一个服务端使用你的 Marquee OAuth 客户端凭据python -m gs_quant.mcp server \ --client-id $CLIENT_ID \ --client-secret $CLIENT_SECRET在另一个终端中与该服务端对话# 一次性命令 python -m gs_quant.mcp client list-tools python -m gs_quant.mcp client describe-tool current_user_info python -m gs_quant.mcp client call-tool whois rmarti # 交互式 REPL python -m gs_quant.mcp client mcp /list mcp /describe whois mcp /call whois rmartiCLIENT_ID与CLIENT_SECRET也可以通过.env文件或 shell 环境变量提供。从main.py 可以看到server与client两个命令启动时都会用find_dotenv(usecwdTrue)从当前工作目录向上查找并加载.env文件CLI 参数未提供时会回退到环境变量CLIENT_ID/CLIENT_SECRET。四、服务端详解4.1 Server CLI 参数python -m gs_quant.mcp server [OPTIONS] --config / -c Path to a YAML McpServiceConfig file --base-path URL path the MCP endpoint is served under (default /mcp) --host Bind address (default 0.0.0.0) --port Bind port (default 4301) --environment Target environment (Dev, Prod, …) --service-name FastMCP server name (default GsQuantMCP) --packages / -p Comma-separated packages to discover tools from (default: gs_quant.mcp.tools) --extra-packages Additional packages to discover tools from (comma-sep) --enable-tags Comma-separated tag list — keep only tools with these tags --disable-tags Comma-separated tag list — drop tools with these tags --enable-keys Comma-separated tool keys (e.g. tool:my_tool) to keep --disable-keys Comma-separated tool keys to drop --auth local | passthrough (default: local) --client-id OAuth client id (local auth only) --client-secret OAuth client secret (local auth only)对应实现位于main.py 的 server 命令CLI 参数会覆盖 YAML 配置文件中的同名项命令行提供的值优先随后创建FastMCP(service_name)将发现到的工具逐个mcp.add_tool(tool)再按enable_tags/disable_tags/enable_keys/disable_keys调用 FastMCP 的enable/disable方法完成工具面surface裁剪最后按--auth选择挂载认证中间件并额外挂载LoggingMiddleware()输出请求日志。4.2 认证策略服务端在启动时安装一个认证中间件二选一--auth local默认适用于单用户 / 桌面场景。服务端在启动时用--client-id/--client-secret或环境变量 /.env文件创建并认证一个GsSession之后所有请求复用该会话python -m gs_quant.mcp server --auth local \ --client-id $CLIENT_ID --client-secret $CLIENT_SECRET所有依赖user_session的工具无论调用者是谁拿到的都是这一个共享会话。源码层面LocalUserAuthMiddleware在初始化时执行GsSession.get(...)并请求/users/self预取用户档案每次请求进入时把user_profile与会话写入 FastMCP 上下文见 middleware.py。--auth passthrough适用于多用户 / 远程部署。启动时不创建任何会话每个请求进来时服务端检查 HTTP 请求并按以下优先级构造每个用户独立的GsSession来源识别为GSSSOcookieGSSSOSSO tokenMarqueeLogincookieMARQUEE_LOGINAuthorization: Bearer ey…3 段 JWTJWTAuthorization: Bearer …其他OAUTHaccess tokenpython -m gs_quant.mcp server --auth passthrough对应的客户端必须把用户的认证信息通过 headers / cookies 转发过去。底层逻辑位于 session_utils.py优先级为GSSSOcookie →MarqueeLogincookie →AuthorizationBearer 头按值是否为 3 段 JWT 区分类型全部缺失则判定为AuthType.UNKNOWN并返回未认证extract_from_starlette_request还会用 cachetools 的 LRU 缓存容量 50缓存同一 (token, auth_type, environment) 组合的会话与用户档案避免重复认证。4.3 配置文件命令行上的一切参数都可以放进 YAML 文件通过-c/--config传入。其 schema 即 config.py 中的McpServiceConfigpydantic 模型字段名采用 camelCase 别名basePath: /mcp host: 0.0.0.0 port: 4301 env: Prod sslConfig: certPath: ${HOME}/certs/server.crt keyPath: ${HOME}/certs/server.keysslConfig的路径支持${VAR}风格的环境变量替换——run.py 在构建 uvicorn 配置时会调用expand_string_with_variables展开certPath/keyPath再传给uvicorn.Config的ssl_certfile/ssl_keyfile从而以 HTTPS 暴露 MCP 端点。port缺省时为4301env默认Prod且各字段均可被命令行同名参数覆盖。4.4 标签与 key 过滤每个工具都可以打标签见下文编写自己的工具。服务端暴露四个开关在启动时对工具注册表进行切片# 只保留带 user 或 data 标签的工具 python -m gs_quant.mcp server --enable-tags user,data # 按 key 禁用某个吵的工具 python -m gs_quant.mcp server --disable-keys tool:current_user_info--enable-*系列隐含onlyTrue即白名单语义--disable-*系列则是移除语义两者可以组合使用。实现上enable与disable均委托给 FastMCP 的注册表方法见main.py。内置工具中users子包的工具带{user}标签、data子包的工具带{data}标签见 users/tools.py 与 data/tools.py因此--enable-tags user,data即可筛选出数据类与用户类工具。4.5 编程式运行服务端除了 CLI也可以直接在代码中构建FastMCP服务器、手动注册工具通过discover_tools、挂载中间件并用gs_quant.mcp.run.run_mcp_server/run_mcp_server_async启动from fastmcp import FastMCP from typing import Literal from gs_quant.mcp import McpServiceConfig, run_mcp_server from gs_quant.mcp.dependencies import depends_user_session from gs_quant.mcp.middleware import LocalUserAuthMiddleware from gs_quant.mcp.tools import mcp_tool, get_registered_tools from gs_quant.session import GsSession from gs_quant.data import Dataset import datetime as dt mcp FastMCP(MyMCP) mcp_tool() def g3_spot(cross: Literal[GBPUSD, EURUSD, USDJPY], user_session: GsSession depends_user_session) - dict: Return some data with user_session: return Dataset(FXSPOT_STANDARD).get_data_last(as_ofdt.date.today(), bbidcross).iloc[0].to_dict() all_tools get_registered_tools() # Find tools inside this package for _, tool in all_tools.items(): mcp.add_tool(tool) mcp.add_middleware(LocalUserAuthMiddleware(client_idCLIENT_ID, client_secretCLIENT_SECRET)) run_mcp_server(mcp, McpServiceConfig(), port4301)run_mcp_server会通过mcp_server.http_app(pathbase_path)生成 ASGI 应用并交给 uvicorn 运行run_mcp_server_async则是其异步版本便于嵌入asyncio运行时见 run.py。五、客户端详解客户端只讲 streamable-HTTP。认证材料来自一个本地GsSession外部用户必须提供--client-id/--client-secret并作为 headers / cookies 转发从而让运行--auth passthrough的服务端完成对调用者的认证。5.1 Client CLI 参数python -m gs_quant.mcp client [OPTIONS] COMMAND [ARGS]... Connection --url Full server URL (overrides host/port/base-path) --config / -c Reuse a servers McpServiceConfig YAML to derive the URL --base-path Server base path (default /mcp) --host Server host (default localhost) --port Server port (default 4301) --ssl / --no-ssl Use https (default no-ssl) --verify-ssl / --no-verify-ssl Toggle TLS cert verification (default verify) Auth --environment Target environment for the GsSession (Dev, Prod, …) --client-id OAuth client id (or env CLIENT_ID) --client-secret OAuth client secret (or env CLIENT_SECRET) -H / --header KV Extra header (repeatable). Also accepts Name: value.提供了凭据时客户端会构建真实的GsSession提取其Authorization、X-Application、X-Version、X-MARQUEE-CSRF-TOKEN头以及GSSSO/MarqueeLogin/MARQUEE-CSRF-TOKENcookies 并转发给服务端。对应实现见 client.py 的 build_auth_headers它遍历内部 requests 会话的头按白名单{AUTHORIZATION, X-MARQUEE-CSRF-TOKEN, X-APPLICATION, X-VERSION}提取再把三个 cookie 合并进单个Cookie头保证跨 HTTP 传输干净可靠。如果只想覆盖单个头例如注入已知 token直接用-H即可python -m gs_quant.mcp client \ --url http://example.com:4301/mcp \ -H Authorization: Bearer eyJ... \ list-tools-H同时接受KV与Name: value两种写法重复使用可添加多个头解析逻辑见main.py 的 _parse_header_kv。另外传入-c服务端配置时客户端会用其中的basePath/host/port/sslConfig自动推导连接 URL。5.2 子命令一览子命令说明list-tools列出服务端可用的工具list-resources列出资源list-prompts列出提示词promptdescribe-tool name展示工具的参数、类型与描述call-tool name [args...]调用工具read-resource uri按 URI 读取资源get-prompt name [args...]获取提示词ping对服务端做往返 ping无子命令进入交互式 REPL各子命令在main.py 中均有对应实现底层复用 client.py 中的do_list_tools、do_describe_tool、do_call_tool等异步函数一次性子命令会以asyncio.run运行出错时统一捕获并以退出码1结束。5.3call-tool的参数解析给定一个简单示例工具from gs_quant.mcp.tools import mcp_tool mcp_tool def add(a: int, b: int 1) - int: Return a b. return a b工具参数支持三种形式按以下顺序解析JSON 对象——整体加引号避免被 shell 拆词python -m gs_quant.mcp client call-tool add {a: 3, b: 4}keyvalue对——值会尽可能做 JSON 解码n10变成整数10flagtrue变成布尔true等python -m gs_quant.mcp client call-tool add a10 b20位置参数——按工具参数声明顺序绑定必填在前、可选在后。客户端会先从服务端拉取 schema 再完成绑定python -m gs_quant.mcp client call-tool add 3 4解析逻辑见 client.py 的 parse_tool_args先尝试把拼接后的整体json.loads为 dict否则若每个 token 都含则按 keyvalue 解析否则在有param_names时按位置绑定三者都不满足则抛出ValueError。其中tool_param_names依据 JSON Schema 的required列表与properties声明顺序把必填参数排前、可选参数排后。可用describe-tool查看参数顺序与类型python -m gs_quant.mcp client describe-tool add # add - Return a b. # ┏━━━━━━┳━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━┓ # ┃ name ┃ type ┃ required ┃ default ┃ description ┃ # ┡━━━━━━╇━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━┩ # │ a │ integer │ yes │ │ │ # │ b │ integer │ no │ 1 │ │ # └──────┴─────────┴──────────┴─────────┴─────────────┘服务端错误如ToolError会被折叠成一行简洁输出CLI 以状态码1退出。5.4 交互式 REPL不带子命令直接运行客户端python -m gs_quant.mcp client即可得到基于prompt_toolkit的交互提示符带有持久化历史保存于~/.gs_quant_mcp_history并对斜杠命令和工具名做 Tab 补全。可用命令/list List tools /list-resources List resources /list-prompts List prompts /describe name Show a tools parameters and types /call name [args...] Call a tool (same arg parsing as call-tool) /read uri Read a resource by URI /prompt name [args...] Get a prompt /ping Ping the server /refresh Refresh tool-name completion cache /help, /? Show help /quit, /exit Exit (Ctrl-D also works)从源码看REPL 启动时会先尝试list_tools预热工具名补全缓存即便list-tools失败也会照常进入 REPL此时补全器只知道斜杠命令等服务端可达后用/refresh刷新见 client.py 的 run_repl。REPL 内命令抛出的异常会被捕获并打印而不会退出会话此外还额外支持/reconnect命令用于在服务端重启后重新建立连接。/call与一次性call-tool使用完全相同的参数解析规则。六、编写自己的工具6.1 注册工具工具就是普通 Python 函数加上来自gs_quant.mcp.tools.registry的mcp_tool(...)装饰器。该装饰器同时做两件事应用 FastMCP 的tool(...)因此所有 kwargs 都会透传——tags、name、description等把函数记录到模块级注册表中key 为module.qualname供后续发现。# my_pkg/tools/math_tools.py from typing import Annotated from gs_quant.mcp.tools.registry import mcp_tool mcp_tool(tags{math}) def add( a: Annotated[int, First addend], b: Annotated[int, Second addend] 0, ) - int: Return a b. return a bAnnotated[T, ...]中的字符串会变成 JSON Schema 中的参数描述客户端可通过describe-tool看到。注册表实现见 tools/registry.py。如果更想保留 FastMCP 原生的tool装饰器可以改为在它之上叠加register_mcp_toolfrom fastmcp.tools import tool from gs_quant.mcp.tools.registry import register_mcp_tool register_mcp_tool tool(tags{math}) def multiply(a: int, b: int) - int: return a * bregister_mcp_tool会校验函数已具备 FastMCP 注入的__fastmcp__属性否则抛出ValueError见 tools/registry.py。6.2 依赖注入Dependencies工具可以通过 FastMCP 的Depends机制按次请求注入用户身份 / 会话。gs_quant.mcp.dependencies内置了两个现成依赖符号解析结果depends_user_profiledict—— Marquee/users/self的用户档案depends_user_sessionGsSession—— 为调用用户完成认证的会话from gs_quant.mcp.dependencies import depends_user_session from gs_quant.mcp.tools.registry import mcp_tool from gs_quant.session import GsSession mcp_tool(tags{user}) def whois(query: str, user_session: GsSession depends_user_session) - dict: A tool that needs to make authenticated requests to Marquee. with user_session: return GsSession.current.sync.get(/path/to/api)在--auth local下两个依赖都基于 MCP服务端的client-id/client-secret解析在--auth passthrough下它们解析为根据请求 cookies / headers 构建的会话。如果工具请求了这些依赖而请求中缺少凭据依赖会抛出ToolError(User not authenticated.)见 dependencies.py。这两个依赖正是内置whois、current_user_info等工具的实现基础可参考 users/tools.py 与 data/tools.py 中get_daily_data/get_intraday_data的实际用法。6.3 标签Tagstags{a, b}让你在服务端启动时对工具面做切片。常见用法# 只读服务器 —— 只挑安全工具 python -m gs_quant.mcp server --enable-tags user,data # 除了实验性工具之外全部启用 python -m gs_quant.mcp server --disable-tags experimental标签也会出现在python -m gs_quant.mcp discover-tools的输出中。6.4 从其他包加载工具服务端通过导入--packages/--extra-packages所列包的每一个子模块来发现工具这样每个mcp_tool都会执行并注册自己# 替换默认的发现包 python -m gs_quant.mcp server -p mycorp.mcp.tools # 或者在内置工具之上叠加你的工具 python -m gs_quant.mcp server --extra-packages mycorp.mcp.tools,otherorg.mcp.tools传入的包必须能在当前解释器中 import。没有特殊的插件清单机制——凡是pkgutil.walk_packages能到达的模块都会被导入。对应实现见 tools/registry.py 的 discover_tools先importlib.import_module(package)再对其__path__递归遍历导入所有子模块最后返回完整注册表。默认发现包是gs_quant.mcp.tools它聚合了users、data、marketview三个子包。七、列出所有已注册工具如果不想启动服务端就想知道--packages会发现哪些工具可以运行python -m gs_quant.mcp discover-tools \ --packages gs_quant.mcp.tools \ --extra-packages mycorp.mcp.tools该命令会把每个工具限定 key、标签和 docstring 以 rich 表格形式打印出来见main.py 的 discover_tools便于在开发自己的工具时快速核对注册结果。八、故障排查ToolError: User not authenticated.—— 工具请求了用户会话但请求里没有提供。解决办法要么让服务端以--auth local运行并提供有效的客户端凭据要么让客户端带上--client-id/--client-secret或-H Authorization: Bearer ...把凭据转发给--auth passthrough的服务端。自签名 TLS 证书—— 给客户端加--no-verify-ssl。REPL 没有工具名补全—— 先确认连接成功如果启动时list-tools失败REPL 仍会打开但补全器只知道斜杠命令。等服务端可达后执行/refresh刷新补全缓存。九、结语gs-quant 的 MCP 模块为量化金融能力接入 LLM Agent 提供了一条清晰的路径服务端负责把 gs_quant 的函数装饰成标准 MCP 工具、按标签裁剪工具面、并通过local/passthrough两种认证策略适配单机与多用户部署客户端则以一次性 CLI 或交互式 REPL 的方式消费这些工具参数解析同时兼容 JSON、keyvalue 与位置参数三种写法。对想要扩展的开发者mcp_tool注册表 Depends依赖注入 --packages发现机制构成了一个简单但完整的插件模型。由于该模块仍属实验性建议在接入生产环境前锁定当前仓库版本并跟进 gs_quant/mcp 的更新。【免费下载链接】gs-quantPython toolkit for quantitative finance项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考