Skip to content

fix(mcp): Stop read_skill serving YAML front matter to the agent - #9318

Open
Lagmator22 wants to merge 2 commits into
jaegertracing:mainfrom
Lagmator22:fix/skill-frontmatter
Open

fix(mcp): Stop read_skill serving YAML front matter to the agent#9318
Lagmator22 wants to merge 2 commits into
jaegertracing:mainfrom
Lagmator22:fix/skill-frontmatter

Conversation

@Lagmator22

Copy link
Copy Markdown

Which problem is this PR solving?

read_skill returns skill files verbatim, so the YAML front matter lands in the model's context along with the procedure. Measured on the embedded skills, that block is 26% of the built-in skill bytes and 30% for the two sub-skills.

None of it is instruction. license and metadata are provenance. name and description already did their job in the root catalog that routed the agent to the file. allowed-tools is declared but no Go file reads it, so dropping it from the payload changes no behaviour.

Description of the changes

  • read_skill strips a leading YAML front matter block before returning the content.
  • Files on disk are unchanged, so the metadata stays where humans and tooling read it.
  • A file with no front matter, or with an unterminated block, is served as-is rather than guessed at.

How was this change tested?

  • TestStripFrontMatter covers the block being removed, no block, an unterminated block, an empty body, a horizontal rule in the body, and a delimiter that is not at the start.
  • TestReadSkillHandler_StripsFrontMatter drives the real handler and asserts license and allowed-tools no longer reach the caller.
  • Both fail with the change backed out. go test ./cmd/jaeger/internal/extension/jaegerquery/... passes.

Checklist

read_skill returns skill files verbatim, so the YAML front matter lands
in the model's context along with the procedure. That block is 26% of the
built-in skill bytes, 30% for the two sub-skills, and none of it is
instruction. license and metadata are provenance, and name/description
already did their job in the root catalog that routed the agent here.

allowed-tools sits in the same block, but nothing in the package reads
it, so dropping it from the payload changes no behaviour.

Files on disk are unchanged, so the metadata stays where humans and
tooling read it. A file with no front matter, or with an unterminated
block, is served as-is.

Signed-off-by: Lagmator22 <ndgurman@gmail.com>
Copilot AI lite review requested due to automatic review settings August 13, 2026 18:07
@Lagmator22
Lagmator22 requested a review from a team as a code owner August 13, 2026 18:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@dosubot dosubot Bot added the go Pull requests that update go code label Aug 13, 2026
@yurishkuro

Copy link
Copy Markdown
Member

@SoumyaRaikwar thoughts?

@github-actions github-actions Bot added the waiting-for-author PR is waiting for author to respond to maintainer's comments label Aug 13, 2026
@SoumyaRaikwar

SoumyaRaikwar commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

@yurishkuro I'm doing some skill evaluation and hit a problemagents don't discover skills unless the prompt names one. Against unmodified main, driving a real ACP agent (Goose), read_skill was called in 0 of 20 runs when the prompt didn't name a skill. It went straight to the telemetry tools every time. The root SKILL.md can't route an agent that never opens it.

Didn't work: rewriting the root index as symptom triage (0/5), making INSTRUCTIONS.md skills-first (0/5), a generic "call this before analysing a trace, start with SKILL.md" trigger in the tool description (0/10). The instructions do reach the model, and it quoted them back verbatim, but it still ignored them.

What moved it: putting the skill names and what each is for into the read_skill tool description, so they're visible without a call. An agent picks a tool by matching its situation against the description, and "read a skill file" gives it nothing to match. A pointer to SKILL.md is still one hop away, which is the 0/10 above.

Two honest numbers. Hand-writing that list got 5/5, but the wording was imperative enough that the agent opened the skill before looking at the trace. That's compliance rather than judgement, and not the behaviour we want. Generating the list from each skill's front matter description got 2/5, and in those runs the agent investigated first, saw errors, then fetched the error skill. Right shape, not yet reliable.

Which is where front matter comes in: generate the catalog at startup from each skill's name/description instead of hard-coding it. One source of truth, nothing to keep in step with the root index, and it covers skills_dir, so an operator's skill becomes discoverable without hand-editing anything. No new tool and no protocol change, just the same 9 tools with one description generated instead of literal.

So on this PR: allowed-tools has no consumer and can go. name/description are worth keeping, since that's the routing signal, and it's the consumer that was missing when #9195 was closed. Compatible with stripping front matter from what read_skill returns: it becomes the source of the catalog rather than payload.

@yurishkuro

Copy link
Copy Markdown
Member

@SoumyaRaikwar did you try asking the agent why it did not try to read the skills? I thought about auto-generating the index from front matter as you describe, but I think it's curing a symptom, not the root cause.

Please take this discussion to a separate issue, this PR is about whether front-matter needs to be returned to the agent, and it does not seem like it's needed - front matter exists for discovery, not when already reading the full skill.

@Lagmator22

Copy link
Copy Markdown
Author

@yurishkuro Thanks. To confirm the scope, this actually only changes what read_skill returns. The files on disk keep their front matter, so it stays available as a source for any catalog or discovery work in a separate issue.

@github-actions github-actions Bot removed the waiting-for-author PR is waiting for author to respond to maintainer's comments label Aug 14, 2026
Copilot AI review requested due to automatic review settings August 14, 2026 06:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@SoumyaRaikwar

SoumyaRaikwar commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

@yurishkuro
Agreed, front matter doesn't need returning to the agent also I've moved the discovery discussion to #9336 .

// description the root catalog already used to route the agent here, so
// serving it again only spends context. A file with no block, or with an
// unterminated one, is returned unchanged rather than guessed at.
func stripFrontMatter(content string) string {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

didn't we already have code for parsing front matter? we need to reuse that and the code should return a struct with fields for front matter attributes and the skill content

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

go Pull requests that update go code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: read_skill serves YAML front matter to the agent, 26% of the skill payload

4 participants