Wraps The Guardian's Open Platform API to search and retrieve full article text from their journalism archive spanning 1999 to present. You get three tools: full-text search with section, tag, contributor, and date filters; single-article retrieval by path slug; and a browse mode that surfaces sections, tags, and latest content. Body text comes back HTML-stripped and truncated at 2,000 words with a flag telling you when to fetch the complete version. Needs a free Guardian API key from their developer program. Useful when you're building research tools, news aggregators, or anything that needs access to quality journalism with proper metadata and contributor attribution rather than scraping.
Public tool metadata for what this MCP can expose to an agent.
verify_recipeVerify a candidate recipe against a Guardian master recipe. Uses deterministic graph-based verification to check technique, temperature, timing, cooking medium, and required ingredients. Returns a formatted text report. In Oracle Mode (default), proprietary data is protected —...4 paramsVerify a candidate recipe against a Guardian master recipe. Uses deterministic graph-based verification to check technique, temperature, timing, cooking medium, and required ingredients. Returns a formatted text report. In Oracle Mode (default), proprietary data is protected —...
dishvaluedish_namestringcandidate_jsonvalueoriginal_promptvaluelist_dishesList all available dish slugs from the Guardian registry. Returns: Dictionary with canonical dish slugs and their aliases.1 paramsList all available dish slugs from the Guardian registry. Returns: Dictionary with canonical dish slugs and their aliases.
cuisine_filterstringSearch, browse, and retrieve full article text from The Guardian's journalism archive (1999–present) via MCP. STDIO or Streamable HTTP.
A free Guardian Open Platform API key is required. Register at https://open-platform.theguardian.com/access — the non-commercial developer tier is free. Set it as
GUARDIAN_API_KEYin your MCP client config or.envfile. The server will not start without it.Rate limits (free tier): 5,000 requests/day, 12 calls/second. The server applies no additional throttling — stay within these bounds.
Three tools for working with The Guardian's journalism archive:
| Tool | Description |
|---|---|
guardian_search | Full-text search across The Guardian's archive (1999–present) with optional section, tag, contributor, and date filters. Returns articles with full body text (HTML stripped, truncated at 2,000 words). |
guardian_get_article | Fetch a single Guardian article by its ID (path slug) with full body text and all metadata. Use after guardian_search to retrieve the complete untruncated text. |
guardian_browse | Browse The Guardian's content by section or tag, or discover available sections and tags. Four modes: section_latest, tag_latest, list_sections, list_tags. |
guardian_searchFull-text search with structured filters across the entire Guardian archive.
from_date, to_date)guardian_get_article for complete textrelevance (default), newest, or oldestpage + page_size (1–50 per page)guardian_get_articleFetch one article by its Guardian path-slug ID.
article_id from guardian_search results — the id field, e.g. "world/2024/mar/01/ukraine-war-latest"truncated: true in the response means the body still exceeded 2,000 words after fetchingguardian_browseBrowse and discover Guardian content — four modes in one tool.
section_latest: newest articles from a section (requires section_id)tag_latest: newest articles carrying a tag (requires tag_id)list_sections: returns all Guardian sections as a flat list — use to discover valid section_id valueslist_tags: searches the tag taxonomy with optional query and tag_type filter — use to discover contributor IDs (tag_type=contributor), keyword tags, series, and moreBuilt on @cyanheads/mcp-ts-core:
none, jwt, oauthin-memory, filesystem, Supabase, Cloudflare KV/R2/D1Guardian-specific:
guardian_browse mode list_tags + tag_type=contributorAgent-friendly output:
guardian_get_article for the restunauthorized, no_results, not_found, invalid_date, api_error) with recovery hints for each casetotal, page, and pages on all paginated responses so agents can communicate result scopeguardian_search — echoes the query and suggests how to broadenA
GUARDIAN_API_KEYis required. Register for the free non-commercial developer key at https://open-platform.theguardian.com/access.
Add the following to your MCP client configuration file:
{
"mcpServers": {
"guardian-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/guardian-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"GUARDIAN_API_KEY": "your-api-key"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"guardian-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/guardian-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"GUARDIAN_API_KEY": "your-api-key"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"guardian-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"-e", "GUARDIAN_API_KEY=your-api-key",
"ghcr.io/cyanheads/guardian-mcp-server:latest"
]
}
}
}
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 GUARDIAN_API_KEY=your-api-key bun run start:http
# Server listens at http://localhost:3010/mcp
git clone https://github.com/cyanheads/guardian-mcp-server.git
cd guardian-mcp-server
bun install
cp .env.example .env
# Edit .env and set GUARDIAN_API_KEY
| Variable | Description | Default |
|---|---|---|
GUARDIAN_API_KEY | Required. Free developer key from open-platform.theguardian.com/access. | — |
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | Port for HTTP server. | 3010 |
MCP_AUTH_MODE | Auth mode: none, jwt, or oauth. | none |
MCP_LOG_LEVEL | Log level (RFC 5424). | info |
LOGS_DIR | Directory for log files (Node.js only). | <project-root>/logs |
STORAGE_PROVIDER_TYPE | Storage backend. | in-memory |
OTEL_ENABLED | Enable OpenTelemetry instrumentation (spans, metrics, completion logs). | false |
See .env.example for the full list of optional overrides.
Build and run:
# One-time build
bun run rebuild
# Run the built server
bun run start:stdio
# or
bun run start:http
Run checks and tests:
bun run devcheck # Lint, format, typecheck, security
bun run test # Vitest test suite
bun run lint:mcp # Validate MCP definitions against spec
docker build -t guardian-mcp-server .
docker run --rm -e GUARDIAN_API_KEY=your-api-key -p 3010:3010 guardian-mcp-server
The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/guardian-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
| Directory | Purpose |
|---|---|
src/index.ts | createApp() entry point — registers tools and initializes the Guardian service. |
src/config | Server-specific environment variable parsing (GUARDIAN_API_KEY). |
src/mcp-server/tools | Tool definitions (*.tool.ts): guardian_search, guardian_get_article, guardian_browse. |
src/services/guardian | Guardian Open Platform API client, normalization, and type definitions. |
tests/ | Unit and integration tests. |
docs/ | Design document and directory tree. |
See CLAUDE.md / AGENTS.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for request-scoped logging, ctx.state for tenant-scoped storagesrc/mcp-server/tools/definitions/index.tsIssues and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
Apache-2.0 — see LICENSE for details.
Powered by The Guardian.
GUARDIAN_API_KEY*API key for The Guardian Open Platform (https://open-platform.theguardian.com/).
MCP_LOG_LEVELdefault: infoSets the minimum log level for output (e.g., 'debug', 'info', 'warn').
MCP_HTTP_HOSTdefault: 127.0.0.1The hostname for the HTTP server.
MCP_HTTP_PORTdefault: 3010The port to run the HTTP server on.
MCP_HTTP_ENDPOINT_PATHdefault: /mcpThe endpoint path for the MCP server.
MCP_AUTH_MODEdefault: noneAuthentication mode to use: 'none', 'jwt', or 'oauth'.
com.mcparmory/google-search
io.github.pipeworx-io/brave-search
marcopesani/mcp-server-serper
brave/brave-search-mcp-server
com.mcparmory/google-search-console
acamolese/google-search-console-mcp