Skip to content

Request: Dual tool output -- content for LLM, raw for hooks #1414

@ljw1004

Description

@ljw1004

In Claude Code, the built-in tools all provide TWO forms of output:

  1. a set of content blocks, for consumption by subsequent LLM requests
  2. raw tool-specific JSON output, for consumption by hooks and display in the UI

Currently the MCP spec only allows for tools to return the first form content, a set of content-blocks. I think the MCP spec should be expanded to allow an optional rawContent: any, for consumption by hooks and UI.

Why?

First, when someone writes a tool, then they'd now be able to tailor the for-LLM content to be exactly the kind of content that LLMs like best to consume, while allowing hook-authors to consume their tool's output in the format best for the hook author.

Second, imagine if all of Claude Code's built-in tools could be moved into its MCP server, and all of Gemini CLI's built-in tools could be moved to its MCP server. (They currently can't because MCP specification isn't expressive enough: it lacks the raw json). That way, when someone writes an agent, they could freely chose what set of built-in tools to use!

I documented for each of Claude Code's built-in tools how the for-LLM-output of the tool differs from the for-hook-and-UI output of the tool: https://github.com/ljw1004/claude-log/blob/main/parse.py

  • For the Read tool
    • for-LLM-output is similar to the output of cat -n, i.e. numbered lines, with a at the end to warn it about malicious files
    • for-hook-output is nicely structured {filePath: str, content: str, numLines: int, startLine: int, totalLines: int}
  • For the Edit tool
    • for-LLM-output says "The file foo.py has been updated. Here's the result of running cat -n on a snippet of the edited file:" and then it shows line-numbered content of the changed lines plus surrounding lines
    • for-hook-output is nicely structured {originalFile: str, structuredPatch: list[{oldStart:int, oldLines:int, newStart: int, newLines: int, lines: list[str]}}
  • and similarly for the others

I've not submitted an MCP spec proposal before. I wanted to create this first as an issue to sound out what people think about it, before I go down full-blown spec proposal route.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    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