Guardian Open Platform — search and retrieve full article text from The Guardian archive.
Search, browse, and retrieve full article text from The Guardian's journalism archive (1999–present) via MCP. STDIO or Streamable HTTP.
The Guardian's journalism archive (1999–present), via the Guardian Open Platform API. Search full text, browse by section or tag, and fetch complete untruncated articles from any MCP client. Runs as a stdio process or a local Streamable HTTP server.
| Tool | Description |
|---|---|
guardian_search | Full-text search across The Guardian's archive with optional section, tag, contributor, and date filters |
guardian_get_article | Fetch a single Guardian article by ID with full untruncated body text and metadata |
guardian_browse | Browse by section or tag, or discover available sections and tags, across four modes |
guardian_search toolAND/OR/NOT, quoted phrases) plus optional section, tag, contributor, and from_date/to_date (YYYY-MM-DD) filtersorder_by: relevance (default), newest, or oldest; paginated with page + page_size (1–50, default 10)truncated flag — fetch the complete text via guardian_get_articleunauthorized, no_results, invalid_date, api_error (retryable)guardian_get_article toolarticle_id — the path-slug id field returned by guardian_search or guardian_browsetruncated: true means the body still exceeded 2,000 words after the full fetchunauthorized, not_found, api_error (retryable)guardian_browse toolmode: section_latest (requires section_id), tag_latest (requires tag_id), list_sections, list_tagslist_tags takes optional query and tag_type (keyword, contributor, blog, series, tone, type, publication, newspaper-book, newspaper-book-section) — use tag_type=contributor to discover contributor IDspage + page_size (1–50, default 10) applies to every modeunauthorized, missing_section_id, missing_tag_id, section_not_found, tag_not_found, api_error (retryable)Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
Guardian-specific:
guardian_browse mode list_tags with tag_type=contributorlist_sections, list_tags) for filter discovery before searchingAgent-friendly output:
guardian_get_article for the resttotal / page / pages on every paginated response so callers can track result scopeguardian_search echoing the query and suggesting how to broadenAdd the following to your MCP client configuration file. Register for a free Guardian Open Platform API key at open-platform.theguardian.com/access.
{
"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_SESSION_MODE | HTTP session mode: stateless, stateful, or auto (resolves to stateful). The server declares stateless; an exported value overrides it. | stateless |
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 storagecreateApp() tools array in src/index.tsIssues 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.
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
npx -y @cyanheads/guardian-mcp-serverMerge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"io-github-cyanheads-guardian-mcp-server": {
"command": "npx",
"args": [
"-y",
"@cyanheads/guardian-mcp-server"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup referenceio.github.cyanheads/guardian-mcp-server works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.