Skip to content

fix(sdk): send no numeric skill resource annotation and a compact skills line in the instructions by default - #986

Merged
frontegg-david merged 2 commits into
release/1.10.xfrom
fix/06-client-safe-skills
Nov 2, 2026
Merged

frontegg-david merged 2 commits into
release/1.10.xfrom
fix/06-client-safe-skills

Conversation

@frontegg-david

@frontegg-david frontegg-david commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #985 (base fix/03-hook-order, the top of #980 → #981 → #983 → #984 → #985).

What and why

Proposal item 1.8: two skill defaults that break MCP clients. Both defaults change; how to get the old behaviour back
is under User-facing change.

Numeric annotations on every SKILL.md resource. Each skill://<skillPath>/SKILL.md resource in resources/list
carried annotations: { audience: ['assistant'], priority: 0.8 }, hard-coded in sep-2640.per-skill.ts, and nothing
turned it off. A widely used Rust MCP client (its JSON parser keeps arbitrary-precision numbers) fails the whole
resources/list with "Unexpected response type" when an annotation is a number, so users deleted priority in a hook.

  • New skillsConfig.resourceAnnotations: 'no-priority' | 'full' | 'off', default 'no-priority'.
  • 'no-priority' keeps audience: ['assistant'] and lastModified (file-backed skills) and sends no number.
  • 'full' brings back priority: 0.8. 'off' sends no annotations field, and skips resolving lastModified.
  • The per-skill resource is the only place SEP-2640 builds skill resource annotations; the templates and
    skill://index.json carry none.

The full skills catalog in the initialize instructions. skillsConfig.injectInstructions defaulted to 'append',
which adds - **name**: description for every skill the caller may see, capped only at 16,000 characters. Some clients
copy the server's instructions into every tool's description: one run held 104 copies, about 970K tokens of tool
documentation.

  • New injectInstructions: 'compact', now the default: the server instructions and channel hints, then one line with
    the number of skills the caller may see and where to read them:
    • This server has 3 skills: the `skill://index.json` resource lists each skill's `SKILL.md` URI.
    • with mcpResources: false: This server has 3 skills: find one with the `skills/search` request and load it with `skills/load`.
  • No line when the caller sees no skill (no skills, only HTTP-visible ones, or the skills:filter flow drops them all).
  • With a read-only skillsConfig.externalProvider the line names no number (This server has skills: …): the
    provider's skills are listed by skill://index.json but not held by the registry, so a count would be wrong. The
    line is sent even when the server declares no skill itself.
  • The count is per caller, from the same filtered list the catalog used (skill authorities and the hookable
    skills:filter flow), so a flag-disabled skill is not counted. It costs nothing extra: that filter already ran for the
    'append' default.
  • 'append', 'prepend' and 'replace' keep the full catalog, and 'off' is unchanged (it still sends the
    sep2640InInstructions hints). composeCallerInstructions stays the single composition point, so stdio, Streamable
    HTTP/SSE, in-memory, web-fetch and the 2026-07-28 server/discover all send the same line.
  • A ?mode=skills_only client gets the line too: it lists no tools, so nothing copies the line into tool descriptions,
    and skills are all such a client can use.

Validation. Both options are Zod enums in skillsConfigOptionsSchema. An unknown value stops @FrontMcp at boot with
InvalidDecoratorMetadataError for skillsConfig (it was a bare ZodError before, for any invalid skillsConfig
field), and the message names the field and the accepted values.

User-facing change

  • What changed: two defaults, one new option and one new option value.
    • skillsConfig.resourceAnnotations (new): 'no-priority' (default) | 'full' | 'off'.
    • skillsConfig.injectInstructions gains 'compact', which is now the default. The exported
      composeInitializeInstructions() and composeCallerInstructions() use it too when no policy is set.
    • An invalid skillsConfig makes @FrontMcp throw InvalidDecoratorMetadataError (@FrontMcp invalid metadata for "skillsConfig": …) instead of a ZodError.
  • Before → after:
    • SKILL.md resource annotations. Before: { audience: ['assistant'], priority: 0.8, lastModified? }. After:
      { audience: ['assistant'], lastModified? }. To get the old behaviour back: skillsConfig: { resourceAnnotations: 'full' }. A hook that deleted priority from resources/list is no longer needed.
    • initialize instructions. Before: the full catalog (Available skills (…): and a - **name**: description line
      per skill, up to 16 KB). After: one line, This server has N skills: the `skill://index.json` resource lists each skill's `SKILL.md` URI. (This server has skills: … with a read-only externalProvider). To get the old
      behaviour back: skillsConfig: { injectInstructions: 'append' }.
    • Servers that already set injectInstructions explicitly, including the deploy manifest's
      (manifest-to-config sets 'append'), see no change. sep2640InInstructions: true still adds its URI hints.
  • frontmcp.dev pages affected (if known): the skillsConfig reference (instructions injection, and a new section for
    SKILL.md resource annotations), the @FrontMcp instructions / skillsConfig option rows, the SEP-2640 skills
    resources page, and the production checklist line about the 16 KB catalog.
  • Skills catalog entries updated:
    • frontmcp-config/references/configure-skills-http.md: the compact mode (and its wording with a read-only
      externalProvider), both default changes with the way back, a new "SKILL.md Resource Annotations" section, the
      boot error, the decision matrix, and the off row (it keeps the sep2640InInstructions hints);
    • frontmcp-config/examples/configure-skills-http/inject-instructions.md and its skills-manifest.json entry;
    • frontmcp-development/references/decorators-guide.md (instructions? and skillsConfig? rows);
    • frontmcp-production-readiness/references/common-checklist.md (the 16 KB line now applies to the catalog modes);
    • frontmcp-deployment/references/protocol-versions.md (server/discover sends the skills line or catalog).

Tests

Red first: the unit specs failed before the change (9 failures, plus the boot-validation cases), and the new e2e
defaults failed against an SDK build of the parent branch (feature-flags-instructions: the compact line;
skills-resources: the compact line and no numeric annotation; skills-only-mode: the compact line), while the
'append' and 'full' restore paths passed there.

  • Unit (libs/sdk):
    • sep-2640.per-skill.spec.ts: the default sends audience with no priority; 'full' adds priority: 0.8; 'off'
      sends no annotations; lastModified stays under 'no-priority' and 'full'; registration adds lastModified
      next to the audience, brings back priority under 'full', and under 'off' neither annotates nor resolves
      lastModified.
    • skill-instructions.helper.spec.ts: 'compact' is the default; the exact line; singular for one skill; the
      skills/* variant with mcpResources: false; it follows the server instructions and channel hints; no line with no
      MCP-visible skill or no registry; per caller, it counts only what skills:filter keeps, and adds no line when the
      caller sees none; no count beside a read-only external provider, and a line on its own; the count kept beside a
      persistent one. Every policy still never ends in a separator.
    • skill-external-provider.spec.ts: on a real scope with a read-only provider, the default instructions name no
      count, with a registered skill and on a server that declares none.
    • transport.local.skill-hints.spec.ts: 'off' keeps the sep2640InInstructions hints.
    • skills-http.options.spec.ts: both defaults; every accepted value; an unknown injectInstructions or
      resourceAnnotations makes @FrontMcp throw InvalidDecoratorMetadataError naming the field.
    • Specs that check the full catalog now ask for 'append' explicitly: skill-filter.flow.spec.ts,
      skill-surface.spec.ts, skill-context.spec.ts, transport.local.skill-hints.spec.ts, and
      plugins/plugin-feature-flags/.../feature-flag.flows.spec.ts.
  • E2E:
    • demo-e2e-skills/e2e/skills-resources.e2e.spec.ts: every SKILL.md resource in resources/list has
      audience: ['assistant'] and no numeric annotation by default; with SKILLS_RESOURCE_ANNOTATIONS=full
      (resourceAnnotations: 'full') each has priority: 0.8; the default instructions are exactly the compact line,
      with the count matching skill://index.json.
    • demo-e2e-skills/e2e/skills-only-mode.e2e.spec.ts: a ?mode=skills_only client gets the compact line.
    • demo-e2e-feature-flags/e2e/feature-flags-instructions.e2e.spec.ts: by default the line counts 1 skill (the
      flag-disabled one is not counted); with SKILLS_INJECT_INSTRUCTIONS=append the full catalog lists the enabled skill
      and leaves the disabled one out (Feature flags: filter the skill catalog in initialize instructions per caller #603).
    • demo-e2e-dts-consumer/fixture/skills-must-compile.ts: injectInstructions: 'compact' and
      resourceAnnotations: 'full' compile on @FrontMcp; resourceAnnotations: 'audience' does not.
  • Ran:
    • npx nx run-many -t test build -p sdk skills: sdk 572 suites / 7401 tests, skills 3 suites / 249 tests, builds green.
    • npx nx run-many -t test build -p plugin-feature-flags plugin-skilled-openapi adapters: 239, 433 and 1011 tests,
      builds green.
    • npx nx test demo-e2e-skills (192 passed, 2 skipped as before), npx nx test demo-e2e-feature-flags (31 passed),
      npx nx test demo-e2e-dts-consumer (10 passed).
    • npx nx run-many -t lint on the touched projects: 0 errors. tsc --noEmit on libs/sdk/tsconfig.lib.json,
      libs/sdk/tsconfig.spec.json and both e2e apps: no diagnostics.
    • node scripts/fix-unused-imports.mjs origin/fix/03-hook-order, and prettier --check on every changed file.

Summary by CodeRabbit

  • New Features
    • Skill initialization instructions now default to a compact line with a skill count and discovery pointer, rather than the full catalog. Append, prepend, replace, and off modes remain available.
    • Added configurable annotations for skill resources: assistant audience only by default, optional priority details, or no annotations.
    • Invalid instruction or annotation settings now produce a clear startup error.
  • Documentation
    • Updated configuration guides and examples to explain the new defaults, options, and discovery behavior.

@frontegg-david
frontegg-david added this pull request to stack #982 November 2, 2026 03:43
@frontegg-david
frontegg-david marked this pull request as ready for review November 2, 2026 03:43
@frontegg-david

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

Run configuration
Commits

Reviewing files that changed from the base of the PR and between 1f9763a and fa583c0.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between e25da6e and ef2da70.

Files selected for processing: 29
  • apps/e2e/demo-e2e-dts-consumer/e2e/dts-consumer.e2e.spec.ts
  • apps/e2e/demo-e2e-dts-consumer/fixture/skills-must-compile.ts
  • apps/e2e/demo-e2e-feature-flags/e2e/feature-flags-instructions.e2e.spec.ts
  • apps/e2e/demo-e2e-feature-flags/src/main.ts
  • apps/e2e/demo-e2e-skills/e2e/skills-only-mode.e2e.spec.ts
  • apps/e2e/demo-e2e-skills/e2e/skills-resources.e2e.spec.ts
  • apps/e2e/demo-e2e-skills/src/main.ts
  • libs/sdk/src/common/decorators/front-mcp.decorator.ts
  • libs/sdk/src/common/types/options/__tests__/skills-http.options.spec.ts
  • libs/sdk/src/common/types/options/skills-http/index.ts
  • libs/sdk/src/common/types/options/skills-http/interfaces.ts
  • libs/sdk/src/common/types/options/skills-http/schema.ts
  • libs/sdk/src/skill/__tests__/skill-context.spec.ts
  • libs/sdk/src/skill/__tests__/skill-external-provider.spec.ts
  • libs/sdk/src/skill/__tests__/skill-filter.flow.spec.ts
  • libs/sdk/src/skill/__tests__/skill-instructions.helper.spec.ts
  • libs/sdk/src/skill/__tests__/skill-surface.spec.ts
  • libs/sdk/src/skill/sep-2640/__tests__/sep-2640.per-skill.spec.ts
  • libs/sdk/src/skill/sep-2640/sep-2640.per-skill.ts
  • libs/sdk/src/skill/skill-instructions.helper.ts
  • libs/sdk/src/skill/skill-scope.helper.ts
  • libs/sdk/src/transport/adapters/__tests__/transport.local.skill-hints.spec.ts
  • libs/skills/catalog/frontmcp-config/examples/configure-skills-http/inject-instructions.md
  • libs/skills/catalog/frontmcp-config/references/configure-skills-http.md
  • libs/skills/catalog/frontmcp-deployment/references/protocol-versions.md
  • libs/skills/catalog/frontmcp-development/references/decorators-guide.md
  • libs/skills/catalog/frontmcp-production-readiness/references/common-checklist.md
  • libs/skills/catalog/skills-manifest.json
  • plugins/plugin-feature-flags/src/__tests__/feature-flag.flows.spec.ts

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour.

Walkthrough

The skills HTTP configuration now defaults to compact initialize instructions and supports configurable annotations for per-skill SKILL.md resources. The SDK adds validation for these options. Unit tests, E2E tests, and documentation cover the configuration and behavior.

Changes: Skills HTTP configuration and behavior

Layer / File(s) Summary
Configuration options and validation
libs/sdk/src/common/types/options/skills-http/*, libs/sdk/src/common/decorators/front-mcp.decorator.ts, libs/sdk/src/common/types/options/__tests__/skills-http.options.spec.ts, apps/e2e/demo-e2e-dts-consumer/*, libs/skills/catalog/frontmcp-config/references/configure-skills-http.md, libs/skills/catalog/frontmcp-development/references/decorators-guide.md, libs/skills/catalog/skills-manifest.json
The options add compact instruction injection and resource annotation policies. Schema defaults are compact and no-priority. FrontMcp throws InvalidDecoratorMetadataError for invalid skillsConfig values. The type-consumer fixture covers supported and unsupported annotation options.
Compact instruction composition
libs/sdk/src/skill/skill-instructions.helper.ts, libs/sdk/src/skill/__tests__/*, libs/sdk/src/transport/adapters/__tests__/transport.local.skill-hints.spec.ts, plugins/plugin-feature-flags/src/__tests__/feature-flag.flows.spec.ts, apps/e2e/demo-e2e-feature-flags/*, apps/e2e/demo-e2e-skills/e2e/skills-only-mode.e2e.spec.ts, libs/skills/catalog/frontmcp-config/examples/configure-skills-http/inject-instructions.md, libs/skills/catalog/frontmcp-deployment/references/protocol-versions.md, libs/skills/catalog/frontmcp-production-readiness/references/common-checklist.md, libs/skills/catalog/skills-manifest.json
Compact mode adds a skill-count line and discovery pointer based on caller-visible skills. Tests cover resource and method pointers, external providers, filtering, and explicit append behavior. E2E coverage checks compact instructions and append mode.
Per-skill resource annotations
libs/sdk/src/skill/sep-2640/sep-2640.per-skill.ts, libs/sdk/src/skill/skill-scope.helper.ts, libs/sdk/src/skill/sep-2640/__tests__/sep-2640.per-skill.spec.ts, apps/e2e/demo-e2e-skills/src/main.ts, apps/e2e/demo-e2e-skills/e2e/skills-resources.e2e.spec.ts
Resource registration applies the selected annotation policy. Default annotations include assistant audience, full adds priority, and off omits annotations. Tests cover lastModified behavior and the E2E configuration exercises full mode.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MCPClient
  participant FrontMcp
  participant composeInitializeInstructions
  participant SkillRegistry
  MCPClient->>FrontMcp: Send initialize request
  FrontMcp->>composeInitializeInstructions: Compose caller instructions
  composeInitializeInstructions->>SkillRegistry: Select caller-visible skills
  SkillRegistry-->>composeInitializeInstructions: Return listed skills
  composeInitializeInstructions-->>FrontMcp: Return instructions with count and pointer
  FrontMcp-->>MCPClient: Return initialize response
Loading

Suggested reviewers: alexmercerpo

Merge Risk: Minimal · previous review ef2da

No merge-blocking issue is established by the available evidence.

Pre-merge checks: Passed 5
Check name Status Explanation
Title check Passed The title clearly identifies both primary changes: removing numeric skill resource annotations and making compact skill instructions the default. It is specific and related to the changeset.
Description check Passed The description includes the required What and why, User-facing change, and Tests sections. It explains the defaults, compatibility options, affected documentation, validation behavior, and test resul…
Docstring Coverage Passed Docstring coverage is 66.67% which is sufficient. The required threshold is 65.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentati…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description includes the required What and why, User-facing change, and Tests sections. It explains the defaults, compatibility options, affected documentation, validation behavior, and test results in sufficient detail.

Full details: Docstring Coverage

Explanation

Docstring coverage is 66.67% which is sufficient. The required threshold is 65.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 12 functions across 23 files. (6 skipped: 6 unsupported.)

Finishing Touches
Generate docstrings
  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

@frontegg-david
frontegg-david marked this pull request as draft November 2, 2026 03:51
@frontegg-david
frontegg-david marked this pull request as ready for review November 2, 2026 03:51
@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor
Action not completed

Already reviewed the last commit. Use @coderabbitai full review to rerun a review of the entire changeset.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions

github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Performance Test Results

Status: ✅ All tests passed

Summary

Project Tests Passed Warnings Failed Leaks
✅ demo-e2e-agents 4 4 0 0 0
✅ demo-e2e-cache 11 11 0 0 0
✅ demo-e2e-codecall 4 4 0 0 0
✅ demo-e2e-config 4 4 0 0 0
✅ demo-e2e-direct 3 3 0 0 0
✅ demo-e2e-elicitation 1 1 0 0 0
✅ demo-e2e-errors 4 4 0 0 0
✅ demo-e2e-hooks 3 3 0 0 0
✅ demo-e2e-multiapp 4 4 0 0 0
✅ demo-e2e-notifications 3 3 0 0 0
✅ demo-e2e-openapi 2 2 0 0 0
✅ demo-e2e-providers 4 4 0 0 0
✅ demo-e2e-public 4 4 0 0 0
✅ demo-e2e-redis 15 15 0 0 0
✅ demo-e2e-remember 4 4 0 0 0
✅ demo-e2e-remote 5 5 0 0 0
✅ demo-e2e-serverless 2 2 0 0 0
✅ demo-e2e-skills 15 15 0 0 0
✅ demo-e2e-standalone 2 2 0 0 0
✅ demo-e2e-transport-recreation 3 3 0 0 0
✅ demo-e2e-ui 4 4 0 0 0

Total: 101 tests across 21 projects

📊 View full report in workflow run


Generated at: 2026-11-02T06:45:32.589Z
Commit: a6d45abe

@frontegg-david
frontegg-david marked this pull request as draft November 2, 2026 04:24
@frontegg-david
frontegg-david marked this pull request as ready for review November 2, 2026 04:25
@frontegg-david
frontegg-david marked this pull request as draft November 2, 2026 04:52
@frontegg-david
frontegg-david marked this pull request as ready for review November 2, 2026 04:52
@frontegg-david
frontegg-david marked this pull request as draft November 2, 2026 05:24
@frontegg-david
frontegg-david marked this pull request as ready for review November 2, 2026 05:25
@frontegg-david
frontegg-david marked this pull request as draft November 2, 2026 05:58
@frontegg-david
frontegg-david marked this pull request as ready for review November 2, 2026 05:58
Base automatically changed from fix/03-hook-order to release/1.10.x November 2, 2026 06:31
…kills line by default

Each SKILL.md resource in resources/list carried priority: 0.8, and some
clients fail the whole list on a numeric annotation. The new
skillsConfig.resourceAnnotations ('no-priority' by default, 'full', 'off')
keeps audience and lastModified and drops priority unless asked for.

The initialize instructions listed every skill's name and description, and
some clients copy them into each tool's description. The new default
injectInstructions: 'compact' sends one line with the skill count the
caller may see and where to read the skills; 'append', 'prepend' and
'replace' keep the full catalog.

An unknown value for either option, or any invalid skillsConfig, makes
@FrontMcp throw InvalidDecoratorMetadataError at boot.
…ternal provider serves skills

A read-only skillsConfig.externalProvider serves skills that skill://index.json
lists but the registry does not hold, so the compact line undercounted them, and
sent no line at all when every skill came from the provider. It now reads
"This server has skills: ..." in that case.

The catalog no longer says 'off' adds nothing about skills (the
sep2640InInstructions hints are still sent), and protocol-versions names the
skills line for server/discover.
@frontegg-david
frontegg-david force-pushed the fix/06-client-safe-skills branch from 1f9763a to fa583c0 Compare November 2, 2026 06:31
@frontegg-david
frontegg-david merged commit 63a71db into release/1.10.x Nov 2, 2026
44 checks passed
@frontegg-david
frontegg-david deleted the fix/06-client-safe-skills branch November 2, 2026 07:05
@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Cherry-pick Created

A cherry-pick PR to main has been automatically created.

Please review and merge if this change should also be in main.

If the cherry-pick is not needed, close the PR.

frontegg-david pushed a commit that referenced this pull request Nov 2, 2026
…a compact skills line in the instructions by default (#994)

Cherry-picked from #986 (release/1.10.x).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant