mcpField
M
MCP Assist — Coordination Memory

MCP Assist — Coordination Memory

远程服务
github.com/aliomraniH记忆与知识011 周前更新
代码仓库

关于 MCP Assist — Coordination Memory

MCP Assist — Coordination Memory 是面向多 Agent 与多界面协作的通用服务,提供记忆、交接、会话和制品管理。它结合按命名空间隔离的记录、服务端执行的步骤序列,以及来源与验证信号。

主要功能

  1. 01通过 Streamable HTTP 提供 30 个 MCP 工具
  2. 02按命名空间划分记忆与协作数据
  3. 03服务端按固定顺序执行步骤
  4. 04内容寻址去重的制品存储
  5. 05写入筛查与来源追踪
  6. 06可轮换的客户端界面令牌

适用场景

  1. 01在 Agent 工作流间共享项目记忆
  2. 02交接任务并记录会话事件
  3. 03存储和获取共享制品
  4. 04检查过时或隔离的记忆条目

MCP 相关

该服务通过 Streamable HTTP 提供 30 个用于记忆、交接、会话、制品、协作、反馈和管理的工具。MCP 客户端可调用由服务端按顺序执行步骤的序列工具。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://mcp-assist-memory.replit.app/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

全部服务地址
Streamable HTTPhttps://mcp-assist-memory.replit.app/mcp需要授权

工具

详细介绍

mcp-assist-memory

一个通用、与项目无关的记忆/协调/制品服务,适用于多 Agent、多界面的协作。一个 FastAPI 进程通过 Streamable HTTP 提供 30 工具 MCP,由 Postgres(+ pgvector) 提供支持,并以独立服务的形式部署在 Replit Reserved VM 上。

这是可复用性约定的 Tier 1:每个项目均可直接复用。它不包含任何领域术语——项目身份仅存在于命名空间 值 中,绝不会出现在工具名称、表、列或代码中。

功能一览
  • 通过 Streamable HTTP 提供 30 工具 MCP(记忆、交接、会话、制品、协调、反馈、管理)。
  • 信任边界主干(Plan v2)——按参与者范围实施恰好一次写入,并显示去重结果;回读验证确认(verified_persisted);标准化错误负载并附带补救措施;写入时筛查并隔离;来源级别(origin、模型归属、derived_from 血缘);信任衰减(needs_reverification);符合 PHI 安全要求的 tool_events 遥测;按命名空间划分的变体配置;以及 observation_log 反馈通道。
  • 按命名空间隔离的多租户——每个项目级查询都会按 namespace 筛选。
  • 可应对瞬时数据库断连——服务器会透明地在新的池化连接上重试真正的连接中断(Neon 缩容/PgBouncer 连接回收,SQLSTATE 57P01/08xxx),并在连接取出时验证连接,因此调用方不再需要重试。重试受幂等性保护,因此绝不会重复写入。
  • 提示词注入防护层——写入时会清理值(伪造标记会单向转义为 [[UNTRUSTED_DATA]],读取时绝不会还原);会筛查并隔离指令类写入(写入确认中会显示隔离情况;设置 include_quarantined: true 可在读取时包含隔离内容);读取结果会以 <<<UNTRUSTED_DATA>>> 标记包裹;当使用方需要原始值时(例如用于 json.loads),可通过 storage.sanitize.unwrap_value 还原。坦诚地说,这些只是防护层,并非证明——确定性筛查和包装可被自适应攻击者绕过;对抗性评估尚待开展(参见 DECISION-PROTOCOL.md 中的 Phase 10 待办事项)。
  • 内容寻址制品(sha256,全局去重),上限为 50 MB,支持范围读取。
  • 按界面划分、可轮换的令牌(web 与 desktop-cli),通过密码保护的 /admin 控制面板进行管理。

30 个工具

分组工具
memorymemory_save memory_get memory_list memory_history memory_delete memory_search
handoffhandoff_save handoff_load handoff_list
sessionsession_create session_append_event session_get session_list session_events
artifactartifact_put artifact_get artifact_list
coordinationcoord_health coord_drift_scan coord_reconcile coord_curate
gateintent_open skill_define gate_close_outcome gate_cache_status
sequencesession_bootstrap namespace_init recall
feedbackobservation_log
adminstats

序列是 Agent 应该遵循的路径。正确使用此服务始终需要遵循一个序列——了解哪个数据库提供了答案、解析配置文件、检查哪些内容已过时,然后再采取行动。过去,这种顺序写在工具描述和技能中,也就是说,它依赖模型在任务过程中记住建议来确保执行;跳过步骤也不会产生任何信号。三个序列工具会在服务端按固定顺序执行步骤,并返回 steps_run,因此,执行顺序由服务端完成,而不是取决于调用方是否正确操作。这些工具纯属增补:它们基于的每个基础工具仍完全按原样工作,可用于精细操作。

recall 和 memory_search 现在共用一个检索门控机制(storage/retrieval.py):采用与 Intent Gate 相同的绝对下限和相对 alpha 值。此前,memory_search 完全没有下限,而 intent_open 同时设有两者,因此同一个存储区面对同一个问题,会因调用方选择的工具不同而给出不同答案。两者对判定结果的处理仍有区别——memory_search 会为每一行添加注释且不丢弃任何内容,recall 默认会过滤,并报告被拒绝的数量——但它们不再会对什么算作匹配意见不一。

Intent Gate(claude/intent-gate/INTENT_GATE_CHARTER.md)按命名空间选择启用(variant_profiles.profile.intent_gate: "on"):修改类工具会获得确定性的 Tier-0 预检(用于替代和删除的两阶段预览/确认、依赖新鲜度标记、紧凑的 gate 确认块);intent_open 会增加 Tier-1 记忆相似度评估器;Tier 2(通过 Anthropic 直接 API 进行 LLM 推理——绝不使用 MCP 采样)则在 tier2: "on" 后启用(默认关闭)。默认配置文件的命名空间与启用 Gate 前的服务逐字节相同。

/healthz(存活状态)和 /admin 令牌仪表板由独立服务提供(不是 MCP 工具)。

多租户——命名空间是项目边界

namespace == 项目 == 租户。 每个项目使用一个命名空间(例如 acme-billing),并按惯例使用键前缀划分子范围(coord/…、knowledge/…)。每个项目级工具都要求提供 namespace,且每次查询都会按其筛选——不存在隐式的跨项目读取。session 和 session_event 表也包含 namespace,因此情景记忆和其他所有内容一样,都有作用域限制。

**Artifact 是刻意设置的例外:**它们通过内容寻址(sha256)并进行全局去重,因此不限定于某个租户——哈希值就是访问凭证。

明确的限制(以及 v2 修复方案)

各表面令牌限定的是连接的客户端表面,而不是客户端可以访问的项目:任何持有有效令牌的人都可以传入任意命名空间,因此命名空间仍是软边界——能为守规矩的客户端提供真正的隔离,但无法防范不守规矩的客户端。

v2 认证路线图——按项目划分令牌/角色。 作用域限定为 acme-billing 的令牌不得读取或写入 other-project。在实现之前, 应将命名空间边界视为由客户端配置执行的约定,而不是由服务端强制执行的限制。(参见 REUSABILITY.md →“命名空间是租户边界”。)

身份验证与 /admin 仪表板

MCP 令牌存储在 Postgres(admin_auth_tokens)中,可在 /admin 中轮换,无需重新部署。每个接入端各有一个有效令牌:

接入端标签客户端发送方式
claude.ai 网页连接器web在 URL 中使用 ?token=<token>(网页连接器无法发送请求头)
Claude Desktop 和 Claude Code CLIdesktop-cliAuthorization: Bearer <token>
CursorcursorAuthorization: Bearer <token>(通过 .cursor/mcp.json)

验证入口接受任意有效令牌,因此每个接入端都可以独立轮换或撤销令牌——轮换 web 令牌绝不会影响 desktop-cli 或 cursor。/admin 页面为每个接入端显示一张卡片,其中包含可直接粘贴使用的 URL/命令以及专属的轮换按钮。

首次启动时,MCP_AUTH_TOKEN 会初始化 web 令牌(确保现有的 claude.ai 连接器继续正常工作);desktop-cli 和 cursor 令牌则会自动生成。首次启动后,仪表板即为唯一可信来源。

  • /admin 由 ADMIN_PASSWORD 进行密码保护(使用签名的 HttpOnly 会话 Cookie,并受 CSRF 保护)。未配置此密码时,仪表板会拒绝登录。
  • 只有以下路由不受 Bearer 验证保护:GET /healthz、流式 GET /artifact/{sha256} 和 /admin(该路由自行进行身份验证)。

无状态传输。 /mcp 以无状态 HTTP 模式运行(http_app(stateless_http=True)):每个请求都独立完整,不依赖内存中的会话亲和性。因此,客户端会话可在 VM 重启或重新部署后继续使用,三个接入端之间也不共享服务端会话状态。

架构

  • 在 FastAPI lifespan(app.py)中创建一个 AsyncConnectionPool,并通过 deps 注入。其他地方都不会打开连接。连接池使用 check=AsyncConnectionPool.check_connection 构建,因此,服务器端在空闲期间终止的连接会在取出时经过验证并丢弃,绝不会交给 调用方。
  • 一个 config.py(pydantic-settings)——读取密钥的唯一位置。
  • StorageBackend ABC(storage/base.py)由 PostgresBackend 实现;18 个工具与其一一对应。
  • 透明重连:读取和幂等写入在连接断开时会重试(_retry_on_disconnect)。例如,OperationalError: terminating connection due to administrator command(SQLSTATE 57P01,Neon 缩容 / PgBouncer)会在新的池化连接上重试,而不会将错误传递给调用方。只有真正的连接断开(08xxx / 57P0x / 连接已关闭)才会重试——其他操作错误(锁超时、连接数过多)会原样抛出。只有在可安全重放时才会重试写入:artifact_put (内容寻址)始终会重试;memory_save/handoff_save/memory_delete 仅在提供 event_id 时重试(恰好一次)。session_* 写入也会重试,但有明确的权衡:在狭窄的提交确认窗口内断开连接,可能导致 session_create 留下一个空的、未被引用的会话行;而 session_append_event 是至少一次(重放可能追加一个重复事件)。对于只追加的会话日志,这比直接让调用失败更好;不带 event_id 的保存仍只运行一次,并会抛出错误。
  • 写入路径上的 sanitize 会剥离伪造的分隔符 / 控制字符;读取时会用 <<<UNTRUSTED_DATA>>> 标记包裹值(防范致命三元组)。注意:value(以及会话事件的 payload)字段返回时会带有包裹标记,因此需要原始值的使用方——例如需要对原本是 JSON 字符串的值调用 json.loads——必须先剥除标记。使用 storage.sanitize.unwrap_value(单个字符串可使用 strip_untrusted);每次读取都会保留此包裹处理。
  • 有界的生命周期就绪检查(不使用无界的 pool.wait())、50 MB 工件大小上限、范围 Blob 读取、幂等 event_id 写入、幂等 Blob 回填。
  • 语义召回(memory_search):设置 VOYAGE_API_KEY 后,每次 memory_save 都会将条目转换为嵌入向量(Voyage,voyage-3.5-lite,1024 维),存入可为空的 embedding vector(1024) 列,该列带有 HNSW 余弦索引;memory_search 按含义对有效条目排序(embedding <=> query),然后将关键词 / 子串匹配结果补足至 limit。嵌入是尽力而为的:它会在获取连接前运行,绝不会阻塞或导致写入失败;未设置密钥时,该列保持 NULL,搜索退化为纯关键词搜索——即 Phase 3 之前的行为。每个搜索环节都会先按 namespace 过滤(不会跨项目召回)。在现有数据库上启用密钥后,运行一次 python scripts/backfill_embeddings.py 为旧行生成嵌入(操作幂等,只处理 NULL 行)。
  • 召回调优(hnsw.ef_search):HNSW 索引是近似索引,因此除非调整查询时的召回参数,较大的存储中可能会漏掉相关结果。memory_search 会根据 HNSW_EF_SEARCH(默认值 100;pgvector 自身的默认值为 40),按语句设置 hnsw.ef_search(仅在语义搜索环节生效,事务范围内)。值越大,召回效果越好,搜索速度会略微变慢;该值必须 >= 搜索上限才能生效。无论如何,小型存储返回的行都相同,因此默认值可以保持不变——如果大型租户报告结果缺失,可调高该值(例如 200);要降低延迟,可将其调低至 40。超大型租户还可以调优索引构建参数(m、ef_construction);参见 migrations/0002_embeddings.sql(更改这些参数需要重新创建索引)。
  • 协调对账器(coord_reconcile):有 GitHub 访问权限时,claim(带有 meta.repo + meta.pr/meta.branch)会对照 GitHub 实时状态进行解析——PR #N 是否已合并?分支 X 的头提交是什么?——并附加仅追加的判定结果;没有访问权限时,状态保持为 unverifiable(绝不会错误地标记为 current)。访问权限按以下优先级获取:显式设置的 GITHUB_TOKEN(只读仓库和 PR),否则——在 Replit 上——使用 Replit 连接器提供的已连接 GitHub 账号(每个缓存窗口都会重新获取令牌,以便在 OAuth 刷新后继续有效),否则禁用此功能。解析是尽力而为的:网络 / API 故障会导致状态为 unverifiable,不会阻止写入。设置 GITHUB_WEBHOOK_SECRET 后,POST /webhook/github 会在 push / pull_request 时对受影响的 claim 进行对账。
  • 记忆整理器(coord_curate):设置 ANTHROPIC_API_KEY 后,可以在会话结束时在写入端进行整合:coord_curate(namespace, session_id) 会读取会话的执行轨迹和相似的现有记忆,询问模型哪些内容值得持久化,并确定性地应用生成的 ADD/UPDATE/MERGE/SUPERSEDE/NOOP 操作。每个操作都会先通过默认拒绝的 PHI 门控;缺少溯源信息(meta.repo + meta.pr/branch)的 claim 会降级为备注;取代操作会设置有效性边界(保留历史记录,绝不删除);写入操作是幂等的(使用确定性的 event_id),因此重新运行会话绝不会重复写入。此功能是尽力而为的:未设置密钥时,整理器会被禁用,coord_curate 将正常空操作({curator_enabled: false, operations: []});任何模型 / 解析失败都会产生零个操作——绝不会错误写入。dry_run=True 会返回拟议操作但不执行写入。可通过 CURATOR_MODEL 和 CURATOR_MAX_OUTPUT_TOKENS 进行调优。整理后的行还会带有第二个 hyde_embedding,因此 memory_search 除了能匹配已存储的陈述,还能匹配未来的问题(HyDE 环节)。

本地运行

cp .env.example .env          # DATABASE_URL + MCP_AUTH_TOKEN + ADMIN_PASSWORD
make install                  # pip install -c constraints.txt -e ".[test]"
make migrate                  # apply migrations/0001_init.sql
make run                      # uvicorn app:app
curl localhost:8000/healthz   # {"status":"ok","db":"ok"}
# token: open http://localhost:8000/admin and sign in with ADMIN_PASSWORD

测试(真实 Postgres)

测试套件针对真实 Postgres 运行;如果未设置 DATABASE_URL,则会正常跳过。中立测试项目为 proj-test(绝不使用真实项目名称)。

DATABASE_URL=... make test

CI(.github/workflows/test.yml)会在每次运行时创建一个临时 Neon 分支,对其执行迁移、运行 pytest,然后删除该分支。设置仓库机密 NEON_API_KEY 和 NEON_PROJECT_ID 即可启用。

冒烟测试(连接器握手)

scripts/smoke_mcp.py 会执行 Claude 连接器所做的完整握手——使用有效令牌通过 /mcp 执行 initialize + tools/list,并断言 HTTP 200、完整的 30 个工具,以及防护措施(无令牌/错误令牌 ⇒ 401,/healthz 数据库正常)。此测试旨在防止传输/身份验证/主机回归问题(例如 fastmcp 3.4.3 的 421)再次悄然上线。

  • **阻止不良构建:**进程内测试部分会在 CI 中通过 pytest(tests/test_smoke_mcp.py)针对临时 Neon 分支运行——握手、门禁或工具数量出现问题,都会在部署前导致构建失败。

  • **标记不健康的线上部署:**部署后,针对已部署的 URL 运行此测试。任何检查失败都会以非零状态退出:

    SMOKE_BASE_URL=https://<your-vm> SMOKE_TOKEN=<active token> make smoke
    

    .github/workflows/smoke.yml 会在手动触发时(或按 6 小时计划)针对线上 URL 运行此测试;设置仓库机密 SMOKE_BASE_URL 和 SMOKE_TOKEN 即可启用(未设置时会正常跳过)。

在 Replit 上部署(Reserved VM)

  1. 在 Secrets 中设置 DATABASE_URL(池化端点)、MCP_AUTH_TOKEN 和 ADMIN_PASSWORD(以及可选的 Phase-3 密钥)。
  2. 部署为 Reserved VM(deploymentTarget = "vm"),而不是 Autoscale;持久性门禁要求进程持续运行。
  3. 部署的 run 步骤会先运行 python scripts/migrate.py,然后启动 uvicorn。
  4. 打开 https://<your-vm>/admin,登录并复制/轮换令牌。将每个客户端指向 https://<your-vm>/mcp。
固定依赖项(确定性构建)

pyproject.toml 声明了宽松的版本范围,但部署构建、post-merge.sh 和 make install 都会传入 -c constraints.txt,因此生产环境安装的版本与开发环境中验证过的版本完全一致。这能防范导致生产环境 /mcp 421 中断的那类故障(未固定版本的构建悄然解析到更新的 fastmcp)。

要主动升级依赖项(避免固定版本过时):

pip install -U <pkg>          # or `pip install -e .` to re-resolve a widened range
make test                     # AND exercise /mcp locally
make lock                     # regenerate constraints.txt from the verified env
# then redeploy — prod now installs the newly verified set

切勿手动编辑 constraints.txt 中的版本;务必使用 make lock(scripts/lock-deps.sh)重新生成。文件头部也记录了相同的操作步骤。

Postgres / Neon

运行中的服务请使用池化连接字符串;psycopg 配置了 prepare_threshold=None,以适配 PgBouncer 事务池化。测试和 scripts/migrate.py 使用直连端点(测试连接池会保留预处理语句)。

边界

此仓库仅限 Tier 1。Canvas 专用 MCP 工具、FHIR 逻辑和 SDK 知识位于单独的 canvas-sdk-tools 仓库中,绝不放在这里。

Blob 迁移(文件系统 → bytea)

python scripts/backfill_artifacts.py /path/to/old/blobstore

迁移具有幂等性(按 sha256 去重),会逐个流式处理文件,跳过并报告任何超过 50 MB 上限的文件,并通过校验和回读随机抽样进行验证。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。