Token导航 LogoToken导航TokenDH.com
Apap MCP Poc logo
运维云端stdio官方级别未说明来源级核验

Apap MCP Poc

MCP Server

drizzle-kit

APAP/MCP服务器的共享服务层重构,通过消除内部HTTP循环,提高性能和可维护性。

工具数

0

提示词数

0

GitHub Stars

0

资源数

0
TypeScript错误处理云端部署

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

JayDS22

提供方

JayDS22

最后核验

2026/5/17 20:23

运行时

Node.js

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

命令预览

npx drizzle-kit push

详细介绍

APAP/MCP服务器POC:共享服务层重构

雅阁项目 |想法#4——强化APAP/MCP服务器

这是我的GSoC应用程序中提出的核心架构更改的概念验证:通过引入MCP工具和REST路由直接使用的共享服务层,消除了APAP参考实现的MCP处理程序中的内部HTTP循环。

作者 Jay Guwalani——马里兰大学帕克分校研究科学家 | jguwalan@umd.edu

______________________________________________________________________

演示

![Demo Video](https://www.youtube.com/watch?v=KFwc5IRuKUc)

______________________________________________________________________

问题

当前RI中的每个MCP工具调用都需要通过整个Express堆栈进行不必要的HTTP往返,才能到达位于同一进程中的数据库:

MCP Tool -> makeApiRequest() -> fetch('http://localhost:9000/...') -> Express -> Handler -> Drizzle -> Postgres

makeApiRequest() 助手在 handlers/mcp.ts 实际上是通过网络调用自己。最重要的是,错误处理都是简单的字符串(throw new Error('Failed to load template'))404、400或500之间没有区别。

我在普利司通遇到了同样的架构,五个专门的代理通过内部REST网关路由到共享的Postgres实例。修复方法是相同的:将业务逻辑拉入共享服务层,并让每个传输直接调用它。

修复

MCP Tool ----\
              >-- services/agreementService.ts --> Drizzle --> Postgres
REST API ----/

一个功能。两个消费者。没有HTTP循环。错误修复会自动传播到这两个协议。

项目结构

src/
  config.ts                 Zod-validated env vars, fail-fast on startup
  index.ts                  Server entry, wires Express + MCP transports + health check

  db/
    schema.ts               Drizzle schema (mirrors APAP RI exactly)
    client.ts               Connection pool factory with DI for tests

  services/
    errors.ts               Typed error hierarchy (6 classes replacing bare strings)
    templateService.ts      Template CRUD via Drizzle
    agreementService.ts     Agreement CRUD + convert + trigger
    index.ts                Barrel export

  handlers/
    mcp.ts                  MCP tool/resource registration (SSE + StreamableHTTP)

  routes/
    api.ts                  REST router, same service imports as MCP

  middleware/
    logging.ts              Pino structured logging, request-id correlation
    healthz.ts              /healthz for Docker readiness probes

使此工作的不变量:

  • 每个服务功能都需要 db 作为其第一个参数(无需Postgres即可测试)
  • 服务返回键入的结果,从不返回原始HTTP响应
  • 服务投掷 ServiceError 子类,从不裸露字符串
  • 服务不从Express或MCP SDK导入任何内容

快速开始

Docker(30秒):

git clone https://github.com/JayDS22/apap-mcp-poc.git
cd apap-mcp-poc
docker compose up

本地(需要运行Postgres):

cp .env_example .env        # edit credentials if needed
npm install
npx drizzle-kit push
npm run dev

无论哪种方式,你都会得到:

APAP MCP POC server listening on http://0.0.0.0:9000
  REST API:       http://0.0.0.0:9000/capabilities
  MCP SSE:        http://0.0.0.0:9000/sse
  MCP Streamable: POST http://0.0.0.0:9000/mcp
  Health:         http://0.0.0.0:9000/healthz

端到端演练

服务器运行后,遍历整个生命周期:

# Health check
curl http://localhost:9000/healthz
# {"status":"ok","timestamp":"2026-03-28T..."}

# Capabilities (matches APAP RI format)
curl http://localhost:9000/capabilities
# ["TEMPLATE_MANAGE","AGREEMENT_MANAGE","SHARED_MODEL_MANAGE","AGREEMENT_CONVERT_HTML"]

# Create a template
curl -s -X POST http://localhost:9000/templates \
  -H 'Content-Type: application/json' \
  -d '{
    "uri": "resource:org.accordproject.protocol@1.0.0.Template#latedelivery",
    "author": "dan",
    "displayName": "Late Delivery and Penalty",
    "version": "1.0.0",
    "description": "Penalties for late delivery of goods",
    "license": "Apache-2.0",
    "keywords": ["late", "delivery", "penalty"],
    "metadata": {"$class": "org.accordproject.protocol@1.0.0.TemplateMetadata", "runtime": "typescript", "template": "clause", "cicero": "0.25.x"},
    "templateModel": {"$class": "org.accordproject.protocol@1.0.0.TemplateModel", "typeName": "LatePenaltyClause", "model": {"ctoFiles": []}},
    "text": {"templateMark": "Late Delivery and Penalty clause text..."}
  }'

# Create an agreement referencing the template
curl -s -X POST http://localhost:9000/agreements \
  -H 'Content-Type: application/json' \
  -d '{
    "uri": "apap://agreement-demo1",
    "data": {"$class": "io.clause.latedeliveryandpenalty@0.1.0.TemplateModel", "forceMajeure": false, "penaltyPercentage": 10.5, "capPercentage": 55, "clauseId": "demo-1"},
    "template": "resource:org.accordproject.protocol@1.0.0.Template#latedelivery",
    "agreementStatus": "DRAFT"
  }'

# Convert to markdown
curl http://localhost:9000/agreements/1/convert/markdown

# Convert to HTML (open in browser)
curl http://localhost:9000/agreements/1/convert/html -o /tmp/agreement.html && open /tmp/agreement.html

# Trigger agreement logic
curl -s -X POST http://localhost:9000/agreements/1/trigger \
  -H 'Content-Type: application/json' \
  -d '{"$class":"io.clause.latedeliveryandpenalty@0.1.0.LateDeliveryAndPenaltyRequest","forceMajeure":false,"goodsValue":1000}'

# Structured error handling -- typed error, not a bare string
curl http://localhost:9000/agreements/9999
# {"error":{"code":"AGREEMENT_NOT_FOUND","message":"Agreement not found: 9999","details":{"identifier":9999}}}

MCP检查员

npx @modelcontextprotocol/inspector
# Open http://127.0.0.1:6274
# Select SSE transport, URL: http://localhost:9000/sse
# Browse Resources, call Tools (getAgreement, convert-agreement-to-format, trigger-agreement)

测试

npm test                  # 53 tests + coverage
npm run test:unit         # 44 unit tests (mocked DB, no Postgres)
npm run test:integration  # 9 integration tests (real Express, mock DB)
npm run typecheck         # TypeScript strict mode

服务层覆盖范围: 98.69%的语句/92.3%的分支/100%的函数. errors.tstemplateService.ts 全面达到100%。

错误处理

RI投掷 new Error('Failed to load template') 在每一条失败的道路上。此POC用带有机器可读代码、HTTP状态映射和结构化详细信息的键入错误替换了这些错误:

错误类别HTTP代码何时
TemplateNotFoundError404TEMPLATE_NOT_FOUND找不到模板ID/URI
AgreementNotFoundError404AGREEMENT_NOT_FOUND未找到协议ID
AgreementConversionError500AGREEMENT_CONVERSION_FAILED渲染失败
InvalidPayloadError400INVALID_PAYLOAD触发器负载不是有效的JSON
TemplateDuplicateError409TEMPLATE_DUPLICATEURI唯一性违规
ValidationError422VALIDATION_ERROR架构验证失败

MCP处理程序和REST路由器都有自己的catch块,用于映射 ServiceError 为他们的协议制定正确的响应形状。任何不是 ServiceError 被视为真正的500。

GSoC时间线映射

阶段本POC涵盖的内容
1-4服务层+错误类型src/services/ --完整的CRUD、转换、触发器、6个错误类
5-8测试基础设施__tests__/ --跨两个MCP传输的单元+集成
9-10CI/CD.github/workflows/ci.yml +Docker编写
11-12观察性+文档Pino日志、健康检查、此自述文件

提案的第3-4阶段(OpenAPI验证、负载测试、贡献者文档)直接建立在这个基础之上。

现有技术

我已经在生产环境中两次发布了这种精确的共享服务层模式:

普利司通(2022-2024): 五个专业代理(分析、行程数据、驾驶员安全、车队性能、碰撞分析)通过内部REST网关路由到Postgres。重构为共享服务,将P95延迟降低了40%,并在其生命周期中首次将系统置于测试覆盖范围内。

阿亚医疗(2025): LangGraph多代理管道,具有5个以上代理(筛选、技能评估、匹配、调度、常见问题解答),通过OCI/AWS上的类型化服务功能共享Postgres后端。相同的模式,相同的可测试性DI方法。

链接

许可证

阿帕奇-2.0

目录标签

目录标签

TypeScript错误处理云端部署服务层重构本地部署性能优化协议处理测试覆盖

接入字段

传输方式(transport,传输协议)

stdio

鉴权方式(authType,认证方式)

none

运行时(runtime,运行环境)

Node.js

来源包(packageName,安装包名)

drizzle-kit

工具数量(toolCount,工具数)

0

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

stdionone部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

来源信息

继续浏览同类 MCP