Skip to content

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

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions