Repository navigation
feat(mcp): answer with Markdown and compact typed data - #562
Merged
Merged
Conversation
Every MCP tool returned the public API answer twice: as pretty-printed JSON in content and again in structuredContent. A ten-row trending call cost about 8,700 tokens, much of it duplicate fields, empty values, and install commands on every row. Presenters in layers/mcp/shared/mcp-presenters.ts now shape each answer: Markdown a model can relay in content, and a compact copy in structuredContent that each tool declares as an outputSchema, so the MCP SDK checks it. Every Skill keeps its repository and its page link. The public API and the SDK are unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🔗 Linked issue
Related to #548
❓ Type of change
📚 Description
An MCP client puts every tool answer into the model's context. Each tool used to return the public API answer twice: pretty-printed JSON in
content, and the same object instructuredContent. The answers also carried fields a model has no use for:likes: 0, empty arrays, full ISO timestamps, long descriptions, whole post texts, and an install command on every list row.The new presenters in
layers/mcp/shared/mcp-presenters.tsshape each answer twice, for two readers:contentis Markdown a model can relay as it is. Each Skill is a linked name, itsowner/repository, its stars, a trimmed description, and its run command. Some clients read only this.structuredContentis a compact copy of the same facts. Each tool now declares it as anoutputSchema, so the MCP SDK checks every answer against it.Every Skill keeps its repository and its skilld.dev page (VISION principle 1). Run commands come before install commands.
get_skillstill returns the full SKILL.md, fenced so its own code blocks stay inside. A trending row still states why it is on the board, with one post's author, date, and link. The public API andskilld-sdkare unchanged, so the CLI sees no difference.Tokens per call on production answers recorded on 2026-10-07, counting
contentplusstructuredContent:search_skills(5)get_skilllist_tracks(14)get_track(10)list_trending(10)get_repository(9)submit_repository(indexed, 9)install_commandget_skillshrinks least because it keeps the full SKILL.md in both forms. The presenter tests run on those recorded answers, saved undertest/fixtures/mcp/.skilld-sdk 0.1.2 types the items of the track list and trending answers as
unknown, although its client parses them withtrackSummarySchemaandtrendingSkillSchema. The presenters take their types from those exported schemas.