Skip to main content
Glama
Orders MCP server

Orders MCP server

MCP 与 API:一个订单服务,两种接口

视频 "MCP vs API: why do we need MCP if REST already works?" 的配套仓库

克隆它,运行两条命令,把同一件事做两遍。一次用纯 REST API,一次在它之上加一个 MCP 服务器。大约需要 20 分钟。


我们要构建什么

你经营一家小型网店。订单不断进来,有些卡住后永远没有发货。你希望一个 AI 代理找出那些卡住的订单,并为每一单开一个 GitHub issue。

这就是整个示例。一件小而真实的工作。

第一种方式,你把 API 文档交给代理,让它用 curl。它必须自己弄清楚该调用哪个端点、为"超过 7 天"构造日期过滤器、注意到响应是分页返回的,还要把分转换成美元。

第二种方式,你给它一个名为 find_stale_orders 的工具,它接收 { older_than_days: 7 }。

两者调用的是同一个端点 GET /orders。商店本身完全不变。变的是谁来做思考:是代理,还是你的服务器。

                        ┌──────────────────────────────────┐
  Web frontend  ───────▶│                                  │
  Mobile app    ───────▶│   Orders service (Express)       │
  Microservice  ───────▶│   GET  /orders                   │
                        │   GET  /orders/:id               │
                        │   PATCH /orders/:id              │
                        └──────────────▲───────────────────┘
                                       │  plain HTTP, nothing AI specific
                        ┌──────────────┴───────────────────┐
  Claude Code   ───────▶│   Orders MCP server              │
  Cursor        ───────▶│   tool: find_stale_orders        │
  Codex         ───────▶│   input: { older_than_days: 7 }  │
                        └──────────────────────────────────┘

你的 API 是一扇门。MCP 为 AI 客户端提供了一个标准的门把手来打开它。

订单服务永远不知道 Claude Code 的存在。MCP 服务器只是你 API 的另一个 HTTP 客户端。唯一的区别是,它用一种代理能理解的方式来描述自己。


Related MCP server: support-agent-mcp

一分钟上手

你需要 Node 20 或更高版本。其他什么都不需要。没有数据库,没有 API 密钥。

git clone https://github.com/bytemonk-academy/mcp-vs-api.git
cd mcp-vs-api
npm install
npm test

npm test 会针对 REST API 和 MCP 服务器运行 31 个测试。如果全部通过,一切正常,剩下的就是你亲眼看着它发生。

现在启动服务并让它保持运行:

npm run api

在第二个终端里,查看数据:

npm run orders
  ID         CUSTOMER             STATUS      PLACED       DAYS  TOTAL
  ----------------------------------------------------------------------
  ORD-1001   Ada Lovelace         UNSHIPPED   2026-07-27   31    $129.00
  ORD-1002   Grace Hopper         UNSHIPPED   2026-08-03   24    $45.99
  ...

  Showing 20 of 24 matching orders.

  !! There are more. page.nextOffset = 20
     You have NOT seen all 24 orders.

然后问它这个演示要回答的问题:

npm run orders -- --stale=7

八个订单。在任何机器上、一天中的任何时间,都是同样的八个。


npm run orders 是什么?

它是 curl 的快捷方式。

它向你的 API 发送 GET /orders,并把响应以表格形式打印出来,而不是原始 JSON。仅此而已。你也可以自己运行同样的请求:

curl "http://localhost:3000/orders"

你得到同样的数据,只是更难读。这个脚本只是为了让你快速检查数据。它不是课程的一部分。在第一阶段,代理只拿到 curl 和文档,没有别的。

它接受几个选项:

npm run orders -- --stale=7             # unshipped for more than 7 days
npm run orders -- --status=UNSHIPPED    # filter by status
npm run orders -- --limit=5 --offset=5  # move through the pages by hand

为什么测试数据长这样

共有 24 个订单,保存在内存中,日期相对于今天设置。所以无论你什么时候克隆这个仓库,都恰好有 8 个过期订单。

有三个问题是有意埋进去的,这样你可以亲眼看到差异,而不是只听视频里说:

  • 响应是分页返回的。 请求订单会得到 20 条,共 24 条。这 20 行里没有任何看起来不完整的地方。一个只读第一页就停下来的代理会给出错误答案,而且语气还很笃定。

  • 有些旧订单已取消。 它们看起来过期了,但实际上不是。如果你按 shippedAt 而不是 status 过滤,就会误把它们算进去。

  • 有些订单刚好卡在 7 天线以下。 天数算错一点点,得到的就是错误的总数,而不是一条错误消息。

MCP 服务器在 src/mcp/server.ts 中用代码一次性处理了这三个问题。而在 curl 版本中,代理必须每次都把这三件事全部做对。


练习

按顺序做。先做第一阶段再做第二阶段,这正是关键所在,因为差异本身就是课程。

指南

你要做什么

第一阶段

docs/phase-1-rest-only.md

把 API 文档交给代理,让它用 curl,观察它需要自己解决什么

第二阶段

docs/phase-2-mcp.md

打开 Orders MCP 服务器和 GitHub 的 MCP 服务器,再次运行同样的提示词

之后

docs/architecture.md

什么变了、什么没变,以及什么时候 MCP 不值得用

这里还有:API 参考(第一阶段给代理用的)、可以复制的提示词,以及故障排查。

第二阶段会打开真实的 GitHub issue,所以请用一个你不介意被填满的测试仓库。


里面有什么

src/
  data/orders.ts     The 24 test orders
  api/app.ts         The REST API. Knows nothing about MCP.
  api/server.ts      Starts it on a port.
  mcp/server.ts      The MCP server. Calls the REST API over HTTP.
scripts/orders.ts    The table viewer used above
clients/             Plain MCP clients, in Python and TypeScript
tests/               Tests for both halves
docs/                The walkthrough
.mcp.json            Claude Code reads this automatically
.cursor/mcp.json     Cursor reads this automatically

三个工具。每一个都是对已有端点的薄封装:

工具

输入

调用

find_stale_orders

{ older_than_days: 7 }

GET /orders?status=UNSHIPPED&before=...,翻遍每一页

get_order

{ order_id: "ORD-1001" }

GET /orders/ORD-1001

mark_order_shipped

{ order_id: "ORD-1001" }

PATCH /orders/ORD-1001

src/mcp/server.ts 大约 170 行,其中大部分是注释。MCP 服务器本质上就是这样。


亲眼看看协议

Claude Code 在这里没有任何特殊操作。它把服务器作为子进程启动,并通过 stdin 和 stdout 发送 JSON-RPC 消息。 clients/raw_mcp_client.py 用手动方式做了同样的事:

async with stdio_client(server) as (read, write):
    async with ClientSession(read, write) as session:
        await session.initialize()
        result = await session.call_tool("find_stale_orders", {"older_than_days": 7})

同一个脚本随后通过 HTTP 与 GitHub 的 MCP 服务器通信来打开 issue:

await session.call_tool("create_issue", {"owner": owner, "repo": name, "title": ...})

两次都是同样的形状。一个服务器是你笔记本电脑上的 Node 进程,另一个由 GitHub 运行。客户端无法区分它们。这才是值得记住的部分。如果你希望只用一种语言,clients/ 里有一个 TypeScript 版本。


测试

npm test

31 个测试。MCP 相关的测试通过 stdio 驱动一个真实的 MCP 客户端,方式与 Claude Code 完全相同。

如果你打算自己写服务器,值得一读。它们展示了真正值得检查的内容:每个工具都有可用的描述和 schema、分页确实有效、404 以工具错误而不是崩溃的形式返回、已取消的订单不会出现在结果中。


命令

npm run api        # REST API on :3000
npm run api:dev    # same, restarts when you edit a file
npm run orders     # print the orders as a table
npm run mcp        # run the MCP server directly (agents usually do this for you)
npm test           # the tests
npm run typecheck  # tsc --noEmit
npm run inspect    # MCP Inspector, to try the tools by hand

npm run inspect 是查看代理所见内容的最快方式:工具名称、描述,以及每个工具的输入 schema。

数据保存在内存中,所以重启 npm run api 会把一切恢复到初始状态。


什么时候 MCP 值得用?

第一阶段是可行的。这不是什么把戏。一个好的代理仅凭 curl 和文档就能找到过期订单并打开 issue。MCP 并不是让这件事成为可能的原因。

它改变的是集成的形态。如何查询你的订单服务现在存在于一个服务器中,而不是存在于每个代理的上下文窗口里。同样的能力可以在 Claude Code、Cursor 和 Codex 中工作,而无需为每一个单独编写新的集成。而且你可以选择暴露哪些能力,这与交出 API 密钥截然不同。

它不改变的是:身份验证、授权、校验、限流、重试和良好的服务设计仍然都是你的工作。一个构建在糟糕 API 之上的 MCP 服务器,仍然是一个糟糕的 API。

粗略地说,价值随客户端数量乘以工具数量而增长。一个代理调用你控制的两个函数?跳过它,直接调用函数就好。五个团队、四个客户端共享三十个工具?那才是共享协议开始回本的时候。 docs/architecture.md 详细讨论了这条线在哪里。


MIT 许可。可以用于你自己的教学,无需署名。

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Exposes Shopify order and inventory management tools via MCP, allowing agents to fetch, update, and print orders without exposing raw Shopify credentials.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Exposes order status lookup and knowledge base search tools from the Support Agent AI over MCP, enabling MCP clients to handle customer support queries with grounded, citation-backed answers.
    1
    MIT