关于 MCP Assist — Coordination Memory
MCP Assist — Coordination Memory 是面向多 Agent 与多界面协作的通用服务,提供记忆、交接、会话和制品管理。它结合按命名空间隔离的记录、服务端执行的步骤序列,以及来源与验证信号。
主要功能
- 01通过 Streamable HTTP 提供 30 个 MCP 工具
- 02按命名空间划分记忆与协作数据
- 03服务端按固定顺序执行步骤
- 04内容寻址去重的制品存储
- 05写入筛查与来源追踪
- 06可轮换的客户端界面令牌
适用场景
- 01在 Agent 工作流间共享项目记忆
- 02交接任务并记录会话事件
- 03存储和获取共享制品
- 04检查过时或隔离的记忆条目
MCP 相关
该服务通过 Streamable HTTP 提供 30 个用于记忆、交接、会话、制品、协作、反馈和管理的工具。MCP 客户端可调用由服务端按顺序执行步骤的序列工具。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://mcp-assist-memory.replit.app/mcpclaude mcp add --transport http aliomranih-mcp-assist-memory https://mcp-assist-memory.replit.app/mcp{"mcpServers":{"aliomranih-mcp-assist-memory":{"type":"http","url":"https://mcp-assist-memory.replit.app/mcp"}}}在 Cursor 中打开{"servers":{"aliomranih-mcp-assist-memory":{"type":"http","url":"https://mcp-assist-memory.replit.app/mcp"}}}在 VS Code 中打开{"mcpServers":{"aliomranih-mcp-assist-memory":{"type":"http","url":"https://mcp-assist-memory.replit.app/mcp"}}}{"mcpServers":{"aliomranih-mcp-assist-memory":{"serverUrl":"https://mcp-assist-memory.replit.app/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
https://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 个工具
| 分组 | 工具 |
|---|---|
| memory | memory_save memory_get memory_list memory_history memory_delete memory_search |
| handoff | handoff_save handoff_load handoff_list |
| session | session_create session_append_event session_get session_list session_events |
| artifact | artifact_put artifact_get artifact_list |
| coordination | coord_health coord_drift_scan coord_reconcile coord_curate |
| gate | intent_open skill_define gate_close_outcome gate_cache_status |
| sequence | session_bootstrap namespace_init recall |
| feedback | observation_log |
| admin | stats |
序列是 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 CLI | desktop-cli | Authorization: Bearer <token> |
| Cursor | cursor | Authorization: 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)——读取密钥的唯一位置。 StorageBackendABC(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)
- 在 Secrets 中设置
DATABASE_URL(池化端点)、MCP_AUTH_TOKEN和ADMIN_PASSWORD(以及可选的 Phase-3 密钥)。 - 部署为 Reserved VM(
deploymentTarget = "vm"),而不是 Autoscale;持久性门禁要求进程持续运行。 - 部署的
run步骤会先运行python scripts/migrate.py,然后启动 uvicorn。 - 打开
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 上限的文件,并通过校验和回读随机抽样进行验证。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。