uk-design-systems-mcp-server
v0.1.0
Published
MCP server exposing the GOV.UK, NHS and Ministry of Justice design system components, examples and patterns. Offline, version-pinned, no external calls.
Maintainers
Readme
UK Design Systems MCP server
An MCP server that gives AI assistants accurate, first-hand knowledge of the UK government design systems — so they emit correct macros and real markup instead of hallucinating component props, guessing option names, or citing docs that don't exist.
It covers three design systems, ingested directly from their pinned frontend packages:
| System | Package | Components |
| --- | --- | --- |
| GOV.UK (gds) | govuk-frontend | 37 |
| NHS (nhs) | nhsuk-frontend | 40 |
| Ministry of Justice (moj) | @ministryofjustice/frontend | 25 |
- 102 components across 3 systems, plus page-level patterns
- Nunjucks + React — Nunjucks/HTML for all three systems; authentic React JSX for GOV.UK and NHS (details)
- Offline — every response is served from a locally bundled, version-pinned dataset and HTML is rendered locally with Nunjucks. The server makes no network calls, which suits public-sector and data-residency requirements.
- Provenant — every tool and resource response includes the exact
package@versionit came from, so you never have to trust the docs over the running server. - Transport: stdio (local editor / assistant integration).
Install & configure
The server runs via npx, so there is nothing to clone or build for normal use. Add it to your MCP client's configuration:
{
"mcpServers": {
"uk-design-systems": {
"command": "npx",
"args": ["-y", "uk-design-systems-mcp-server"]
}
}
}- Claude Code: put the block above in your project's
.mcp.json(or runclaude mcp add). - Claude Desktop: add it under
mcpServersinclaude_desktop_config.json. - Any MCP client: use the same
command/args.
That's it — the first run downloads the package and starts the server over stdio.
Verify it works
npx -y @modelcontextprotocol/inspector npx -y uk-design-systems-mcp-serverTools
Every component tool accepts an optional system (gds | nhs | moj). If you reference a component id that exists in more than one system (e.g. button), the server asks you to pick one rather than guessing.
| Tool | What it does |
| --- | --- |
| gds_list_components | Enumerate components, optionally filtered by system. |
| gds_get_component | Full macro-option schema (with nested options), deprecations, "when not to use" guidance and example names for one component. |
| gds_get_example | A worked example: the options, the canonical Nunjucks call, and (GOV.UK/NHS) the pre-rendered HTML. |
| gds_render_component | Generate a Nunjucks macro call, live-rendered static HTML, or React JSX (framework: 'react') from an options object. |
| gds_search_components | Map a natural-language intent ("ask for a date of birth") to the right components and patterns. |
| gds_get_pattern | Page-level patterns: start pages, question pages, check-answers, confirmation, validation/errors, task lists. |
| gds_validate_usage | Sense-check a component choice against design-system guidance (e.g. select vs radios). |
Every data-returning tool supports response_format: "markdown" (default) or "json", and surfaces the XSS/html and WCAG 2.2 accessibility notes where relevant.
Resources
The dataset is also exposed as read-only, URI-addressable MCP resources (with listing and autocompletion), so clients can browse and cache data without a tool call:
| URI | Contents |
| --- | --- |
| ukds://components | Index of all components across all systems (JSON). |
| ukds://component/{system}/{name} | One component's full schema, guidance and examples (JSON). |
| ukds://patterns | Index of all page patterns (JSON). |
| ukds://pattern/{name} | One pattern's full detail (JSON). |
Example calls
Get a component's options (macro name resolves unambiguously):
{ "name": "gds_get_component", "arguments": { "name": "govukButton" } }Disambiguate a shared id with system:
{ "name": "gds_get_component", "arguments": { "name": "button", "system": "nhs" } }Render live HTML from options (works for GOV.UK, NHS and MOJ):
{
"name": "gds_render_component",
"arguments": {
"name": "button",
"system": "nhs",
"options": { "text": "Continue" },
"framework": "html"
}
}Find the right component for an intent:
{ "name": "gds_search_components", "arguments": { "query": "upload several files at once" } }Generate React JSX (GOV.UK / NHS):
{
"name": "gds_render_component",
"arguments": {
"name": "button",
"system": "gds",
"options": { "start": true, "children": "Start now" },
"framework": "react"
}
}→ import { Button } from 'govuk-react'; … <Button start>Start now</Button>
React (JSX) support
Alongside Nunjucks, gds_render_component with framework: 'react' emits JSX, and gds_get_component reports the React component, import and props. React data is sourced from real React libraries (not an invented mapping), so component and prop names are authentic:
| System | React library | Notes | Components with a binding |
| --- | --- | --- | --- |
| GOV.UK | govuk-react | The mature, most-used GOV.UK React port (styled-components). ~2 years old but the latest stable release. | 26 |
| NHS | nhsuk-react-components | Actively maintained; targets nhsuk-frontend 10.x (matches our pin). | 35 |
| MOJ | — none exists — | No canonical React port. | 0 (Nunjucks only) |
These are community ports with idiomatic React APIs (e.g. start/buttonColour props, children instead of text/html), so React props are not the same as the Nunjucks macro options — the server extracts them from each library's own TypeScript types and labels them best-effort. Every React response cites the library @version it came from, and components without a React equivalent (all MOJ, plus GOV.UK/NHS components the library doesn't cover) return a clear "no React binding — use Nunjucks" message rather than inventing JSX. The React libraries are ingest-time devDependencies only; the running server stays React-free.
Fidelity note:
govuk-reactis a styled-components reimplementation, so its rendered markup differs fromgovuk-frontend's and it lags the current version — but it is the most widely used, stable GOV.UK React library. If you need markup identical to the Nunjucks output, useframework: 'nunjucks' | 'html'.
Local development
git clone https://github.com/IgnatG/govuk-design-system-mcp-server.git && cd uk-design-systems-mcp-server
npm install
npm run build # ingest the frontends, compile TS, copy data into dist/
npm test # build + end-to-end smoke test across all three systems
npm run typecheck # tsc --noEmitUseful scripts:
npm run inspector— open the MCP Inspector against the built server.npm run dev— run from source with watch mode (tsx).
Internal imports use the #app/* subpath-imports alias instead of ../../ relative paths (e.g. import { ok } from "#app/services/format.js"). It is defined once in package.json and resolves to ./dist/* at runtime, and to ./src/* for type-checking and npm run dev (the development condition). The # prefix — not @app/ — is required: Node treats @app/… as an npm package, whereas #… is the standard for package-private imports and needs no bundler or extra tooling.
To point an MCP client at your local checkout without publishing, link the binary (this avoids hard-coding any machine-specific path):
npm run build
npm linkthen configure the client with "command": "uk-design-systems-mcp-server".
Upgrading a pinned design-system version
- Bump
govuk-frontend,nhsuk-frontendand/or@ministryofjustice/frontendinpackage.jsonandnpm install. - Run
npm run build(re-ingests, recompiles, copies data) andnpm test. - Review
scripts/metadata.tsfor any new/removed components (ingest warns about drift).
Versioning & releases
This project uses Conventional Commits and
release-please. On every push to
main, release-please maintains a release PR that updates the version and
CHANGELOG.md; merging it tags a release and the workflow publishes to npm with
provenance.
feat:→ minor bump,fix:→ patch bump,feat!:/BREAKING CHANGE:→ major.- Publishing uses npm Trusted Publishing (OIDC) — no long-lived
NPM_TOKENsecret. Thepublishjob requestsid-token: writeand npm mints a short-lived credential for the release, with provenance attached automatically. - CI (
.github/workflows/ci.yml) type-checks, builds and runs the smoke test on Node 20, 22 and 24 for every push and PR.
Scope
v1 covers the base GOV.UK, NHS and MOJ component libraries in Nunjucks, plus React (JSX) output for GOV.UK and NHS (see React support). Page-level patterns are currently GOV.UK-focused. MOJ has no React output because no canonical React port exists.
License
AGPL-3.0-or-later. This project ingests and renders content from
govuk-frontend, nhsuk-frontend and @ministryofjustice/frontend, each MIT
licensed; see NOTICE for attributions. GOV.UK Design System documentation
is © Crown copyright under the Open Government Licence v3.0.
