mcpField
A
adrkit decision memory

adrkit decision memory

本地服务
adrkit.dev记忆与知识213 天前更新

关于 adrkit decision memory

adrkit decision memory 是面向编码 Agent 的本地只读 MCP 服务,用于查询由 Git 管理的架构决策记录。它也呈现已拒绝和已取代的决策,帮助 Agent 避免重复提出团队否决的方案;不调用模型或网络。

主要功能

  1. 01按文本和元数据搜索决策
  2. 02获取完整决策记录
  3. 03按仓库文件路径匹配决策
  4. 04列出已取代决策及其替代项
  5. 05只读访问 Git 管理的 Markdown

适用场景

  1. 01确认架构选择是否已有定论
  2. 02查找约束特定文件的决策
  3. 03查看已拒绝或已取代的方案
  4. 04离线检查 ADR 记录

MCP 相关

该 MCP 服务通过 stdio 提供四种只读工具:搜索决策、获取决策、查找与文件路径相关的决策,以及列出已取代的决策。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"dev-adrkit": {
"command": "npx",
"args": [
"-y",
"@adrkit/mcp"
],
"env": {
"ADRKIT_MCP_CWD": "<ADRKIT_MCP_CWD>",
"ADRKIT_MCP_DIR": "<ADRKIT_MCP_DIR>"
}
}
}
}
启动命令npx -y @adrkit/mcp
需要配置的环境变量
ADRKIT_MCP_CWDRepository root; must contain a readable .git entry. Defaults to the process working directory.
ADRKIT_MCP_DIRADR directory, resolved against the root and required to stay contained within it. Defaults to docs/adr.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@adrkit/mcp0.20.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

@adrkit/mcp

为编码 Agent 提供确定性、离线、只读的决策记忆——包括你已经否决的决策。

一个本地 Model Context Protocol 服务,让 Agent 框架能够通过 stdio 查询一个由 Git 管理的 ADR(架构决策记录)语料库,回答诸如 “这件事已经定下来了吗?”、“哪些决策适用于这些文件?” 和 “这个决策被什么取代了?” 等问题。它会专门呈现已被取代和已被否决的决策,避免 Agent 重新提出团队已经排除的方案。

不调用模型,不调用网络,不进行写入。 服务从你的仓库读取 Markdown 文件,并返回结构化 JSON。它从不调用 LLM、打开套接字或修改语料库。每个工具都标注为 readOnlyHint: true、openWorldHint: false。

这是 adrkit 的一部分。语料库以 Git 管理,每个决策对应一个带有类型化 YAML frontmatter 的 Markdown 文件(@adrkit/core);此服务只读取语料库。它已列入官方 MCP 注册表,名称为 dev.adrkit/mcp(这是 Node/npm 的 @adrkit/mcp 包,与 PyPI 上的 adr-kit Python 包无关)。

状态

已发布到 npm,适用于 Node 22+,提供精简的只读 stdio 接口:四个工具,不提供写入途径。

adrkit 仍处于 1.0 之前的阶段。如果你需要可重复的客户端安装,请在 MCP 配置中固定明确的 @adrkit/mcp 版本,而不要使用浮动的 latest。

快速开始

已发布的二进制文件名为 adrkit-mcp。使用 npx 运行(无需安装):

npx -y @adrkit/mcp --cwd /path/to/your/repo --dir docs/adr

它通过 stdio 使用 JSON-RPC 通信,因此通常应让 MCP 客户端连接到它,而不是手动运行。以下是可直接复制粘贴的客户端配置。

Claude Desktop

编辑 claude_desktop_config.json(macOS: ~/Library/Application Support/Claude/claude_desktop_config.json)。Claude 会从任意工作目录启动服务,因此请将 ADRKIT_MCP_CWD 设置为仓库的绝对路径:

{
  "mcpServers": {
    "adrkit": {
      "command": "npx",
      "args": ["-y", "@adrkit/mcp"],
      "env": {
        "ADRKIT_MCP_CWD": "/absolute/path/to/your/repo",
        "ADRKIT_MCP_DIR": "docs/adr"
      }
    }
  }
}
VS Code

在工作区中创建 .vscode/mcp.json(VS Code 使用 servers 键,并替换 ${workspaceFolder}):

{
  "servers": {
    "adrkit": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@adrkit/mcp", "--cwd", "${workspaceFolder}", "--dir", "docs/adr"]
    }
  }
}
Cursor

创建 .cursor/mcp.json(项目级)或 ~/.cursor/mcp.json(全局):

{
  "mcpServers": {
    "adrkit": {
      "command": "npx",
      "args": ["-y", "@adrkit/mcp"],
      "env": {
        "ADRKIT_MCP_CWD": "/absolute/path/to/your/repo",
        "ADRKIT_MCP_DIR": "docs/adr"
      }
    }
  }
}
GitHub Copilot CLI

添加到 ~/.copilot/mcp-config.json(用户级)或 ./.copilot/mcp-config.json(仓库级)。Copilot CLI 会从受信任的仓库目录启动服务,因此默认的 cwd 通常可以正确解析:

{
  "mcpServers": {
    "adrkit": {
      "type": "local",
      "command": "npx",
      "args": ["-y", "@adrkit/mcp", "--dir", "docs/adr"],
      "tools": ["*"]
    }
  }
}

你也可以在 copilot 会话中使用 /mcp add 交互式添加。

配置参考
选项环境变量默认值含义
--cwd <path>ADRKIT_MCP_CWDprocess.cwd()仓库根目录;必须解析为包含可读 .git 项的目录(普通克隆或链接工作树中的 .git 文件)。
--dir <path>ADRKIT_MCP_DIRdocs/adrADR 目录,相对于 --cwd 解析,且必须位于该目录内(会检查真实路径,因此会拒绝通过符号链接逃逸的路径)。

命令行标志优先于环境变量,环境变量优先于默认值。配置不可用时,进程会以非零状态退出,并在 stderr 输出诊断信息(无法解析的标志返回 2,无效的根目录/目录返回 1),且不会启动传输层。stdout 仅用于 JSON-RPC 协议帧。

协议修订版

服务端在同一个 stdio 连接上同时支持两个时代的 MCP 协议,由客户端选择。连接开始时的交互会选定协议时代,并在连接的整个生命周期内固定使用:

客户端以此开始服务端提供
server/discover,或任何携带 2026 _meta 封装的请求2026-07-28 — 无状态,无握手
initialize / notifications/initialized协商使用的 2025 时代修订版

在 2026-07-28 中,没有 initialize 握手,也没有会话 ID:每个请求都在 _meta 中携带自己的协议版本和客户端能力,每个结果都自描述(resultType,以及 _meta 中的服务端身份)。tools/list 和 server/discover 可缓存(SEP-2549),并以 ttlMs: 300000, cacheScope: "public" 提供,因为这 4 个工具的表面在进程生命周期内固定,且不包含语料内容。语料读取永远不可缓存:每次 tools/call 都会加载全新的投影。

两个时代之间的工具没有其他变化——名称、架构、注解和结构化结果均相同。服务端不使用 2026-07-28 修订版弃用的任何功能(roots、sampling、logging),也不使用其移除的功能(sessions、ping、resources/subscribe)。

四个工具

共四个工具,全部为只读工具。每个工具都使用固定注解(readOnlyHint: true、destructiveHint: false、idempotentHint: true、openWorldHint: false),在 content[0].text 中返回确定性、易读的摘要行,并附带包含语料自身解析/验证结果的 findings 分页。每个实质性响应还包含一个同级的 corpusHealth:{ fingerprint, recordCount, excludedCount }。

以下结构是真实的输入/输出契约(参见 packages/mcp/src/tools)。 每个工具的结构化输出都是 { corpusHealth?, result };“output”下展示的对象是这个判别式 result 联合类型的成员(由 outcome 确定)。findings 和所有会增长的数组都使用游标分页(参见 分页);为简洁起见,此处省略 findings 和重复的分页字段。

search_decisions

对 id、标题、标签和正文进行规范化字面子串搜索(默认包含已被取代/拒绝记录的归档区)。筛选条件采用 AND 关系: status/scope 匹配任意项;tags 匹配全部项。

// input
{
  "query": "postgres",          // required, 1–256 code units, non-empty after trim
  "status": ["accepted"],        // optional, ≤6, any-of
  "tags": ["database"],          // optional, ≤32 tags × ≤64 chars, all-of
  "scope": ["backend"]           // optional, ≤3, any-of
}
// output → single "results" branch (empty results use the same branch)
{
  "outcome": "results",
  "items": [
    {
      "id": "0007",
      "title": "Adopt Postgres",
      "status": "accepted",
      "sourcePath": "docs/adr/0007-adopt-postgres.md",
      "matchedFields": ["title", "body"]   // subset of id | title | tag | body
    }
  ],
  "cursor": null
}
get_decision

获取单个 ref 的完整类型化 frontmatter 和正文。

// input
{ "ref": "0007" }               // AdrRef, 1–128 chars (local id, or a "log:id" federated ref)
// output → discriminated on "outcome"
// found (the full record is nested under "decision"):
{
  "outcome": "found",
  "decision": {
    "requestedRef": "0007",
    "id": "0007",
    "title": "Adopt Postgres",
    "status": "accepted",
    "sourcePath": "docs/adr/0007-adopt-postgres.md",
    "frontmatter": { /* typed YAML: status, tags, affects, relations, ... */ },
    "body": "## Context\n..."
  }
}
// other outcomes:
// { "outcome": "not-found", "requestedRef": "9999" }
// { "outcome": "ambiguous-local-id", "requestedRef": "0007", "candidates": [ /* DecisionSummary[] */ ] }
// { "outcome": "federated-log-unavailable", "requestedRef": "core:12", "log": "core", "id": "12" }

系统可识别 log:id 联合 ref,但绝不会解析或替换它——此服务端只读取一个本地语料。

get_decision_context

通过各记录自身的 affects 匹配器,获取适用于仓库相对路径 files[] 的约束决策 / 活跃提案 / 历史决策。仅将路径与模式进行比较——绝不打开路径对应的文件。

// input
{
  "files": ["src/db/pool.ts", "src/db/schema.sql"]
  // 1–256 entries; each POSIX, 1–1024 chars; no leading "/", no "..", no drive, no "\"
}
// output → single "matches" branch (all three arrays; empty is the same branch)
{
  "outcome": "matches",
  "governing": [
    {
      "id": "0007",
      "title": "Adopt Postgres",
      "status": "accepted",
      "sourcePath": "docs/adr/0007-adopt-postgres.md",
      "firedMatchers": [ { "type": "path", "pattern": "src/db/**" } ],
      "relations": { "supersedes": [], "supersededBy": null, "relatesTo": [], "conflictsWith": [] }
    }
  ],
  "activeProposals": [],
  "history": []
}
list_superseded

列出每条已被取代的记录及其直接本地替代状态——此工具可防止 Agent 再次提出已被拒绝的方案。

// input (pagination only)
{}
// output → single "entries" branch
{
  "outcome": "entries",
  "items": [
    {
      "id": "0003",
      "title": "Use MySQL",
      "status": "superseded",
      "sourcePath": "docs/adr/0003-use-mysql.md",
      "supersededBy": {            // one of four states:
        "resolved": true,
        "target": { "id": "0007", "title": "Adopt Postgres", "status": "accepted", "sourcePath": "docs/adr/0007-adopt-postgres.md" }
      }
      // unresolved states:
      //   { "resolved": false, "targetRef": "0099", "reason": "dangling" }
      //   { "resolved": false, "targetRef": "0007", "reason": "ambiguous", "candidateCount": 2 }
      //   { "resolved": false, "targetRef": "core:1", "reason": "federated-unavailable", "log": "core", "id": "1" }
    }
  ],
  "cursor": null
}

关系 ref(supersedes、supersededBy、relatesTo、conflictsWith)会原样呈现,绝不展开——请通过第二次 get_decision 调用跟进。取代关系只报告一跳,不进行传递遍历。

库接口

包根目录仅导出一个封装好的生命周期工厂。无法访问底层 SDK 服务、其注册项或传输层:

import { createAdrkitMcpServer } from '@adrkit/mcp';

const server = createAdrkitMcpServer({ cwd: process.cwd(), dir: 'docs/adr' });
await server.start();   // validates the root, then serves one stdio connection
// ... later:
await server.close();

createAdrkitMcpServer(options?) 在构造时不会访问文件系统,并返回一个冻结的、无原型的句柄,其中恰好只有 start() 和 close()。

传输故障——例如传输启动失败,或客户端已断开连接导致的后台流错误(如 EPIPE)——会通过可选的 onError 选项报告,该选项默认输出 stderr 诊断信息。adrkit-mcp 二进制文件还会以非零状态码退出。不会向 stdout 写入任何内容:stdout 专用于协议帧。

按照 MCP stdio 绑定的规定,关闭 stdin 即为关闭信号:adrkit-mcp 二进制文件以状态码 0 退出,且 stderr 不输出任何内容。stdin 关闭时仍在处理的请求会被中止且不会得到答复,因此客户端(或通过管道输入请求的脚本)必须保持 stdin 打开,直到读取完所有需要的响应。

限制

query 为 1–256 个代码单元(去除首尾空白后不能为空);ref 为 1–128;files[] 包含 1–256 个条目,每个条目为 1–1024 个仅限 POSIX 的字符(不得以 / 开头,不得包含 ..、盘符或反斜杠);status 最多 6 个,scope 最多 3 个,tags 最多 32 个、每个最多 64 个字符;结果和发现项的分页默认 20 条,最多 100 条;每条记录的 ADR 源内容上限为 64 KiB(超大记录会被排除,并作为 record-too-large 发现项显示,绝不会截断)。每个输入对象都经过严格校验——任何未知字段都会在访问语料库前被拒绝。

分页与游标重启

每个可增长的通道都会返回一个 cursor(最后一页时为 null)。游标是不透明且带版本的,并同时绑定语料库指纹和调用的查询形状。仅当请求参数完全相同且语料库未发生变化时,才可复用返回的游标;否则,响应会返回非错误的 invalid-cursor 结果(corpus-changed、query-mismatch、wrong-channel、offset-out-of-range、cursor-not-applicable、version-unsupported 或 decode-failed),此时应从不带游标的状态重新开始遍历。主要结果通道和 findings 通道分别分页。无法读取 ADR 目录时,会返回 corpus-unavailable 结果。

边界(有意排除的范围)

不提供第五个工具;不执行写入、提案或 PR 创建;不提供 MCP 提示词、资源、订阅或采样;不支持 HTTP/SSE 传输或身份验证;不访问模型、嵌入、排名或网络;不使用持久化缓存、索引或数据库;不支持按名称联邦聚合日志或聚合多个代码仓库;不遍历传递性取代关系。

工具链

使用 Bun 开发和测试;发布的制品为面向 Node.js >=22 的 ESM,并已在 Node 22 和 24 上验证。运行时依赖严格限定为 @adrkit/core、@modelcontextprotocol/server(MCP TypeScript SDK v2)和 zod。

Apache-2.0。

评论

支持 Markdown

第一次接触 MCP?

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

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