Back to Directory/Developer Tools

io.github.cyanheads/guardian-mcp-server

Guardian Open Platform — search and retrieve full article text from The Guardian archive.

Developer ToolsTypeScriptv0.1.4

@cyanheads/guardian-mcp-server

Search, browse, and retrieve full article text from The Guardian's journalism archive (1999–present) via MCP. STDIO or Streamable HTTP.

3 Tools

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework


Overview

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.

Tools

ToolDescription
guardian_searchFull-text search across The Guardian's archive with optional section, tag, contributor, and date filters
guardian_get_articleFetch a single Guardian article by ID with full untruncated body text and metadata
guardian_browseBrowse by section or tag, or discover available sections and tags, across four modes

Capability reference

guardian_search tool

  • Boolean query syntax (AND/OR/NOT, quoted phrases) plus optional section, tag, contributor, and from_date/to_date (YYYY-MM-DD) filters
  • Sort via order_by: relevance (default), newest, or oldest; paginated with page + page_size (1–50, default 10)
  • Body text is HTML-stripped and truncated at 2,000 words with a truncated flag — fetch the complete text via guardian_get_article
  • Typed error reasons: unauthorized, no_results, invalid_date, api_error (retryable)
  • Zero-result responses carry an enrichment notice echoing the query

guardian_get_article tool

  • Input: article_id — the path-slug id field returned by guardian_search or guardian_browse
  • Returns complete untruncated body text (HTML stripped), full metadata, contributor list, and pillar/section classification
  • truncated: true means the body still exceeded 2,000 words after the full fetch
  • Typed error reasons: unauthorized, not_found, api_error (retryable)

guardian_browse tool

  • Four modes via mode: section_latest (requires section_id), tag_latest (requires tag_id), list_sections, list_tags
  • list_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 IDs
  • Pagination via page + page_size (1–50, default 10) applies to every mode
  • Typed error reasons: unauthorized, missing_section_id, missing_tag_id, section_not_found, tag_not_found, api_error (retryable)

Features

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:

  • Wraps the Guardian Open Platform API with a free non-commercial developer key
  • Full body text extraction — HTML stripped, not just headlines or abstracts
  • Contributor ID discovery via guardian_browse mode list_tags with tag_type=contributor
  • Section and tag taxonomy browsing (list_sections, list_tags) for filter discovery before searching
  • Free tier: 5,000 requests/day, 12 calls/second — the server applies no additional throttling

Agent-friendly output:

  • Truncation flags on every article response — signal to call guardian_get_article for the rest
  • Typed error reasons across all three tools, each paired with a recovery hint
  • total / page / pages on every paginated response so callers can track result scope
  • Zero-result enrichment notice on guardian_search echoing the query and suggesting how to broaden

Getting started

Add 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

Prerequisites

Installation

  1. Clone the repository:
git clone https://github.com/cyanheads/guardian-mcp-server.git
  1. Navigate into the directory:
cd guardian-mcp-server
  1. Install dependencies:
bun install
  1. Configure environment:
cp .env.example .env
# Edit .env and set GUARDIAN_API_KEY

Configuration

VariableDescriptionDefault
GUARDIAN_API_KEYRequired. Free developer key from open-platform.theguardian.com/access.—
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_HTTP_PORTPort for HTTP server.3010
MCP_SESSION_MODEHTTP session mode: stateless, stateful, or auto (resolves to stateful). The server declares stateless; an exported value overrides it.stateless
MCP_AUTH_MODEAuth mode: none, jwt, or oauth.none
MCP_LOG_LEVELLog level (RFC 5424).info
LOGS_DIRDirectory for log files (Node.js only).<project-root>/logs
STORAGE_PROVIDER_TYPEStorage backend.in-memory
OTEL_ENABLEDEnable OpenTelemetry instrumentation (spans, metrics, completion logs).false

See .env.example for the full list of optional overrides.


Running the server

Local development

  • 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

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.


Project structure

DirectoryPurpose
src/index.tscreateApp() entry point — registers tools and initializes the Guardian service.
src/configServer-specific environment variable parsing (GUARDIAN_API_KEY).
src/mcp-server/toolsTool definitions (*.tool.ts): guardian_search, guardian_get_article, guardian_browse.
src/services/guardianGuardian Open Platform API client, normalization, and type definitions.
tests/Unit and integration tests.
docs/Design document and directory tree.

Development guide

See CLAUDE.md / AGENTS.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for request-scoped logging, ctx.state for tenant-scoped storage
  • Register new tools in the createApp() tools array in src/index.ts
  • Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields

Contributing

Issues are welcome. Run checks and tests before submitting:

bun run devcheck
bun run test

License

Apache-2.0 — see LICENSE for details.


Powered by The Guardian.

Installation

Source-derived launch command. Check the maintainer’s required arguments and credentials before running:

bash
npx -y @cyanheads/guardian-mcp-server

Set up in your AI client

Merge 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.

json
{
  "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 reference

Package

@cyanheads/guardian-mcp-servernpm

Compatible MCP Clients

io.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.

  • Claude Desktop~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.
  • Cursor~/.cursor/mcp.jsonRestart Cursor for changes to take effect.
  • VS Code.vscode/mcp.jsonReload VS Code window for changes to take effect.
  • Windsurf~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect.
  • Claude Code.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.

Learn More