Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
作者提供的说明(英文原文)
Send a thought, get one metathought that makes your agent inspect its own assumptions. Keyless.
这三项永远不会合并成一个分数:意见、测量和人气是不同的东西。
我们还没有为它写通俗的介绍。下面是我们从注册中心读取到的事实。
选择你使用的 AI 应用,然后复制设置。
你需要
你用的是哪个应用?
在上方选择你的应用。我们会记住它,下次按钮会显示“安装到 …”。
适用于网页版、桌面版和手机版 Claude:
https://api.ejentum.com/self-inspect-mcp打开 Claude Desktop → Settings → Developer → Edit Config,把下面的内容粘贴到 claude_desktop_config.json
{
"mcpServers": {
"self-inspect": {
"command": "npx",
"args": [
"-y",
"self-inspect-mcp"
]
}
}
}在终端中运行这条命令
claude mcp add --transport http self-inspect https://api.ejentum.com/self-inspect-mcpclaude mcp add self-inspect -- npx -y self-inspect-mcp粘贴到项目中的 .cursor/mcp.json,或 ~/.cursor/mcp.json
{
"mcpServers": {
"self-inspect": {
"url": "https://api.ejentum.com/self-inspect-mcp"
}
}
}粘贴到项目中的 .cursor/mcp.json,或 ~/.cursor/mcp.json
{
"mcpServers": {
"self-inspect": {
"command": "npx",
"args": [
"-y",
"self-inspect-mcp"
]
}
}
}浏览器会先询问是否打开应用,然后应用会显示设置并请你确认。密钥的值会留空,由你自己填写。
粘贴到项目中的 .vscode/mcp.json
{
"servers": {
"self-inspect": {
"type": "http",
"url": "https://api.ejentum.com/self-inspect-mcp"
}
}
}粘贴到项目中的 .vscode/mcp.json
{
"servers": {
"self-inspect": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"self-inspect-mcp"
]
}
}
}浏览器会先询问是否打开应用,然后应用会显示设置并请你确认。密钥的值会留空,由你自己填写。
ChatGPT 只能连接互联网上的服务器:
https://api.ejentum.com/self-inspect-mcp菜单名称可能因套餐和版本不同而略有差异。
你的选择通过 Cookie 保存在这台设备上,无需账户。
这些设置是根据作者在注册中心的条目生成的。如果 README 的写法不同,请以 README 为准。
我们还没有读取这个服务器的工具列表;我们会轮流检查各个端点。
我们检查的是任何人都能看到的信息;我们没有阅读代码。不适用的检查项不计入总数。 · 检查于 2026年11月8日
注册名称已通过 GitHub 账户 ejentum 验证,该账户拥有此仓库
我们还没有从 GitHub 读取这个仓库
我们还没有从 GitHub 读取这个仓库
尚未检查;我们会轮流检查各个端点
尚未检查;我们会轮流检查各个端点
尚未检查;我们会在检查端点时读取工具列表
与注册中心里这个分类中所有活跃的服务器比较。只有当发布者拥有该仓库时,星标数才计入。
它在 1 项适用的基础检查中通过了 1 项。我们没有阅读代码。在添加密钥或令牌之前,请先看看这个服务器要求哪些权限,并使用只具备所需权限的密钥。
注册中心没有列出必需的密钥,不过有些服务器会在首次使用时要求你登录。
两种方式都可以:安装在你的电脑上,或者连接云端版本。
GitHub 仓库最后更新于–,最新版本(0.1.1)于5个月前进入注册中心。
支持 MCP 的应用,例如 Claude Desktop、Claude Code、Cursor 和 VS Code。它通过 URL 连接,所以接受远程 MCP 服务器的应用也可以使用,例如开启开发者模式的 ChatGPT。
同一分类中有:Spec Driven Development, Remote Desktop Commander, Tethered Trust
同一分类中其他作者的服务器,按星标数排序。
如何看卡片:↓ 每周下载量i★ GitHub 星标i三大支柱:评价 · 检查 · 使用情况i更新 = 最新版本发布到注册中心的时间i
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Fit, compatibility and recall checks for AI agents before they buy: verdicts, evidence, receipts.
按原文从作者的仓库复制。PopNx MCP 没有审查或背书其内容。HTML、图片和脚本已被移除。链接会离开本站。
A question your agent would not think to ask itself.
An agent sends a thought, or a description of the task it is working on. It gets back one *metathought*: a short, abstract question that turns the agent's attention back onto its own task and assumptions before it continues. Not advice, not an answer. A question.
Keyless, free, deterministic. No LLM, no embeddings, no semantic similarity. Selection is a small heuristic over an open CSV you can read in five minutes, and the code that answers api.ejentum.com/self-inspect is the code in this repo. A test proves the two cannot drift.
Agents move forward. That is the whole problem. Left to itself, an agent:
None of these are knowledge failures. The model already knows better. They are attention failures: the agent never stops to ask the one question that would have caught it.
And it cannot reliably ask that question itself. Whatever picks what to reflect on is the same process that is already committed, so an agent that "double-checks" tends to re-run its own bias and call it confidence. Acknowledging a trap is not escaping it.
Self-Inspect is the external question. It returns a metathought the agent would not have produced on its own: *What is assumed? What is fixed? What does not follow? What is missing? When would this not hold? What confidence is warranted?* The agent still does the thinking. The tool just makes it look.
Put it in the loop at the moments an agent would otherwise barrel through:
Send a thought, get a metathought, answer it to yourself, continue with more awareness. It always returns a question (there is no "no result" case), one call, no model in the loop, no key.
Self-inspect hands back the one question that names the assumption your claim is quietly resting on. Answer it with a concrete counterexample and rebuild the claim around what breaks; do not just acknowledge the question and move on. Call it only at a genuine wall you cannot get past on your own, never on a schedule: forcing it every step manufactures fake corrections that read worse than using nothing. (This recipe is what separated the strongest runs from the weakest in our own evaluation.)
From a multi-run benchmark (a small model and a frontier model, 40-turn open-ended reasoning, blind order-swapped judging):
Send a thought, get a metathought. No key.
REST (any language):
curl -s -X POST https://api.ejentum.com/self-inspect \
-H "Content-Type: application/json" \ -d '{"thought":"I am committing to this architecture and treating it as fixed"}'
MCP, Claude Code:
claude mcp add --transport http self-inspect https://api.ejentum.com/self-inspect-mcp
MCP, Claude Desktop / Cursor / any HTTP-MCP client:
{
"mcpServers": { "self-inspect": { "type": "http", "url": "https://api.ejentum.com/self-inspect-mcp" } } }
The MCP server exposes one tool, self_inspect, that takes a thought and returns the metathought. No install, no key.
Python (single file, zero dependencies):
For Python environments, dist/self_inspect.py is the whole engine in one file — the CSV is inlined, stdlib only, nothing to install. It runs the exact published selector locally (~2 ms per call, no network):
python self_inspect.py "I am committing to this architecture and treating it as fixed"
from self_inspect import self_inspect
self_inspect("I am about to assert the default timeout is 30s from memory")
A cross-language parity test (test/parity.python.test.mjs) holds it byte-identical to the JS engine — same thought, same metathought, in Python, JS, or against the hosted endpoint.
| Surface | Endpoint | Auth | Returns |
|---|---|---|---|
| REST | POST https://api.ejentum.com/self-inspect | keyless, per-IP rate limit (120/min) | [{ label, metathought }] |
| MCP over HTTP | https://api.ejentum.com/self-inspect-mcp (Streamable HTTP) | keyless, per-IP rate limit (60/min) | tool self_inspect -> metathought text |
| MCP stdio / offline | the mcp/ package; SELF_INSPECT_LOCAL=1 runs the selector locally | keyless | tool self_inspect (npx self-inspect-mcp) |
Both hosted endpoints are keyless and protected by per-IP rate limiting plus standard security headers (HSTS, nosniff, frame-deny).
select(thought, rows) (src/selector.js) routes in two levels, deterministically, over the data in selfinspect.csv:
src/normalize.js).input_type): 3 x (type-name tokens present in the thought) + 1 x (distinct content tokens from that lens's questions present). Content tokens are the meta_thought words minus a small visible stopword list. Evidence aggregates across all of a lens's questions, so a lens can win on signal spread across several of its rows.strict over booster, then lexicographic lens name.operator_rank (the canonical question). matched: true.matched: false.Self-Inspect always returns a metathought. There is always a worthwhile question an agent can ask about its own task and assumptions, so the tool never returns null. The matched flag distinguishes a routed lens (true) from a universal default (false); the metathought is never empty. Deterministic: the same input always returns the same metathought. (To make more inputs route to a specific lens, add wording to the CSV, or a future triggers column, never a model.)
selfinspect.csv (~50 lenses, 137 questions):
| column | role | shipped to caller |
|---|---|---|
input_type | the cognitive lens; its name tokens are routing keys, weighted x3 | as part of id |
operator_rank | order within the lens (1 = canonical); tiebreak | as part of id |
runtime_tier | strict (core) or booster (perceptual); strict preferred on ties | no |
meta_thought | the returned text (verbatim) AND a source of content routing tokens | yes |
The returned id is input_type-operator_rank (e.g. confidence-4). To add or change a metathought, edit the CSV. Do not edit dist/backend.cjs or the deployed copy by hand.
npm run build regenerates dist/backend.cjs (the engine behind the hosted endpoint) and dist/self_inspect.py (the single-file Python port) from selfinspect.csv + src/normalize.js + src/selector.js (build/generate.mjs).
test/drift.test.mjs fails if either committed artifact is not byte-identical to the generator output, and test/parity.python.test.mjs fails if the Python port's results diverge from the JS selector on the full corpus. So an engine that drifts from the CSV/selector, in either language, cannot pass CI: the full suite runs on every push and pull request (.github/workflows/ci.yml), on a runner with Python installed so the parity test actually executes. Anyone can clone this repo, run the fixtures locally and against the live endpoint, and confirm identical selection.
npm test # selector fixtures + drift test
npm run build # regenerate dist/backend.cjs git diff --exit-code dist/backend.cjs # clean == no drift
What does the metathought actually change? In a 30-turn software-design conversation, agents that called Self-Inspect once per turn surfaced ~3.5x more decision-forks (assumptions, edge cases, preconditions) than the *identical* agent with no tool: same model (Claude Sonnet 4.6), same conversation, same prompt.
And the question is *aimed*, not generic: the routing tracked the moment. When would this not hold? arrived as the agent was making a boundary call; What is assumed? arrived as it was about to persist state, and it answered *"I've been assuming persistence lives outside the module"* — surfacing an assumption it had never stated.
The full data, the verbatim metathoughts, and a one-command reproduction (node evals/tools/analyze.mjs) are in evals/.
REST returns an array of one object with exactly two fields: label (the lens, from input_type) and metathought (the question). Unroutable input still returns a universal default (a different lens, same shape):
{"thought":"How much confidence is warranted in this result?"} -> [{ "label": "confidence", "metathought": "What confidence is warranted?" }]
{"thought":"order a pizza"} -> [{ "label": "sequence", "metathought": "What order is active?" }]
The MCP surfaces (self_inspect) return the metathought text only.
The hosted side runs dist/backend.cjs (the CommonJS build of the same CSV + selector) inside an Express route, mounted keyless and iso
只显示了开头部分;其余内容请在仓库中阅读