Skip to content

finding: GET /api/v1/meta/skill lists a skill twice after a runtime PUT, and the meta PUT never reaches the prompt bridge (two divergent skill-read paths) #7654

Description

@huangyiirene

Unconfirmed observation from the QA run — recorded for triage; the two mechanisms below were located but not independently root-caused, and the natural next step is to decide the single source of truth for skill rows (merge/dedup by name) that both the meta HTTP list and the MCP prompt bridge read from.

Symptom

Two related divergences in how skill metadata is read after a runtime store override:

  1. GET /api/v1/meta/skill returns the same skill twice after a runtime PUT — the store-override row and the package row are both listed, not merged/deduped by name.
  2. PUT /meta/skill/<name> {active:true} → 200 does not reach the prompt bridge. Flipping a skill active via the runtime metadata API does not make it appear over MCP prompts.
  • Expected: one row per skill name (override merged over package), and a runtime {active:true} PUT reflected in the prompt bridge.

Root cause (as located, unconfirmed)

The two surfaces read from different sources:

  • The MCP prompt bridge's listSkills calls metadataService.list('skill') — registry/package rows (packages/mcp/src/mcp-server-runtime.ts:753, listSkills: async () => (await metadataService.list('skill')) ?? []).
  • The HTTP meta list goes through protocol.getMetaItems — which merges store overrides.

So the store override (the {active:true} PUT) lands on the getMetaItems path but never on the metadataService.list path the bridge consumes; and on the HTTP list path the override and package rows are not deduped by name, producing the double listing. Both mechanisms are present on origin/main (mcp-server-runtime.ts:753; the dedup gap is in the getMetaItems merge in packages/metadata-protocol).

Note: the fix straddles packages/metadata-protocol (dedup/merge of skill rows) and packages/mcp (which source listSkills reads). Routed domain:metadata because the defining symptom — duplicate rows and un-merged overrides — lives in the metadata read/list layer; flag if the maintainer prefers the bridge-side lane.

Reproduction

  1. Boot a showcase with a packaged skill.
  2. PUT /api/v1/meta/skill/<name> with {active:true} → 200.
  3. GET /api/v1/meta/skill → the skill appears twice (override row + package row).
  4. Query the skill over MCP prompts → the {active:true} flip is not reflected.

Source

Extracted from the QA run #7627 (framework 92f26f7, console 6314e87f).

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions