From dfd30aecf12fc449a592a0c71b7af44cd2fec265 Mon Sep 17 00:00:00 2001 From: Matt Obee Date: Thu, 27 Aug 2026 12:03:56 +0100 Subject: [PATCH 1/2] Add missing MCP scenario patterns Keep the manually maintained catalogue in step with the eight scenario patterns published on primer.style. --- .changeset/update-mcp-scenario-patterns.md | 5 +++ packages/mcp/src/primer.ts | 20 ++++++++++++ packages/mcp/src/server.test.ts | 37 ++++++++++++++++++++++ packages/mcp/src/server.ts | 4 +-- 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 .changeset/update-mcp-scenario-patterns.md diff --git a/.changeset/update-mcp-scenario-patterns.md b/.changeset/update-mcp-scenario-patterns.md new file mode 100644 index 00000000000..e6d4868f36b --- /dev/null +++ b/.changeset/update-mcp-scenario-patterns.md @@ -0,0 +1,5 @@ +--- +'@primer/mcp': minor +--- + +MCP server: Add Create, Delegate, Edit and View scenario patterns to the `list_patterns` and `get_pattern` tools. diff --git a/packages/mcp/src/primer.ts b/packages/mcp/src/primer.ts index 6a1dfbb13a8..a34d09c9d7b 100644 --- a/packages/mcp/src/primer.ts +++ b/packages/mcp/src/primer.ts @@ -51,11 +51,26 @@ const patterns: Array = [ name: 'Copy', category: 'scenario', }, + { + id: 'create', + name: 'Create', + category: 'scenario', + }, + { + id: 'delegate', + name: 'Delegate', + category: 'scenario', + }, { id: 'delete', name: 'Delete', category: 'scenario', }, + { + id: 'edit', + name: 'Edit', + category: 'scenario', + }, { id: 'filter', name: 'Filter', @@ -66,6 +81,11 @@ const patterns: Array = [ name: 'Search', category: 'scenario', }, + { + id: 'view', + name: 'View', + category: 'scenario', + }, { id: 'data-visualization', name: 'Data Visualization', diff --git a/packages/mcp/src/server.test.ts b/packages/mcp/src/server.test.ts index a20e6a97429..2005946bbf4 100644 --- a/packages/mcp/src/server.test.ts +++ b/packages/mcp/src/server.test.ts @@ -72,6 +72,43 @@ describe('MCP server', () => { ) }) + it('lists every published scenario pattern', async () => { + const result = await client.callTool({name: 'list_patterns'}) + const scenarioPatterns = ['Copy', 'Create', 'Delegate', 'Delete', 'Edit', 'Filter', 'Search', 'View'] + + expect(result.content).toContainEqual( + expect.objectContaining({ + type: 'text', + text: expect.stringContaining( + `## Scenario patterns\n\n${scenarioPatterns.map(name => `- ${name}`).join('\n')}`, + ), + }), + ) + }) + + it.each([ + {name: 'Create', id: 'create'}, + {name: 'Delegate', id: 'delegate'}, + {name: 'Edit', id: 'edit'}, + {name: 'View', id: 'view'}, + ])('retrieves the $name scenario pattern from its published URL', async ({name, id}) => { + vi.mocked(fetch).mockResolvedValue(new Response(`

${name}

`)) + + const result = await client.callTool({ + name: 'get_pattern', + arguments: {name}, + }) + + expect(fetch).toHaveBeenCalledTimes(1) + expect(vi.mocked(fetch).mock.calls[0]?.[0].toString()).toBe(`https://primer.style/product/scenario-patterns/${id}`) + expect(result.content).toContainEqual( + expect.objectContaining({ + type: 'text', + text: expect.stringContaining(`Here are the guidelines for the \`${name}\` pattern for Primer:`), + }), + ) + }) + it('requires between 2 and 10 names', async () => { const tooFew = await callBatch(['Button']) const tooMany = await callBatch(Array.from({length: 11}, (_, index) => `Component${index}`)) diff --git a/packages/mcp/src/server.ts b/packages/mcp/src/server.ts index f1e031a27ed..7fb21e7a897 100644 --- a/packages/mcp/src/server.ts +++ b/packages/mcp/src/server.ts @@ -441,7 +441,7 @@ ${text}`, 'list_patterns', { description: - 'List all of the patterns available from Primer React. Scenario patterns describe specific user tasks (copy, delete, filter, search). Prefer a scenario pattern when one fits the task, and fall back to the more generic UI patterns otherwise.', + 'List all of the patterns available from Primer React. Scenario patterns describe specific user tasks. Prefer a scenario pattern when one fits the task, and fall back to the more generic UI patterns otherwise.', annotations: {readOnlyHint: true}, }, async () => { @@ -471,7 +471,7 @@ ${ui.join('\n')}`, 'get_pattern', { description: - 'Get a specific pattern by name. Scenario patterns describe specific user tasks (copy, delete, filter, search). Prefer a scenario pattern when one fits the task, and fall back to the more generic UI patterns otherwise.', + 'Get a specific pattern by name. Scenario patterns describe specific user tasks. Prefer a scenario pattern when one fits the task, and fall back to the more generic UI patterns otherwise.', inputSchema: z.object({ name: z.string().describe('The name of the pattern to retrieve'), }), From 416d3128bee9734a6d96867124ba3e0ac05b51bd Mon Sep 17 00:00:00 2001 From: Matt Obee Date: Thu, 27 Aug 2026 12:38:17 +0100 Subject: [PATCH 2/2] Add Customize MCP pattern --- .changeset/update-mcp-scenario-patterns.md | 2 +- packages/mcp/src/primer.ts | 5 +++++ packages/mcp/src/server.test.ts | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.changeset/update-mcp-scenario-patterns.md b/.changeset/update-mcp-scenario-patterns.md index e6d4868f36b..b5b3729e80f 100644 --- a/.changeset/update-mcp-scenario-patterns.md +++ b/.changeset/update-mcp-scenario-patterns.md @@ -2,4 +2,4 @@ '@primer/mcp': minor --- -MCP server: Add Create, Delegate, Edit and View scenario patterns to the `list_patterns` and `get_pattern` tools. +MCP server: Add Create, Customize, Delegate, Edit and View scenario patterns to the `list_patterns` and `get_pattern` tools. diff --git a/packages/mcp/src/primer.ts b/packages/mcp/src/primer.ts index a34d09c9d7b..55dd80cded6 100644 --- a/packages/mcp/src/primer.ts +++ b/packages/mcp/src/primer.ts @@ -56,6 +56,11 @@ const patterns: Array = [ name: 'Create', category: 'scenario', }, + { + id: 'customize', + name: 'Customize', + category: 'scenario', + }, { id: 'delegate', name: 'Delegate', diff --git a/packages/mcp/src/server.test.ts b/packages/mcp/src/server.test.ts index 2005946bbf4..0e47205d692 100644 --- a/packages/mcp/src/server.test.ts +++ b/packages/mcp/src/server.test.ts @@ -74,7 +74,7 @@ describe('MCP server', () => { it('lists every published scenario pattern', async () => { const result = await client.callTool({name: 'list_patterns'}) - const scenarioPatterns = ['Copy', 'Create', 'Delegate', 'Delete', 'Edit', 'Filter', 'Search', 'View'] + const scenarioPatterns = ['Copy', 'Create', 'Customize', 'Delegate', 'Delete', 'Edit', 'Filter', 'Search', 'View'] expect(result.content).toContainEqual( expect.objectContaining({ @@ -88,6 +88,7 @@ describe('MCP server', () => { it.each([ {name: 'Create', id: 'create'}, + {name: 'Customize', id: 'customize'}, {name: 'Delegate', id: 'delegate'}, {name: 'Edit', id: 'edit'}, {name: 'View', id: 'view'},