关于 AsItIs
AsItIs 是只读 MCP 服务和命令行工具,用于检查编码 Agent 的 Markdown 指令文件。它提供结构查看、lint、上下文预算和修复预览功能,不会修改文件。
主要功能
- 01读取 Markdown 并提供字节级元数据
- 02提取标题大纲并 lint 指令文件
- 03估算 Agent 上下文令牌预算
- 04按加载时机查找指令文件
- 05以差异形式建议修复但不写入
适用场景
- 01使用前审查 Agent 指令文件
- 02查找失效链接和相互冲突的规则
- 03估算每次会话加载指令的上下文成本
- 04在 CI 或 pre-commit 中检查指令文件
MCP 相关
MCP 服务提供六种只读工具,用于读取、提纲整理、lint、预算估算、查找和建议修复 Markdown 指令文件。它通过 stdio 通信,并仅在配置的根目录范围内读取。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
@asitis/mcp
用于 Markdown 文件和 AI Agent 指引文件的只读 MCP 服务。 来自 AsItIs,一款绝不会重写文件的 Markdown 编辑器。采用 MIT 许可证。源代码、问题反馈和 Claude Code 插件:github.com/Katta041/asitis-agent-tools。
它为你的编码 Agent 提供六种工具,可读取、梳理大纲、检查问题、评估预算并建议修复 CLAUDE.md、AGENTS.md、GEMINI.md、SKILL.md、子 Agent、命令、规则、Cursor .mdc 规则、Copilot 指引和记忆文件,而且无法修改其中任何文件。同一个软件包还提供 asitis 命令,可用于 CI 和提交前检查。
- 不会写入。 软件包中没有写入、修补或删除工具,也没有任何写入代码。
- 不访问网络。 没有遥测、更新检查或远程调用。它只通过标准输入/输出与 MCP 通信。
- 仅限你的文件夹。 它只读取你启动时指定的一个或多个文件夹中的 Markdown 文件,以及自身的
.asitisrc.json和根目录中的.gitmodules,除非调用请求选择加入技能或配置扫描。
安装
需要 Node 22.13 或更高版本。请始终固定版本;切勿在 Agent 配置中使用 @latest。MCP 客户端会在项目之外启动服务,因此请为 --root 提供绝对路径。
检查是否可以运行:
npx -y @asitis/[email protected] --version
Claude Code
在项目文件夹中运行:
claude mcp add asitis -- npx -y @asitis/[email protected] --root "$PWD"
或者安装 Claude Code 插件。该插件提供字节级保真编辑技能、/asitis:md-lint、/asitis:md-budget 和可选的防护钩子,并在 Node 的权限模型下运行此服务:
claude plugin marketplace add Katta041/asitis-agent-tools
claude plugin install asitis@asitis
Claude Desktop
macOS 上的 ~/Library/Application Support/Claude/claude_desktop_config.json,Windows 上的 %APPDATA%\Claude\claude_desktop_config.json:
{
"mcpServers": {
"asitis": {
"command": "npx",
"args": ["-y", "@asitis/[email protected]", "--root", "/absolute/path/to/project"]
}
}
}
Cursor
项目中的 .cursor/mcp.json(或 ~/.cursor/mcp.json):
{
"mcpServers": {
"asitis": {
"command": "npx",
"args": ["-y", "@asitis/[email protected]", "--root", "${workspaceFolder}"]
}
}
}
如果你的 Cursor 版本无法展开 ${workspaceFolder},请使用绝对路径。如果根路径仍包含 ${...},服务会拒绝使用该路径,而不会自行猜测。
VS Code
项目中的 .vscode/mcp.json(Copilot Agent 模式)。VS Code 使用 servers 键,而不是 mcpServers:
{
"servers": {
"asitis": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@asitis/[email protected]", "--root", "${workspaceFolder}"]
}
}
}
Codex(命令行、IDE 和桌面版)
~/.codex/config.toml:
[mcp_servers.asitis]
command = "npx"
args = ["-y", "@asitis/[email protected]", "--root", "/absolute/path/to/project"]
Gemini CLI
项目中的 .gemini/settings.json(或 ~/.gemini/settings.json):
{
"mcpServers": {
"asitis": {
"command": "npx",
"args": ["-y", "@asitis/[email protected]", "--root", "/absolute/path/to/project"]
}
}
}
强化安全:Node 的权限模型
直接在 Node 的权限模型下运行该文件,由 Node 自身阻止写入和子进程(Node 25 及更高版本还会阻止网络访问):
npm install -g @asitis/[email protected]
node --permission \
--allow-fs-read="$(npm root -g)/@asitis/mcp" \
--allow-fs-read=/absolute/path/to/project \
"$(npm root -g)/@asitis/mcp/dist/asitis-mcp.mjs" --root /absolute/path/to/project
在客户端配置中,command 为 node,其余每个词都按相同顺序放入 args。将 $(npm root -g) 替换为该命令打印出的文件夹,因为配置不会运行 Shell 命令。
如果桌面应用找不到 npx 或 node,请使用其完整路径(运行 which npx,Windows 上运行 where npx)作为 command。
CLI 和 CI
此软件包还提供 asitis 命令,供脚本、CI 和 pre-commit 使用。它采用与 lint_steering 相同的方式进行检查,并返回以下退出码:0(无问题)、1(发现达到或高于 --fail-on 阈值的问题,默认为 error)、2(可修复的问题,并在 stderr 输出一行说明)或 3(asitis 中的错误)。
npx -y -p @asitis/[email protected] asitis lint # every steering file under the current folder
npx -y -p @asitis/[email protected] asitis lint CLAUDE.md AGENTS.md # only these files
npx -y -p @asitis/[email protected] asitis lint --format sarif > asitis.sarif
npx -y -p @asitis/[email protected] asitis lint --fix-preview=safe | git apply # apply the safe fixes yourself
npx -y -p @asitis/[email protected] asitis budget # tokens each agent loads every session
输出格式:text、json、sarif(GitHub code scanning 读取的标准报告格式)和 github(拉取请求批注)。使用 github 时,只有错误和警告会生成批注;添加 --annotate-notes 也会为提示生成批注。它不会写入文件;--fix-preview 会输出差异,由你决定是否应用。asitis lint --help 和 asitis budget --help 会列出各命令的选项。
$ npx -y -p @asitis/[email protected] asitis lint --include skills
.claude/skills/release/SKILL.md:4:1 warning sec-skill-allowed-tools allowed-tools pre-approves "Bash" (any shell command), so during the turn that invokes this skill those calls go ahead without asking you; scope each entry to the commands it needs, for example Bash(git status *) or WebFetch(domain:docs.example.com)
CLAUDE.md:7:1 warning duplicate-rule Same rule as line 5: "Run `pnpm test` before every commit". Duplicates cost context and drift apart when one is edited; keep one
CLAUDE.md:9:1 warning broken-link Relative link target not found: "docs/api.md". Fix the path or remove the link
CLAUDE.md:11:1 note hidden-comment 1 comment (HTML or [//]: # style) is hidden in rendered views on line 11: "maintainer note: keep this short". It does not read like an instruction to an agent; Claude Code strips it from CLAUDE.md at session start, though its Read tool and other agents still see it, so check that it says what you expect
Linted 2 files: 0 errors, 3 warnings, 1 note.
Skill scan: 1 skill folder, 0 scripts and 0 markdown files read, 0 other files checked for executable headers (0 files in all).
该次运行返回 0:使用默认的 --fail-on error 时,只有错误会导致构建失败。植入的不可见字符或双向文本字符,以及指示 Agent 忽略指令、隐藏内容、运行命令或获取机密信息的隐藏注释,都属于错误,因此默认会导致构建失败。传入 --fail-on warning 也会让警告导致构建失败。
GitHub Action。 无需安装 npm,即可运行内置 CLI 并将问题添加到拉取请求中:
permissions:
contents: read
jobs:
asitis:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 22
- uses: Katta041/[email protected]
pre-commit。 仅检查暂存区中的 steering 文件:
repos:
- repo: https://github.com/Katta041/asitis-agent-tools
rev: v0.3.0
hooks:
- id: asitis-lint
docs/ci.md 介绍了 Action 的输入和 SARIF 上传,以及 lefthook、husky 和 GitLab CI。所有标志和退出码均列于 docs/cli-contract.md。
配置
在项目根目录下放置 .asitisrc.json。所有配置项均为可选:
{
"$schema": "https://raw.githubusercontent.com/Katta041/asitis-agent-tools/main/packages/mcp/schema/asitisrc-1.json",
"extends": "recommended",
"rules": {
"duplicate-rule": "off",
"length": ["warning", { "claudeMdLines": 300 }]
},
"ignore": ["vendor/**", "examples/**"],
"overrides": [{ "files": ["docs/**"], "rules": { "contradiction": "off" } }],
"include": ["skills", "config"]
}
| 键 | 作用 |
|---|---|
rules | 按规则 ID 设置为 error、warning、note 或 off。length 还接受 claudeMdLines、skillMdLines、cursorRuleLines、codexBytes、windsurfChars 和 memoryIndexLines。 |
extends | recommended(默认值)或 strict:提示会变为警告;会出现两条清单提示(纯钩子、未列出 tools 的子 Agent);在 CLI 和 Action 中,还会运行技能和配置扫描。 |
ignore、overrides | 要跳过的文件 glob,以及按 glob 设置的规则。 |
include | 可选扫描项:skills、config、config-local。CLI 和 Action 会应用此配置。MCP 服务会忽略此配置,并要求你向 lint_steering 传入 include,因此仓库无法让服务读取超出你要求范围的内容。 |
拼写错误会导致运行停止,并显示文件、行号和建议(.asitisrc.json line 2: unknown key "rulez" (did you mean "rules"?))。
若要忽略单条发现,请在其上方添加带有规则 ID 的注释:``,或使用 asitis-disable-file 忽略整个文件。-- 后的原因是可选的;填写后会包含在 JSON 和 SARIF 输出中。规则 ID 是每条发现中严重性后面的词,所有规则均列于 docs/rules/。安全规则(隐藏指令、不可见字符、sec-* 规则)无法通过注释忽略,因为攻击者恰恰会添加这样的注释;请在 .asitisrc.json 或基线中关闭这些规则,以便在审查中看到相关配置。对于现有仓库,运行 asitis lint --format json --write-baseline > .asitis-baseline.json,然后传入 --baseline .asitis-baseline.json,即可只报告新发现的问题。
每条规则都有附带示例的页面:docs/rules/。
工具
| 工具 | 返回内容 |
|---|---|
read_markdown | 文件中存储的原始文本,以及字节概况:编码、BOM、CRLF/LF/CR 数量、末尾换行、尾随空白、无效 UTF-8 字节范围、sha256。支持对大型文件分页读取(offset_bytes、max_bytes,默认 256 KB,最大 1 MB)。as: "base64" 会返回精确的字节内容。会将内容标记为不可信,并概述隐藏字符和注释。 |
outline | ATX 和 setext 标题及其行号,会跳过 frontmatter 和围栏代码。 |
lint_steering | 检查第 1 行是否为 frontmatter 且 YAML 是否有效;检查 SKILL.md 和子 Agent 是否包含必需的 name 和 description;未知键;长度是否符合供应商限制;失效的相对链接和 @path 导入;零宽字符、双向文本字符及其他不可见字符;看起来像指令的隐藏 HTML 注释;通过内联样式隐藏的文本;重复和看似矛盾的规则;跨文件检查 Claude Code 永远不会读取的 AGENTS.md、彼此内容不一致的镜像文件,以及 Codex 的共享 32 KiB 预算。未指定路径时,会检查文件夹中的所有 steering 文件。会应用 .asitisrc.json 和抑制注释。include: ["skills"] 还会扫描技能文件夹中的脚本,include: ["config"] 会审计 .claude/settings.json 和 MCP 配置文件。 |
context_budget | 估算每个文件和每个工具在每次会话中加载的内容所占的 token 数:Claude Code(CLAUDE.md 及最多 4 层的 @imports;若没有 CLAUDE.md,则为 AGENTS.md;没有 paths 的规则;将记忆文件夹添加为第二个根目录时,读取 MEMORY.md 的前 200 行;技能和子 Agent 列表)、Codex(根目录 AGENTS.md,前 32 KiB)、Gemini CLI(GEMINI.md 及最多 5 层的导入)、始终应用的 Cursor 规则、Copilot 仓库说明、Windsurf 和 Cline 规则。长列表会被截断;总数仍会计入每个文件。 |
find_steering_files | 所有 steering 文件,并按加载时机分组:每次会话、匹配时(paths、globs、applyTo)、调用时(技能、命令、Agent、提示词)、按需加载(嵌套指令文件)、记忆。 |
suggest_fixes | 针对机械性问题的修复方案(不可见字符、frontmatter 不在第 1 行、技能名称字段、尾随空白、缺少末尾换行、类似指令的 HTML 注释),以统一差异格式呈现,并附上每处编辑的修改前后文本。每项修复均标记为安全或需审核。它不会写入文件;由你的助手应用你接受的修改。 |
每个工具都标注为 readOnlyHint: true、destructiveHint: false、openWorldHint: false。除非你主动请求,否则工具结果不会包含指向 asitis.app 的链接:启用 --footer(或设置 ASITIS_MCP_FOOTER=1)时,每个会话的第一条结果末尾会附上一行 Edit these files without rewriting them: https://asitis.app/?ref=mcp,后续结果和错误不会重复此行。仍然接受 --no-footer,但不会产生任何影响。结果仅包含文本。传入 --structured(或设置 ASITIS_MCP_STRUCTURED=1)后,还会在 structuredContent 中以 JSON 格式返回每条结果,供脚本使用。默认关闭,因为 Claude Code 2.1 在文本和 JSON 同时存在时会将 JSON 而非文本提供给模型,从而丢失不可信内容提示,以及 read_markdown 返回的文件文本。
检查的供应商限制及其来源见 src/limits.ts:
| 文件 | 限制 |
|---|---|
| CLAUDE.md | 建议少于 200 行(Claude Code 记忆文档) |
| SKILL.md | 少于 500 行;列表中 description 加 when_to_use 会截断至 1,536 个字符(Claude Code 技能文档);name 最多 64 个字符,description 最多 1,024 个字符(Agent Skills 规范;Claude API 和 claude.ai 会拒绝更长的内容,而 Claude Code 会加载这些内容并截断列表中的显示) |
| MEMORY.md | 加载前 200 行或 25 KB(Claude Code 记忆文档) |
| AGENTS.md | Codex 加载的所有 AGENTS.md 文件合计 32 KiB,按根目录优先(project_doc_max_bytes) |
| Cursor 规则 | 少于 500 行 |
| Windsurf 规则 | 每个工作区规则文件 12,000 个字符(global_rules.md 为 6,000 个字符) |
隐私
- 服务和 CLI 不建立网络连接,也不包含网络代码。它们不会收集或发送任何内容。
- 它们绝不会写入、重命名或删除文件,也不会创建临时文件。修复结果会以差异形式返回;是否应用由你或你的助手决定。
- 默认情况下只读取 Markdown 指导文件、
.asitisrc.json,以及在相对链接缺失时读取根目录的.gitmodules(用于判断断开的链接是否指向尚未检出的子模块)。只有在传入include: ["skills"](或--include skills)时才会读取技能脚本;只有在传入include: ["config"]时才会读取.claude/settings.json、.mcp.json、.cursor/mcp.json、.vscode/mcp.json和.gemini/settings.json。此时还会读取根目录package.json和pyproject.toml中的name、homepage和repository,以便识别项目自身的 MCP 服务和安装脚本。.claude/settings.local.json需要config-local。绝不会读取~/.claude.json。设置文件中的值绝不会被回显:发现项会指出键名,任何看起来像密钥的内容都会被遮盖。 - 它会在 stderr 输出一行启动日志(版本和根文件夹),绝不包含文件内容。
- 你的助手如何处理结果由你的助手决定。 工具结果会进入模型的上下文,因此会传给你的助手所使用的 AI 提供商。这属于你的助手的网络流量,与我们无关。
安全模型
- 根目录限制。 每个路径都会通过
realpath解析,并且必须位于启动时指定的根目录内。拒绝../路径遍历、指向根目录外的绝对路径,以及解析后指向根目录外的符号链接(文件或文件夹)。解析后指向根目录内的符号链接会被跟随,因此会按 Agent 所见的方式检查链接到 AGENTS.md 的 CLAUDE.md 或链接到的.claude/skills文件夹。除非传入--allow-broad-root,否则不允许将文件系统根目录和主目录设为根目录。 - 默认仅处理 Markdown,除非你选择加入。 默认只读取
.md、.mdc、.markdown、.mdx、.cursorrules、.windsurfrules和.clinerules,以及.asitisrc.json(最多 64 KB)。include: ["skills"]会添加技能文件夹中的脚本(每个最多 1 MB;其中的其他文件只读取前 4 字节以检测二进制文件),include: ["config"]会添加“隐私”下列出的 Agent 设置和 MCP 配置文件。始终拒绝.env*、.git/或node_modules/中的任何内容、~/.claude.json以及所有其他文件,包括通过指向这些文件的符号链接访问时。仓库的.asitisrc.json无法在 MCP 服务中启用这些扫描;只有调用(或 CLI 标志)可以启用。其他文件的@imports只按其大小计数,不会被读取。任何读取的内容都不会被执行。 - 限制工作量。 拒绝超过 16 MB 的文件(
--max-file-mb),限制结果大小,每次工具调用的预算为 20 s,并且所有扫描器的运行时间均为线性。测试套件会在每次调用 3 s 的预算下,将 32 个对抗性 10 MB 输入(未闭合的注释、括号和反引号风暴、2,000 字符的导入令牌、无效 UTF-8 等)交给每个工具处理。 - 不可信内容。
read_markdown会将文件内容标记为数据而非指令,并预先报告隐藏指令和不可见字符。这无法阻止模型遵从所读取的文本,但会让这些文本显现出来。 - 更强的沙箱,可选。 在 Node 的权限模型下运行服务,使运行时本身禁止写入和启动子进程(Node 25 及更高版本还会禁止网络访问)。“安装”中的 Hardened 设置介绍了具体方法;Claude Code 插件默认启用此功能。
已知限制
- 令牌数是本地近似值(英语约为每个令牌 4 个字符),并非任何供应商的分词器结果。
- 根目录内指向其他位置文件的硬链接会像其他文件一样读取(只读)。
- 在检查和打开之间替换父文件夹中的符号链接,是一种小概率竞态;最终路径组件会通过
O_NOFOLLOW打开,并按 inode 检查。 - 在 Windows 上,会根据真实路径判断并测试 junction、大小写折叠路径、8.3 短名称、
\\?\和\\.\设备前缀、UNC 路径以及末尾的点或空格。替代数据流(notes.md:stream)和保留设备名称(CON、NUL.md)会被直接拒绝。
选项
asitis-mcp --root <folder> [--root <folder>...] [options]
--root <folder> Folder the server may read (repeatable). Default: the current folder.
--footer Add one line linking to asitis.app to the first result of the session. Off by default.
--structured Also return each result as JSON (structuredContent), for scripts. Off by default.
--max-file-mb <n> Largest file to analyse, in MB (default 16, max 64).
--allow-broad-root Allow your home folder or the filesystem root as the root.
--version Print the version.
--help Print this help.
ASITIS_MCP_ROOT(文件夹之间用 : 分隔;Windows 上用 ;)、ASITIS_MCP_FOOTER=1 和 ASITIS_MCP_STRUCTURED=1 均可用作环境变量。对于位于项目之外的记忆文件夹,可再添加一个 --root,例如 ~/.claude/projects/<project>/memory。
出错时会打印一行并以代码 2 退出,例如:
asitis-mcp: Root folder not found: /x. Pass an existing folder with --root.
软件包
此软件包包含两个文件:服务 dist/asitis-mcp.mjs 和 CLI dist/asitis.mjs(使用 esbuild 构建并已压缩),没有运行时依赖,也没有安装脚本。软件包内置 MCP SDK(固定为 1.31.0)、zod 和 yaml;其许可证位于 dist/THIRD_PARTY_NOTICES.md。此仓库中的发布工作流(.github/workflows/release.yml)会通过 npm provenance 发布,因此发布的版本会在 npmjs.com 上显示来源证明,并可通过 npm audit signatures 验证。最高至 0.2.4 的版本均为手动发布,未附带来源证明。
许可证
MIT。变更记录列于更新日志。请通过 GitHub 安全公告私下报告漏洞。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。