Skip to content

Wrap get_pending_status response as Claude Code hook decision JSON #215

@liplus-lin-lay

Description

@liplus-lin-lay

purpose

Claude Code の `type: "mcp_tool"` UserPromptSubmit hook 経由で `get_pending_status` を呼んだ際、戻り値が AI 文脈に注入されない事象を解消する。local bridge で戻り値を Claude Code の decision JSON shape に wrapping することで、docs literal の挙動に乗せる。

premise

Claude Code 公式 docs (https://code.claude.com/docs/en/hooks) の `type: "mcp_tool"` hook section literal:

The tool's text content is treated like command-hook stdout: if it parses as valid JSON output it is processed as a decision, otherwise it is shown as plain text.

UserPromptSubmit の decision JSON canonical shape:

{
  \"hookSpecificOutput\": {
    \"hookEventName\": \"UserPromptSubmit\",
    \"additionalContext\": \"<plain text>\"
  }
}

現状の `get_pending_status` は `{"pending_count": N, "latest_received_at": "...", "types": {...}}` という generic JSON を返すため、Claude Code 側で「JSON parse 成功 → decision として処理」 path に入るが decision schema にマッチせず silent discard される。

実機検証 (2026-04-25):

  • `.mcp.json` 経由 install + Claude Code 2.1.119 + LI_PLUS_WEBHOOK_DELIVERY=mcp_hook 構成で確認
  • `mcp_tool` hook resolver の `not connected` error 解消後も、UserPromptSubmit context に webhook 情報は前景化されない
  • pending event が 12件 stash されている状態で AI 側からは webhook 通知が見えない
  • bash hook (on-user-prompt.sh) の stdout は AI 文脈に正しく inject されており、injection 機能自体は動作している
  • 詳細経緯は liplus-language#1167

constraints

  • 戻り値 shape を変えると AI 手動呼び出し時も decision-shape JSON が返る。AI は JSON 構造を読めるので致命的問題ではないが、他 MCP client (Codex / Cursor / Continue.dev など) との互換性影響は本 issue 起案時点で実証していない可能性レベルの懸念である。
  • Local bridge (mcp-server/server/index.js) の `setRequestHandler(CallToolRequestSchema, ...)` で `name === "get_pending_status"` を special-case する形にすれば Cloudflare Worker 側変更は不要。
  • `decision: "block"` は付けない(prompt がブロックされる)。
  • `hookEventName` は docs canonical shape に従い `"UserPromptSubmit"` を入れる。
  • `additionalContext` の中身は plain text 自然文(pending_count + types + latest_received_at の要約、100文字程度)。

target files

  • `mcp-server/server/index.js` の `setRequestHandler(CallToolRequestSchema, ...)` 内 `name === "get_pending_status"` 分岐
  • 必要に応じて test 追加 (戻り値 shape の unit test)

関連

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestformingbody being rewritten toward canonical form

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions