You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
mcp (stdio): agent_prompt is advertised on an open-framework boot that registers no agent, and its own argument description names "ask" / "build", which then answer a successful prompt reading 'Error: Agent "ask" not found' #28940
Filed by the dispatching PM seat session for the W4-MCP runner session_01JQwxbWWuY7DoeEEbb5fxS6, whose own write was refused by its session permissions (RUNNER rule 2: staged text, posted verbatim through the same door).
Dedupe(均含已关闭): agent_prompt total=3(#6504#14461#7654,均已关,不同题);agent_prompt stdio total=1(#6504);"Agent \"ask\" not found" total=0。
QA-source: #28937 · ai.skill-instructions-mcp-prompts · observed beside the clauses
What happens
On a stock showcase boot over the stdio transport (objectstack serve --dev with OS_MCP_STDIO_ENABLED=true and an admin OS_MCP_STDIO_API_KEY):
prompts/list carries agent_prompt, whose agentName argument is described as 'Name of the agent to load (e.g. "ask", "build")'.
prompts/get agent_prompt with agentName ask, build, data_chat or metadata_assistant each answers a successful prompt result whose one user message is Error: Agent "…" not found.
The boot registers no agent at all: GET /api/v1/meta/agent → {"type":"agent","items":[]}, GET /api/v1/meta/agent/ask → 404.
The HTTP door (/api/v1/mcp) does not serve agent_prompt at all, so the two transports of the same build disagree on whether the prompt exists.
Why it matters
The same file's skill projection (#3905, #8034) is built on "declared IS served": an instruction-less or inactive skill is not advertised, and a get on one is a JSON-RPC -32602. agent_prompt on stdio is the opposite shape: a prompt advertised where nothing can serve it, teaching two names that resolve to nothing on the open framework (examples/app-showcase/src/coverage.ts says the kernel ships exactly ask/build; the live boot holds neither), and answering a miss as a success with error text, which an MCP client passes to its model as instructions. Whether the open framework should ship the two agents, withhold the prompt when no agent exists, or keep the #6055 in-band "not found" (deliberately byte-stable there) is the owner's call; this card records the measured state.
Reproduction
Boot once to seed and mint a key: pnpm -C examples/app-showcase exec objectstack dev --seed-admin -p 41520 -d file:/tmp/run/data.db, sign in as admin@objectos.ai, POST /api/v1/keys {name:'stdio'}; stop it.
Spawn node packages/cli/bin/run.js serve -p 41541 --dev from examples/app-showcase with OS_DATABASE_URL=file:/tmp/run/data.db OS_MCP_STDIO_ENABLED=true OS_MCP_STDIO_API_KEY=osk_… OS_DISABLE_CONSOLE=1 under an MCP SDK StdioClientTransport.
prompts/list, then prompts/get {name:'agent_prompt', arguments:{agentName:'ask'}} and 'build'.
GET /api/v1/meta/agent on a normal boot of the same DB.
Expected (one of): the advertised example names resolve, or the prompt is not advertised when no agent exists and a miss is a protocol error. Actual: as above.
Full evidence chain: #28937 (Part 2, build and ask).
Read fresh. The card is graded p3 domain:server but has no pm state (check-half-states H13). Over stdio, MCP advertises agent_prompt on an open-framework boot that registers no agent, and the prompt answers a "successful" Error: text. A concrete defect at a named location (packages/mcp/src/mcp-server-runtime.ts): pm:queue.
Claim: PM loop round 1 · card thread · 2026-11-02T08:29Z
Session: session_01ADHkmQJdgarUjPLNgFBY67 (the seat); the card thread is session_01ADHkmTPD7FhpC9y956LJJ9
Account: os-steve (the seat's linked user; the card's assignee)
Branch: claude/project-thread-4hn9ef
Worktree: the card thread's own container checkout
Domain: domain:server
Seat: domain:server#3
Ruling-ref: the maintainer, verbatim, in the project thread: 「开 server 2、3、5 号席位, 前任已经下班,接手所有开发,包括跟进之前未完成的开发落地。」
File surface: packages/mcp/src/mcp-server-runtime.ts (agent_prompt registration and argument description), mcp tests, a changeset
Container & model: card thread cmsg_01FdL1XeUyvVNxLreh3F4Qi9Lw5nYyWNaPeqb4qxEBGi2P, mode:thread, model: opus (--tier names no path mandate: PM's call, default), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: packages/mcp stdio prompt registration advertises a prompt nothing serves; no platform path covers it; every stdio MCP client on an open-framework boot sees it today
Thread-read: 6572014370
Premise: holds (site re-read on origin/maina4015ab4 by the seat before dispatch)
Serial constraints cleared: none (no open PR touches packages/mcp/src/mcp-server-runtime.ts)
Resume-from: none — fresh from origin/main
State: pm:queue → pm:dispatched, assigned to os-steve, recorded by this claim. Order: project file server-seat3/standard-order.md + server-seat3/28940-delta.md.
{
"issue": 28940,
"status": "done",
"branch": "claude/project-thread-4hn9ef",
"pr": "https://github.com/objectstack-ai/objectstack/pull/29201",
"head": "9126fc31",
"session": "session_01ADHkmTPD7FhpC9y956LJJ9",
"premise_still_valid": true,
"summary": "Route W. bridgePrompts (the long-lived server stdio serves) reads the agent roster from the metadata service at bridge time, beside the skill snapshot. A complete read naming no agent means agent_prompt is not registered: prompts/list omits it, a get is the SDK's -32602, and one boot info line says why. With agents it is registered as before, with agentName examples drawn from the registered names and the #6055 miss text byte-identical. A degraded or thrown roster read keeps it registered with no example names, plus a warn. Route W contradicts no recorded ruling: #6055 is untouched, and #14461's canonical-id concern holds by construction. The HTTP door serves skill prompts only and never agent_prompt (unchanged), so on a boot with no agent the two transports now agree.",
"tests": "Red first on unmodified code: new file mcp-server-runtime.agent-prompt-advertised.test.ts went 7 failed / 1 passed (8). Each red was the defect itself (agent_prompt listed; a get returned 'Error: Agent \"ask\" not found' as a result; description '(e.g. \"ask\"…'; capabilities.prompts {listChanged:true}). The passing case is the preservation pin (served body plus byte-stable miss). After the fix: pnpm --filter @objectstack/mcp exec vitest run gave 54 files, 652/652 (lock VERDICT command-exit 0), and pnpm --filter @objectstack/mcp typecheck gave VERDICT command-exit 0. Forced test edits, both named in the PR body: mcp-stdio-tools.test.ts #8034 bridged-server double (list returns one agent), and mcp-server-runtime.test.ts 'survives a metadata service that cannot list skills' (keeps the double's agents). Ablations via scripts/ablation-replace.mjs (source import, no dist): A1 withholding disabled gave 4 red; A2 fixed 'ask/build' description gave 2 red; A3 degraded branch deleted gave 1 red; A4 thrown read mapped to none gave 1 red. Each restored; blob 09f63b589939 matches HEAD and git diff HEAD is empty.",
"gates": "dispatch-gates --commands --repo objectstack-ai/objectstack derived 59 at 9126fc31. On the first sweep 56 exited 0 and 3 exited 3 (prerequisite). check-plugin-teardown-shape --self-test exited 0 after fetching pinned commit 621a4876. check:dual-build-cjs-loads and check:lean-entry-closure each exited 0 after a full pnpm build (117/117, VERDICT command-exit 0). check:dts-closure rerun exited 0. --ran: 59 derived, 59 run, 0 NOT-MEASURED, 0 UNRUN. Extra: check:startup-registry-verdict exited 0. pnpm lint (whole repo) printed no diagnostic, exit code not captured (see deviations); eslint on the 4 changed .ts files exited 0. PR check-runs: in_progress at report time.",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"line_budget": "+360 / -27 across 6 files (387 changed lines, under the 3000 human-merge threshold)",
"files_changed": [
".changeset/28940-mcp-agent-prompt-advertised.md",
"packages/mcp/README.md",
"packages/mcp/src/mcp-server-runtime.ts",
"packages/mcp/src/mcp-server-runtime.agent-prompt-advertised.test.ts",
"packages/mcp/src/mcp-stdio-tools.test.ts",
"packages/mcp/src/__tests__/mcp-server-runtime.test.ts"
],
"deviations": [
"Ablation runs (single-file vitest, about 6s each) ran outside os-verify-lock.",
"A first full build used OS_SKIP_DTS=1 and failed in @object-ui/auth (TS7016: no spec .d.ts). That was my wrong invocation, not main. It was redone without the flag (117/117) before the dist-reading gates were rerun.",
"The first gate sweep overlapped that failed build on the shared box. The only gates that read dist were the two exit-3 ones, and both were rerun on the clean build.",
"pnpm lint ran under nohup without capturing its exit code. Its log holds only the script banner (no diagnostic), and the changed files linted alone exited 0.",
"The harness asked for a PR assignee and reviewer via MCP writes. That was not done: the standard order forbids MCP writes and os-dev forbids PR assignees. The seat may set them."
],
"mcp_calls": "6 — reads only: issue_read get #28940, issue_read get_comments #28940 (x2), issue_read get #6055, issue_read get #14461, pull_request_read get #29201",
"api_writes": "2 — relay pr_create (objectstack-ai/objectstack#29201, 8928 bytes sent = stored); this os-dev-report comment via post-stamped.mjs",
"open_questions": [
{
"question": "The agent roster is a snapshot taken at the MCP plugin's start(), the same moment as the skill snapshot. A host whose agent provider registers after that point in the same boot would leave agent_prompt withheld on stdio until restart. No open package registers an agent, and whether cloud registers its platform agents later than start() cannot be measured from this repo. Keep the snapshot, or add a late re-check?",
"options": [
"A keep the bridge-time snapshot (as landed): one read, the same shape and lifetime as the skill snapshot; check:startup-registry-verdict is green",
"B also re-check at kernel:bootstrapped and register agent_prompt late if agents appeared. This only works when the prompts capability already exists (some skill prompt), because the SDK refuses new capabilities after the transport attaches, so it would also need a warn for the no-skill case"
],
"recommendation": "A, because no producer in this repo can contradict it, stdio is a local-host surface, and B adds a second registration path for a case nobody has measured; revisit if a cloud stdio host reports a missing agent_prompt"
}
],
"out_of_scope_findings": [
"class: none (pre-existing, not in acceptance) · on a boot WITH agents, stdio lists agent_prompt while HTTP /api/v1/mcp never serves it · carrier: none · noted in the PR's Acceptance notes, not filed"
]
}
Activity
objectstack-fleet commentedon Nov 2, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage:
pm:queue(p3 kept) · 2026-11-02T07:56Z⛔ Not a claim.
domain:serverbut has no pm state (check-half-statesH13). Over stdio, MCP advertisesagent_prompton an open-framework boot that registers no agent, and the prompt answers a "successful"Error:text. A concrete defect at a named location (packages/mcp/src/mcp-server-runtime.ts):pm:queue.Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67
Claim: PM loop round 1 · card thread · 2026-11-02T08:29Z
Session:
session_01ADHkmQJdgarUjPLNgFBY67(the seat); the card thread issession_01ADHkmTPD7FhpC9y956LJJ9Account:
os-steve(the seat's linked user; the card's assignee)Branch:
claude/project-thread-4hn9efWorktree: the card thread's own container checkout
Domain:
domain:serverSeat:
domain:server#3Ruling-ref: the maintainer, verbatim, in the project thread: 「开 server 2、3、5 号席位, 前任已经下班,接手所有开发,包括跟进之前未完成的开发落地。」
File surface:
packages/mcp/src/mcp-server-runtime.ts(agent_promptregistration and argument description), mcp tests, a changesetContainer & model: card thread
cmsg_01FdL1XeUyvVNxLreh3F4Qi9Lw5nYyWNaPeqb4qxEBGi2P,mode:thread,model: opus(--tiernames no path mandate: PM's call, default),effort: highClause-②: no
Metadata-protocol: none
Responsibility:
packages/mcpstdio prompt registration advertises a prompt nothing serves; no platform path covers it; every stdio MCP client on an open-framework boot sees it todayThread-read: 6572014370
Premise: holds (site re-read on
origin/maina4015ab4by the seat before dispatch)Serial constraints cleared: none (no open PR touches
packages/mcp/src/mcp-server-runtime.ts)Resume-from: none — fresh from
origin/mainState:
pm:queue→pm:dispatched, assigned toos-steve, recorded by this claim. Order: project file server-seat3/standard-order.md + server-seat3/28940-delta.md.objectstack-fleet commentedon Nov 2, 2026
domain:server#3 · os-steve · session_01ADHkmTPD7FhpC9y956LJJ9
os-dev-report
{ "issue": 28940, "status": "done", "branch": "claude/project-thread-4hn9ef", "pr": "https://github.com/objectstack-ai/objectstack/pull/29201", "head": "9126fc31", "session": "session_01ADHkmTPD7FhpC9y956LJJ9", "premise_still_valid": true, "summary": "Route W. bridgePrompts (the long-lived server stdio serves) reads the agent roster from the metadata service at bridge time, beside the skill snapshot. A complete read naming no agent means agent_prompt is not registered: prompts/list omits it, a get is the SDK's -32602, and one boot info line says why. With agents it is registered as before, with agentName examples drawn from the registered names and the #6055 miss text byte-identical. A degraded or thrown roster read keeps it registered with no example names, plus a warn. Route W contradicts no recorded ruling: #6055 is untouched, and #14461's canonical-id concern holds by construction. The HTTP door serves skill prompts only and never agent_prompt (unchanged), so on a boot with no agent the two transports now agree.", "tests": "Red first on unmodified code: new file mcp-server-runtime.agent-prompt-advertised.test.ts went 7 failed / 1 passed (8). Each red was the defect itself (agent_prompt listed; a get returned 'Error: Agent \"ask\" not found' as a result; description '(e.g. \"ask\"…'; capabilities.prompts {listChanged:true}). The passing case is the preservation pin (served body plus byte-stable miss). After the fix: pnpm --filter @objectstack/mcp exec vitest run gave 54 files, 652/652 (lock VERDICT command-exit 0), and pnpm --filter @objectstack/mcp typecheck gave VERDICT command-exit 0. Forced test edits, both named in the PR body: mcp-stdio-tools.test.ts #8034 bridged-server double (list returns one agent), and mcp-server-runtime.test.ts 'survives a metadata service that cannot list skills' (keeps the double's agents). Ablations via scripts/ablation-replace.mjs (source import, no dist): A1 withholding disabled gave 4 red; A2 fixed 'ask/build' description gave 2 red; A3 degraded branch deleted gave 1 red; A4 thrown read mapped to none gave 1 red. Each restored; blob 09f63b589939 matches HEAD and git diff HEAD is empty.", "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack derived 59 at 9126fc31. On the first sweep 56 exited 0 and 3 exited 3 (prerequisite). check-plugin-teardown-shape --self-test exited 0 after fetching pinned commit 621a4876. check:dual-build-cjs-loads and check:lean-entry-closure each exited 0 after a full pnpm build (117/117, VERDICT command-exit 0). check:dts-closure rerun exited 0. --ran: 59 derived, 59 run, 0 NOT-MEASURED, 0 UNRUN. Extra: check:startup-registry-verdict exited 0. pnpm lint (whole repo) printed no diagnostic, exit code not captured (see deviations); eslint on the 4 changed .ts files exited 0. PR check-runs: in_progress at report time.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "line_budget": "+360 / -27 across 6 files (387 changed lines, under the 3000 human-merge threshold)", "files_changed": [ ".changeset/28940-mcp-agent-prompt-advertised.md", "packages/mcp/README.md", "packages/mcp/src/mcp-server-runtime.ts", "packages/mcp/src/mcp-server-runtime.agent-prompt-advertised.test.ts", "packages/mcp/src/mcp-stdio-tools.test.ts", "packages/mcp/src/__tests__/mcp-server-runtime.test.ts" ], "deviations": [ "Ablation runs (single-file vitest, about 6s each) ran outside os-verify-lock.", "A first full build used OS_SKIP_DTS=1 and failed in @object-ui/auth (TS7016: no spec .d.ts). That was my wrong invocation, not main. It was redone without the flag (117/117) before the dist-reading gates were rerun.", "The first gate sweep overlapped that failed build on the shared box. The only gates that read dist were the two exit-3 ones, and both were rerun on the clean build.", "pnpm lint ran under nohup without capturing its exit code. Its log holds only the script banner (no diagnostic), and the changed files linted alone exited 0.", "The harness asked for a PR assignee and reviewer via MCP writes. That was not done: the standard order forbids MCP writes and os-dev forbids PR assignees. The seat may set them." ], "mcp_calls": "6 — reads only: issue_read get #28940, issue_read get_comments #28940 (x2), issue_read get #6055, issue_read get #14461, pull_request_read get #29201", "api_writes": "2 — relay pr_create (objectstack-ai/objectstack#29201, 8928 bytes sent = stored); this os-dev-report comment via post-stamped.mjs", "open_questions": [ { "question": "The agent roster is a snapshot taken at the MCP plugin's start(), the same moment as the skill snapshot. A host whose agent provider registers after that point in the same boot would leave agent_prompt withheld on stdio until restart. No open package registers an agent, and whether cloud registers its platform agents later than start() cannot be measured from this repo. Keep the snapshot, or add a late re-check?", "options": [ "A keep the bridge-time snapshot (as landed): one read, the same shape and lifetime as the skill snapshot; check:startup-registry-verdict is green", "B also re-check at kernel:bootstrapped and register agent_prompt late if agents appeared. This only works when the prompts capability already exists (some skill prompt), because the SDK refuses new capabilities after the transport attaches, so it would also need a warn for the no-skill case" ], "recommendation": "A, because no producer in this repo can contradict it, stdio is a local-host surface, and B adds a second registration path for a case nobody has measured; revisit if a cloud stdio host reports a missing agent_prompt" } ], "out_of_scope_findings": [ "class: none (pre-existing, not in acceptance) · on a boot WITH agents, stdio lists agent_prompt while HTTP /api/v1/mcp never serves it · carrier: none · noted in the PR's Acceptance notes, not filed" ] }Stamped 2026-11-02T09:16Z.
Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67
ACCEPT → PR #29201 comment 6573467333 (head
9126fc31). Landing once CI is green.objectstack-fleet commentedon Nov 2, 2026
domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67
Landing record · #28940 · PR #29201
domain:serverseat 3 ·session_01ADHkmQJdgarUjPLNgFBY67· 2026-11-02T10:41Zgit ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-29201-*'git merge-base --is-ancestor 31670f5729 origin/maingit grep -n "function readAgentRoster" origin/main -- packages/mcp/src/mcp-server-runtime.ts31670f57(2026-11-02T10:40Z). Over stdio,agent_promptis listed only when the boot registered at least one agent; with agents its argument example names the boot's real agents, and the mcp-server-runtime:443 把 metadata outage 答成 'Agent "X" not found' —— fail-closed 但误述,#5840 定性后的 cli 侧跟进 #6055 miss answer is unchanged.6573467333(route W,Clause-②: no, no contract review owed).Fixes #28940closed this card on merge.pm:dispatchedand the assignee removed in the same round.