MCP server: One MCP server.

Guardian

@cyanheadsMCP server · External

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

Newsv0.2.0Apache-2.0TypeScript
Freeno charge per call

Runs on your machine from its package; the steps are below.

What it does

  1. Reads
  2. Writes
  3. High impact

At most: only reads or looks up information.

What it costs

Free

Odel charges nothing per call. The publisher may charge for its own service.

Runs locally over stdio

This server isn't hosted — your MCP client launches it from a package registry. Use one of the commands below, or drop the config into your client (e.g. Claude Desktop).

npm@cyanheads/guardian-mcp-serverv0.2.0

Run

npx -y @cyanheads/guardian-mcp-server

MCP client config

{
  "mcpServers": {
    "guardian": {
      "command": "npx",
      "args": [
        "-y",
        "@cyanheads/guardian-mcp-server"
      ]
    }
  }
}
npm@cyanheads/guardian-mcp-serverv0.2.0

Run

npx -y @cyanheads/guardian-mcp-server

MCP client config

{
  "mcpServers": {
    "guardian": {
      "command": "npx",
      "args": [
        "-y",
        "@cyanheads/guardian-mcp-server"
      ]
    }
  }
}
README6 min read

@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 to today. Search full text, browse by section or tag, and fetch individual articles.

Tools

ToolDescription
guardian_search_articlesFull-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 body text and metadata
guardian_browse_contentBrowse by section or tag, or discover available sections and tags, across four modes

Capability reference

guardian_search_articles tool

  • Boolean query syntax (AND/OR/NOT, quoted phrases), optional section/tag/contributor and from_date/to_date (YYYY-MM-DD) filters; order_by: relevance (default), newest, or oldest; page + page_size (1–50, default 10)
  • Articles carry metadata, HTML-stripped body text and a truncated flag; results include total, page, pages, page_size, and order_by
  • Fails with no_results or invalid_date (dates must be real calendar dates)
  • tag accepts comma (AND), pipe | (OR), hyphen - (NOT), and parentheses, e.g. environment/climate-crisis|environment/flooding. Wrap an OR expression in parentheses when also passing contributor.

guardian_get_article tool

  • Required article_id: the path-slug id returned by guardian_search_articles or guardian_browse_content
  • Returns HTML-stripped body text, metadata, contributors, pillar/section classification, and truncated
  • Fails with not_found

guardian_browse_content tool

  • Four mode values: section_latest (requires section_id), tag_latest (requires tag_id), list_sections, list_tags; page + page_size (1–50, default 10) for articles and tags
  • list_tags filters by optional query and tag_type (keyword, contributor, blog, series, tone, type, publication, newspaper-book, newspaper-book-section); output carries mode, total, and the matching results/sections/tags array
  • Fails with missing_section_id, missing_tag_id, section_not_found, or tag_not_found. tag_id accepts the same boolean expressions as search's tag.

All three tools also fail with status-specific HTTP errors. Not retryable: unauthorized (401), access_denied (403), request_rejected (400), validation_failed (422), invalid_request, request_conflict, request_not_found, and api_unsupported (501). Retryable: api_timeout (408/425/504), rate_limited (429), and api_error (other 5xx). Each error carries a recovery hint.


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_content 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:

  • Search and article-returning browse modes cap previews at 2,000 words and set truncated; call guardian_get_article for the full text
  • 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

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.

json
{
  "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):

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

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

sh
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:
sh
git clone https://github.com/cyanheads/guardian-mcp-server.git
  1. Navigate into the directory:
sh
cd guardian-mcp-server
  1. Install dependencies:
sh
bun install
  1. Configure environment:
sh
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
LOG_TOOL_FAILURE_PAYLOADSLog failed tool arguments and results, redacted by key name and capped by LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES (default 16384). Secrets in free-form values remain visible.false
STORAGE_PROVIDER_TYPEStorage backend.in-memory
OTEL_ENABLEDEnable OpenTelemetry instrumentation (spans, metrics, completion logs).false
OTEL_EXPORTER_OTLP_ENDPOINTBase OTLP URL; traces use /v1/traces, metrics use /v1/metrics.—
OTEL_EXPORTER_OTLP_LOGS_ENDPOINTOpt-in OTLP log endpoint, used as-is.—

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


Running the server

Local development

  • Build and run:

    sh
    # One-time build
    bun run rebuild
    
    # Run the built server
    bun run start:stdio
    # or
    bun run start:http
    
  • Run checks and tests:

    sh
    bun run devcheck   # Lint, format, typecheck, security
    bun run test       # Vitest test suite
    bun run lint:mcp   # Validate MCP definitions against spec
    

Docker

sh
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_articles, guardian_get_article, guardian_browse_content.
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:

sh
bun run devcheck
bun run test

License

Apache-2.0 — see LICENSE for details.


Powered by The Guardian.

Similar modules

Browse News