Content
# UK Design Systems MCP server
An [MCP](https://modelcontextprotocol.io) 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`](https://github.com/alphagov/govuk-frontend) | 37 |
| **NHS** (`nhs`) | [`nhsuk-frontend`](https://github.com/nhsuk/nhsuk-frontend) | 40 |
| **Ministry of Justice** (`moj`) | [`@ministryofjustice/frontend`](https://github.com/ministryofjustice/moj-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](#react-jsx-support))
- **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@version` it 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:
```json
{
"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 run `claude mcp add`).
- **Claude Desktop:** add it under `mcpServers` in `claude_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
```bash
npx -y @modelcontextprotocol/inspector npx -y uk-design-systems-mcp-server
```
---
## Tools
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):
```json
{ "name": "gds_get_component", "arguments": { "name": "govukButton" } }
```
Disambiguate a shared id with `system`:
```json
{ "name": "gds_get_component", "arguments": { "name": "button", "system": "nhs" } }
```
Render live HTML from options (works for GOV.UK, NHS and MOJ):
```json
{
"name": "gds_render_component",
"arguments": {
"name": "button",
"system": "nhs",
"options": { "text": "Continue" },
"framework": "html"
}
}
```
Find the right component for an intent:
```json
{ "name": "gds_search_components", "arguments": { "query": "upload several files at once" } }
```
Generate React JSX (GOV.UK / NHS):
```json
{
"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`](https://github.com/govuk-react/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`](https://github.com/NHSDigital/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-react` is a styled-components reimplementation, so its rendered markup differs from `govuk-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, use `framework: 'nunjucks' | 'html'`.
---
## Local development
```bash
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 # unit tests + build + end-to-end smoke test
npm run typecheck # tsc --noEmit
```
Useful scripts:
- `npm run test:unit` — fast unit tests (`node:test`, run from source via `tsx`; no build needed).
- `npm run test:e2e` — build + end-to-end smoke test across all three systems.
- `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](https://nodejs.org/api/packages.html#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):
```bash
npm run build
npm link
```
then configure the client with `"command": "uk-design-systems-mcp-server"`.
### Upgrading a pinned design-system version
1. Bump `govuk-frontend`, `nhsuk-frontend` and/or `@ministryofjustice/frontend` in `package.json` and `npm install`.
2. Run `npm run build` (re-ingests, recompiles, copies data) and `npm test`.
3. Review `scripts/metadata.ts` for any new/removed components (ingest warns about drift).
---
## Versioning & releases
This project uses [Conventional Commits](https://www.conventionalcommits.org/) and
[release-please](https://github.com/googleapis/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](https://docs.npmjs.com/generating-provenance-statements).
- `feat:` → minor bump, `fix:` → patch bump, `feat!:`/`BREAKING CHANGE:` → major.
- Publishing uses npm [Trusted Publishing](https://docs.npmjs.com/trusted-publishers) (OIDC) — no long-lived `NPM_TOKEN` secret. The `publish` job requests `id-token: write` and npm mints a short-lived credential for the release, with provenance attached automatically.
- CI (`.github/workflows/ci.yml`) type-checks, runs unit tests, 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](#react-jsx-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](LICENSE). This project ingests and renders content from
`govuk-frontend`, `nhsuk-frontend` and `@ministryofjustice/frontend`, each MIT
licensed; see [NOTICE](NOTICE) for attributions. GOV.UK Design System documentation
is © Crown copyright under the Open Government Licence v3.0.
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
everything-claude-code
Complete Claude Code configuration collection - agents, skills, hooks,...
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
cc-switch
All-in-One Assistant for Claude Code, Codex & Gemini CLI across platforms.
servers
Model Context Protocol Servers
servers
Model Context Protocol Servers
Time
A Model Context Protocol server for time and timezone conversions.