股票价格查询服务

一个基于模型上下文协议(MCP)的股票价格查询服务,支持客户端输入请求,适用于金融数据查询和开发演示场景。

  • by GaetanJuvin
  • Ruby
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 GaetanJuvin/mcp-elicitation-demo

使用说明

股票价格MCP服务器(激励演示)

该项目是具有客户端启发的模型上下文协议(MCP)的最小实现。它演示了服务器如何在工具调用期间通过客户端请求额外的用户输入(如股票行情),以及客户端如何声明和处理启发功能。

参考: MCP征集(草案)

运作原理

  • 客户端 (mcp_client.rb):

    • 宣布 elicitation 能力期间 initialize.
    • 发送 tools/list 然后 tools/call 为了 get_stock_price.
    • 当服务器要求输入时(elicitation/create),它在本地提示并以结构化响应进行回复。
    • 详细模式打印彩色I/O: → (青色)用于发送JSON, ← (黄色)表示接收到的JSON。
  • 服务器 (mcp_server.rb):

    • 广告 get_stock_price 工具。
    • 如果缺少ticker参数,则发送 elicitation/create 向客户端发送请求,并等待客户端的响应。
    • 将获取的引号作为JSON编码的文本内容项返回。
  • 价格获取 (price.rb):

    • 从以下来源获取引文 stooq.com 并解析CSV以返回 { symbol, price, date, time, name }.

在本地运行

要求:Ruby 3.1+

可选(如果您使用Bundler):

bundle install

运行客户端(它将生成服务器):

ruby mcp_client.rb --server ./mcp_server.rb -v

提前提供报价(跳过引出):

ruby mcp_client.rb --server ./mcp_server.rb --ticker NVDA -v

详细会话示例

颜色: → 发送(青色), ← 收到(黄色)。以下输出具有代表性。

→ {"jsonrpc":"2.0","id":"init-...","method":"initialize","params":{"clientInfo":{"name":"mcp-client-ruby","version":"1.0.0"},"capabilities":{"elicitation":{}}}}
← {"jsonrpc":"2.0","id":"init-...","result":{"protocolVersion":"2024-11-05","serverInfo":{"name":"stock-price","version":"1.0.0"},"capabilities":{"tools":{},"elicitation":{}}}}

→ {"jsonrpc":"2.0","id":"list-...","method":"tools/list"}
← {"jsonrpc":"2.0","id":"list-...","result":{"tools":[{"name":"get_stock_price","description":"Get latest stock price for any ticker","inputSchema":{...}}]}}

→ {"jsonrpc":"2.0","id":"call-...","method":"tools/call","params":{"name":"get_stock_price","arguments":{}}}
← {"jsonrpc":"2.0","id":"elic-...","method":"elicitation/create","params":{"message":"Which stock ticker would you like to look up?","schema":{"type":"object","properties":{"ticker":{"type":"string","minLength":1,"description":"Ticker symbol like NVDA, AAPL"}},"required":["ticker"],"additionalProperties":false}}}

(prompt) Which stock ticker would you like to look up?
→ {"jsonrpc":"2.0","id":"elic-...","result":{"ticker":"NVDA"}}

← {"jsonrpc":"2.0","id":"call-...","result":{"content":[{"type":"text","text":"{\"symbol\":\"NVDA\",\"price\":123.45,\"date\":\"2025-09-20\",\"time\":\"15:59:00\"}"}]}}
NVDA 123.45

相关代码位置

  • 客户声明 elicitation 能力和操控性 elicitation/create:
initialize_request_id = new_id("init")
write_jsonrpc(server_stdin, { jsonrpc: "2.0", id: initialize_request_id, method: "initialize", params: { clientInfo: { name: "mcp-client-ruby", version: "1.0.0" }, capabilities: { elicitation: {} } } })
  • 服务器发送 elicitation/create 当ticker丢失时:
if ticker_symbol.empty?
  elicited_result = elicit_request(
    "Which stock ticker would you like to look up?",
    {
      type: "object",
      properties: {
        ticker: { type: "string", minLength: 1, description: "Ticker symbol like NVDA, AAPL" }
      },
      required: ["ticker"],
      additionalProperties: false
    }
  )

备注

  • 此示例遵循规范中描述的MCP启发流程,并使用简单的提示/响应交互。详见规范草案: MCP激发.
  • 客户端以详细模式打印彩色JSON-RPC流量,使流量易于检查。

进一步阅读

  • 内存库(架构、流程、组件): docs/MEMORY_BANK.md