diff --git a/.changeset/gold-snakes-smash.md b/.changeset/gold-snakes-smash.md new file mode 100644 index 00000000000..ad0db50a420 --- /dev/null +++ b/.changeset/gold-snakes-smash.md @@ -0,0 +1,5 @@ +--- +'@primer/mcp': minor +--- + +Adds support for fetching docs via the `/llms.txt` endpoint per-component diff --git a/package-lock.json b/package-lock.json index a8504a0d680..5c18a285e11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -81,7 +81,7 @@ "react-dom": "^18.3.1" }, "devDependencies": { - "@primer/react": "38.10.0", + "@primer/react": "38.11.0", "@primer/styled-react": "1.0.3", "@types/react": "^18.3.11", "@types/react-dom": "^18.3.0", @@ -95,7 +95,7 @@ "name": "example-nextjs", "version": "0.0.0", "dependencies": { - "@primer/react": "38.10.0", + "@primer/react": "38.11.0", "@primer/styled-react": "1.0.3", "next": "^16.1.5", "react": "^19.2.0", @@ -138,7 +138,7 @@ "version": "0.0.0", "dependencies": { "@primer/octicons-react": "^19.21.0", - "@primer/react": "38.10.0", + "@primer/react": "38.11.0", "@primer/styled-react": "1.0.3", "clsx": "^2.1.1", "next": "^16.1.5", @@ -256,16 +256,11 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/cli/node_modules/convert-source-map": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/@babel/cli/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "ISC", "dependencies": { @@ -338,11 +333,6 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/node_modules/convert-source-map": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", "dev": true, @@ -11799,6 +11789,13 @@ "node": ">= 0.6" } }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, "node_modules/cookie": { "version": "0.7.2", "license": "MIT", @@ -27004,7 +27001,7 @@ }, "packages/react": { "name": "@primer/react", - "version": "38.10.0", + "version": "38.11.0", "license": "MIT", "dependencies": { "@github/mini-throttle": "^2.1.1", diff --git a/packages/mcp/src/primer.ts b/packages/mcp/src/primer.ts index 8b0039dd451..91689ff2057 100644 --- a/packages/mcp/src/primer.ts +++ b/packages/mcp/src/primer.ts @@ -21,10 +21,6 @@ function idToSlug(id: string): string { return 'dialog' } - if (id.startsWith('skeleton')) { - return 'skeleton-loaders' - } - return id.replaceAll('_', '-') } diff --git a/packages/mcp/src/server.ts b/packages/mcp/src/server.ts index c760f2fb58a..4d90cd9b034 100644 --- a/packages/mcp/src/server.ts +++ b/packages/mcp/src/server.ts @@ -111,12 +111,27 @@ server.registerTool( }) if (!match) { return { - content: [ - { - type: 'text', - text: `There is no component named \`${name}\` in the @primer/react package. For a full list of components, use the \`list_components\` tool.`, - }, - ], + isError: true, + errorMessage: `There is no component named \`${name}\` in the @primer/react package. For a full list of components, use the \`list_components\` tool.`, + content: [], + } + } + + const llmsUrl = new URL(`/product/components/${match.slug}/llms.txt`, 'https://primer.style') + const llmsResponse = await fetch(llmsUrl) + if (llmsResponse.ok) { + try { + const llmsText = await llmsResponse.text() + return { + content: [ + { + type: 'text', + text: llmsText, + }, + ], + } + } catch (_: unknown) { + // If there's an error fetching or processing the llms.txt, we fall back to the regular documentation } } @@ -691,13 +706,7 @@ server.registerTool( inputSchema: { surroundingText: z.string().describe('Text surrounding the image, relevant to the image.'), alt: z.string().describe('The alt text of the image being evaluated'), - image: z - .union([ - z.instanceof(File).describe('The image src file being evaluated'), - z.url().describe('The URL of the image src being evaluated'), - z.string().describe('The file path of the image src being evaluated'), - ]) - .describe('The image file, file path, or URL being evaluated'), + image: z.string().describe('The image URL or file path being evaluated'), }, }, async ({surroundingText, alt, image}) => {