Elicitation hooks not triggered with --input-format stream-json

Resolved 💬 6 comments Opened Mar 25, 2026 by meanmail Closed May 1, 2026

Description

MCP elicitation hooks (configured via --settings) do not fire when Claude Code is started with --input-format stream-json. The same hooks work correctly without --input-format stream-json.

Reproduction

  1. Create an MCP server that uses elicitInput() (from @modelcontextprotocol/sdk):
const result = await server.elicitInput({
  message: "Please provide your name",
  requestedSchema: {
    type: "object",
    properties: { name: { type: "string" } },
    required: ["name"],
  },
});
  1. Configure an Elicitation hook in a settings file:
{
  "hooks": {
    "Elicitation": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "cat > /tmp/elicit-proof.json && echo '{\"hookSpecificOutput\":{\"hookEventName\":\"Elicitation\",\"action\":\"accept\",\"content\":{\"name\":\"Test\"}}}'",
        "timeout": 60
      }]
    }]
  }
}
  1. Works — hook fires and elicitation succeeds:
claude -p "Call greet_user tool" \
  --output-format json \
  --dangerously-skip-permissions \
  --settings /tmp/settings.json
  1. Fails — hook never fires, MCP server gets timeout (MCP error -32001):
echo '{"type":"user_message","content":"Call greet_user tool"}' | \
claude -p \
  --output-format stream-json \
  --input-format stream-json \
  --verbose \
  --dangerously-skip-permissions \
  --settings /tmp/settings.json

Also fails with --permission-prompt-tool instead of --dangerously-skip-permissions.

Expected behavior

Elicitation hooks should work regardless of --input-format. The hook is the intended mechanism for handling elicitation in headless/automated scenarios (per the docs).

Environment

  • Claude Code version: 2.1.81
  • OS: macOS 15.4 (arm64)
  • MCP SDK: @modelcontextprotocol/sdk 1.27.1

View original on GitHub ↗

This issue has 6 comments on GitHub. Read the full discussion on GitHub ↗