Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
作者提供的说明(英文原文)
Human approvals, notifications, inbound webhooks, wake-ups for headless agents. Free trial: /try
这三项永远不会合并成一个分数:意见、测量和人气是不同的东西。
我们还没有为它写通俗的介绍。下面是我们从注册中心读取到的事实。
选择你使用的 AI 应用,然后复制设置。
Authorization标为机密的值是你账户的钥匙。千万不要分享给别人,也不要粘贴到聊天里。
你需要
你用的是哪个应用?
在上方选择你的应用。我们会记住它,下次按钮会显示“安装到 …”。
这个地址需要在请求的 header 中放入密钥,而添加连接器的菜单无法设置。请改用 Claude Code、Cursor 或 VS Code。
在终端中运行这条命令
claude mcp add --transport http pendnt https://api.pendnt.dev/mcp --header 'Authorization: your-value'运行前请先填写空着的值。
粘贴到项目中的 .cursor/mcp.json,或 ~/.cursor/mcp.json
{
"mcpServers": {
"pendnt": {
"url": "https://api.pendnt.dev/mcp",
"headers": {
"Authorization": "your-value"
}
}
}
}浏览器会先询问是否打开应用,然后应用会显示设置并请你确认。密钥的值会留空,由你自己填写。
粘贴到项目中的 .vscode/mcp.json
{
"servers": {
"pendnt": {
"type": "http",
"url": "https://api.pendnt.dev/mcp",
"headers": {
"Authorization": "your-value"
}
}
}
}浏览器会先询问是否打开应用,然后应用会显示设置并请你确认。密钥的值会留空,由你自己填写。
这个地址需要在请求的 header 中放入密钥,而添加连接器的菜单无法设置。请改用 Claude Code、Cursor 或 VS Code。
你的选择通过 Cookie 保存在这台设备上,无需账户。
Authorization 机密 必填 HTTP header这些设置是根据作者在注册中心的条目生成的。如果 README 的写法不同,请以 README 为准。
我们还没有读取这个服务器的工具列表;我们会轮流检查各个端点。
我们检查的是任何人都能看到的信息;我们没有阅读代码。不适用的检查项不计入总数。 · 检查于 2026年11月6日
注册名称已通过域名 pendnt.dev 验证(注册中心会核实域名所有权)
我们还没有从 GitHub 读取这个仓库
我们还没有从 GitHub 读取这个仓库
尚未检查;我们会轮流检查各个端点
尚未检查;我们会轮流检查各个端点
尚未检查;我们会在检查端点时读取工具列表
与注册中心里这个分类中所有活跃的服务器比较。只有当发布者拥有该仓库时,星标数才计入。
它在 1 项适用的基础检查中通过了 1 项。我们没有阅读代码。在添加密钥或令牌之前,请先看看这个服务器要求哪些权限,并使用只具备所需权限的密钥。
你需要填写:Authorization
它在作者的云端运行。通过互联网连接,无需安装,但你发送的内容会经过作者的服务器。
GitHub 仓库最后更新于–,最新版本(0.2.0)于2个月前进入注册中心。
支持 MCP 的应用,例如 Claude Desktop、Claude Code、Cursor 和 VS Code。它通过 URL 连接,所以接受远程 MCP 服务器的应用也可以使用,例如开启开发者模式的 ChatGPT。
同一分类中有:Spec Driven Development, Remote Desktop Commander, 오늘냥이 (Oneul Nyangi)
同一分类中其他作者的服务器,按星标数排序。
如何看卡片:★ 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.
Real cat photos, diaries, profiles, age and food reference calculators, and breeds.
按原文从作者的仓库复制。PopNx MCP 没有审查或背书其内容。HTML、图片和脚本已被移除。链接会离开本站。
Try it in 10 seconds — no account:
curl https://api.pendnt.dev/try?plain=1returns a 72-hour trial key (20 requests) with a quickstart.
Wires a Claude Code session — interactive or headless (claude -p) — up to a pendnt workspace: durable human approvals, notifications, and a "run finished" ping, without the agent needing a terminal.
"pendnt" is a placeholder product name. It's kept in exactly one place — PRODUCT_NAME in lib/config.mjs — plus the name fields in plugin.json, marketplace.json and .mcp.json, and the matching MCP server name registered in /app/src/routes/mcp.ts. Rename all of those together and it's renamed everywhere that matters.
This plugin ships two independent ways to answer permission prompts headlessly — pick one (or both; --permission-prompt-tool takes priority when both are wired up, see §1a below):
hooks/permission-request.mjs) — works with plain claude -p, no extra flags. Runs automatically before every tool-use prompt.--permission-prompt-tool mcp__pendnt__permission_prompt — Claude Code's own dedicated mechanism for headless permission prompts (see INTEGRATIONS.md §1a).Plus a Notification hook and a Stop hook that both relay to POST /v1/notify — see What's included below.
This repo doubles as its own local marketplace — .claude-plugin/marketplace.json lists this plugin with source: "./", pointing at the same directory plugin.json lives in. From Claude Code:
/plugin marketplace add Pendnt/pendnt-plugin
/plugin install pendnt@pendnt
(or non-interactively: claude plugin marketplace add Pendnt/pendnt-plugin && claude plugin install pendnt@pendnt)
To publish for real later, split marketplace.json out into its own repo with source pointing at this plugin's repo (see INTEGRATIONS.md §1d for the marketplace manifest shape and github/git-subdir/npm/archive source types), then claude plugin marketplace add / from anywhere.
| Variable | Required | Default | Meaning |
|---|---|---|---|
PENDNT_API_KEY | yes | — | Authorization: Bearer for every call to the API (aio_..., from POST /dev/bootstrap locally, or your real workspace's API key in production). Without it, the PermissionRequest/Notification/Stop hooks all fail closed (deny / no-op) rather than erroring the session. |
PENDNT_URL | no | https://api.pendnt.dev | Base URL of the pendnt REST API — not including /mcp or /v1. Point this at http://localhost:8787 for local dev against wrangler dev (see below). |
PENDNT_APPROVAL_TIMEOUT_S | no | 600 (10 min) | Total wall-clock budget the PermissionRequest hook spends re-polling before it gives up and denies. Each individual poll is capped server-side at 25s (wait_s), so the hook loops GET /v1/requests/:id?wait_s=25 until this budget runs out. |
Set them in your shell, or in .claude/settings.json under env — see settings.json docs. .mcp.json's ${PENDNT_URL:-...} / ${PENDNT_API_KEY} syntax is Claude Code's own env-var expansion for .mcp.json values (headers *and* URLs) — see INTEGRATIONS.md §1e.
pendnt remote MCP server (${PENDNT_URL:-https://api.pendnt.dev}/mcp, Authorization: Bearer ${PENDNT_API_KEY}) so all 14 tools (request_approval, check_request, permission_prompt, notify, create_endpoint, list_endpoints, wait_for_event, schedule_wakeup, list_wakeups, cancel_wakeup, kv_get, kv_set, kv_delete, whoami) are available to the model directly, under mcp__pendnt__ — except permission_prompt, which Claude Code removes from its own visible tool list once named by --permission-prompt-tool (see below), since it's meant to be called by the CLI itself, not by the model.settings.json's hooks key, see INTEGRATIONS.md §1d):hooks/permission-request.mjs. Fires before every tool-use prompt. POSTs a summary of the tool call to POST /v1/requests (kind: "approval", wait_s: 25, timeout_s: $PENDNT_APPROVAL_TIMEOUT_S), then re-polls GET /v1/requests/:id?wait_s=25 until it's answered or the total PENDNT_APPROVAL_TIMEOUT_S budget elapses. Prints exactly one JSON object per INTEGRATIONS.md §1b's PermissionRequest contract: json { "hookSpecificOutput": { "hookEventName": "PermissionRequest", "decision": { "behavior": "allow", "updatedInput": {} } } } or {"behavior": "deny", "message": "..."}. Fails closed on every error path (missing API key, network failure, operator denies, request expires, timeout) — the only way to get allow is an explicit approval. An operator using the answer page's free-text box (always shown, even for kind: "approval" requests) is treated as approval only if the text starts with yes/y/allow/approve/ok — anything else denies with that text as the reason.hooks/notify.mjs. Relays notification_type/message to POST /v1/notify. Cannot block Claude Code (per the hook's own semantics) and never tries to — always exits 0.hooks/stop.mjs. Relays a "run finished" message to POST /v1/notify at the end of every turn. Never returns {"decision":"block"} — it only notifies, it doesn't keep the agent going.config.mjs (env vars + the PRODUCT_NAME constant), client.mjs (thin fetch wrappers for /v1/requests and /v1/notify), stdin.mjs (hook stdin JSON parsing). No npm dependencies — plain Node 18+ (fetch, AbortController) is enough.--permission-prompt-tool path (§1a)Instead of (or in addition to — Claude Code prefers --permission-prompt-tool over hooks when both apply) the PermissionRequest hook, you can point Claude Code's dedicated permission-prompt mechanism directly at the permission_prompt MCP tool this plugin's .mcp.json registers — the one tool in this server purpose-built for this flag (see /app/README.md's permission_prompt section for the full contract):
export PENDNT_API_KEY=aio_...
export PENDNT_URL=https://api.pendnt.dev # or http://localhost:8787 for local dev export MCP_TOOL_TIMEOUT=600000 # ms — must exceed PERMISSION_PROMPT_WAIT_S (default 540s)
claude -p --permission-prompt-tool mcppendntpermission_prompt "deploy to prod"
Three things worth knowing before you rely on this path:
pendnt MCP server connects, capped by MCP_TIMEOUT (default 30s, env var, milliseconds) — bump it if your network is slow: export MCP_TIMEOUT=60000 (from INTEGRATIONS.md §1a).allow from a --permission-prompt-tool is converted to deny for any MCP tool call flagged _meta["anthropic/requiresUserInteraction"] — this prompt tool can't rubber-stamp those regardless of what the operator answers (also from INTEGRATIONS.md §1a).PERMISSION_PROMPT_WAIT_S (env var on /app, default 540s = 9 min) waiting for the operator, unlike every other tool's ≤25s wait_s. Claude Code's own MCP_TOOL_TIMEOUT (its per-tool-call timeout, ms, default 30000) must be set higher than that or the CLI gives up first — hence export MCP_TOOL_TIMEOUT=600000 above.Unlike request_approval, permission_prompt *does* return Claude Code's exact {behavior, updatedInput, updatedPermissions, interrupt} / {behavior:"deny", message, interrupt} contract natively — an allow echoes the original input back as updatedInput, a deny (or an unanswered timeout) carries a human-readable message. That's the same translation the PermissionRequest hook below does by hand for its own hook-shaped contract; permission_prompt does it as the MCP tool result directly, which is what --permission-prompt-tool actually reads.
export PENDNT_API_KEY=aio_...
export PENDNT_URL=https://api.pendnt.dev export MCP_TOOL_TIMEOUT=600000
claude -p --permission-prompt-tool mcppendntpermission_prompt \ "review open PRs and merge the ones that pass CI"
Or, with the PermissionRequest hook doing the work instead (no extra flag needed once the plugin is installed):
export PENDNT_API_KEY=aio_...
export PENDNT_URL=https://api.pendnt.dev
claude -p "review open PRs and merge the ones that pass CI"
Either way, every tool-use prompt now creates a durable approval request instead of blocking on a terminal that doesn't exist — check your configured channels (email/web inbox — see /app/README.md's "Channels" section for what's actually implemented today), answer from your phone, and the agent resumes.
wrangler devFrom /app:
cd ../app
npm install npm run db:migrate:local npm run dev # http://localhost:8787
In another terminal, bootstrap a workspace + API key (see /app/README.md) and point the plugin's env vars at it:
BOOT=$(curl -s -X POST http://localhost:8787/dev/bootstrap -d '{}')
export PENDNT_API_KEY=$(echo "$BOOT" | jq -r .api_key) export PENDNT_URL=http://localhost:8787
Then either run a hook script directly, feeding it the JSON a real Claude Code hook invocation would send on stdin (useful for iterating on the hook without a full Claude Code session):
echo '{"session_id":"s1","cwd":"'"$PWD"'","tool_name":"Bash","tool_use_id":"toolu_1","tool_input":{"command":"deploy prod"}}' \
| PENDNT_APPROVAL_TIMEOUT_S=60 node hooks/permission-request.mjs
...or install the plugin locally (/plugin marketplace add Pendnt/pendnt-plugin from Claude Code, see Install) and drive a real session — with PENDNT_URL/PENDNT_API_KEY exported in the shell Claude Code runs in, every tool-use prompt round-trips through your local wrangler dev instance. Answer the request the same way /app/README.md's curl walkthrough does: compute the HMAC signature yourself (it's a pure function of the request id and SIGNING_SECRET) and POST /a/ / , or watch the log delivery channel's console output from wrangler dev for the answer link once a real channel is wired up.
fetch/AbortController only) — every hook script runs under plain node hooks/*.mjs, no npm install step inside the plugin itself.PermissionRequest hook's fail-closed defaults (missing key, network error, timeout → deny) are a deliberate safety choice, not a limitation to work around — a headless agent with nobody to ask should not proceed by default.hooks/hooks.json's Notification matcher is not narrowed to specific notification_types — every notification (including ones that aren't permission-prompt-related) gets relayed. Narrow the matcher or filter inside hooks/notify.mjs if that's noisier than you want.Practical writeups on running agents unattended, at pendnt.dev/guides: --dangerously-skip-permissions alternatives · [claude -p on cron](http
只显示了开头部分;其余内容请在仓库中阅读