Skip to content

Serve Glean skills over the MCP skills extension - #47

Open
aditya-scio wants to merge 1 commit into
mainfrom
feat/mcp-skills-extension
Open

Serve Glean skills over the MCP skills extension#47
aditya-scio wants to merge 1 commit into
mainfrom
feat/mcp-skills-extension

Conversation

@aditya-scio

Copy link
Copy Markdown

Implements OpenAI's Import skills from the MCP server flow, so hosts that import skills from the MCP server (ChatGPT plugins) pick up the skills the signed-in user has in Glean instead of only the one skill packaged under plugins/glean/skills/.

Skills come from the experimental Platform Skills API: GET /api/skills for metadata (cursor-paginated), GET /api/skills/{id}/content for the bundle — same origin and bearer token setup already captured, with X-Glean-Include-Experimental: true.

Surface

capabilities.extensions["io.modelcontextprotocol/skills"] is advertised at initialize, alongside resources (required to register resources/read).

Method Behavior
skills/list One page (10 skills); cursor maps to the Platform API cursor. Each entry: skill://glean/<name>/SKILL.md uri, full parsed SKILL.md frontmatter, every bundle file with a sha256: digest.
skills/get The catalog entry for one SKILL.md uri.
resources/read Bytes for any listed uri — text for UTF-8, blob otherwise. Served from an in-process cache, with a bounded crawl as fallback when the host reads a uri this process never listed.
resources/list Only what was already listed, so host startup never triggers bundle downloads.

Unconfigured or signed-out sessions serve an empty catalog; setup remains the only path that drives OAuth. Non-ENABLED, oversized (spec import limits: 256 KiB SKILL.md, 1 MiB/file, 5 MiB/skill, 100 files) and duplicate-named skills are skipped and logged to glean-server.log.

Changes

  • src/skills-catalog.ts — catalog build, caching, and the three handlers
  • src/zip.ts — minimal central-directory ZIP reader (stored + deflate), so bundles need no new dependency
  • src/index.ts — capabilities + registration
  • zod promoted to a direct dependency, imported as zod/v4 to match the SDK's entrypoint (bundle grows ~25 KB, not ~400 KB)
  • README section

Verification

  • npm run typecheck clean; npm test 201 passing (12 new in tests/skills-catalog.test.ts, covering the zip reader, bundle normalization, digests, cursor passthrough, auth headers, skip/crawl paths)
  • dist rebuilt and in sync
  • End-to-end run of the built server over stdio against a fake Platform API: skills/listskills/getresources/read, wrapper directory stripped, advertised digests matching the served bytes

Notes

  • The Platform Skills API is experimental; response shape changes would need a matching update here.
  • Not implemented: skills list-changed notifications, zip64/CRC verification.

🤖 Generated with Claude Code

Advertise the draft SEP-2640 skills extension
(`io.modelcontextprotocol/skills`) so hosts that import skills from the MCP
server — ChatGPT plugins — pick up the skills the signed-in user has in Glean,
instead of only the one skill packaged in the plugin directory.

- skills/list pages Glean's experimental Platform Skills API
  (GET /api/skills, cursor-paginated) and, for each ENABLED skill, downloads
  its bundle (GET /api/skills/{id}/content) to emit a catalog entry: a
  skill://glean/<name>/SKILL.md uri, the full parsed SKILL.md frontmatter, and
  every bundle file with a sha256 digest.
- skills/get returns one entry; resources/read serves the bytes (text for
  UTF-8, blob otherwise) from an in-process cache, falling back to a bounded
  crawl when the host reads a uri this process never listed.
- resources/list only reports what was already listed, so host startup never
  triggers bundle downloads.
- src/zip.ts: minimal central-directory ZIP reader (stored + deflate) so
  bundles need no new dependency.

Auth and origin reuse the token setup already captured; unconfigured or
signed-out sessions serve an empty catalog.
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