Skip to content
PressRadar

Docs

Connect PressRadar via MCP.

PressRadar gives your AI assistant tools via the Model Context Protocol (MCP) to search your sources and maintain your own journalist data.

Overview

The MCP server is available at the /api/mcp path of this website (Streamable HTTP). Every request authenticates with your workspace API key as a bearer token.

Your assistant decides when to use which tool. PressRadar never sends messages on its own; for regular briefings, set up a schedule in your client.

Good to know

MCP does not push news into an inactive conversation. Your AI assistant only queries PressRadar when you (or an automation) send a request. Automatic briefings need a separately configured schedule, such as a scheduled task in your AI client, if it supports one.

Setup

  1. Sign up and complete the questionnaire.
  2. Choose up to 10 sources and wait until at least one is active.
  3. Create your API key in the workspace and copy it – it is shown only once.
  4. Add PressRadar as a server in the settings or MCP configuration of Claude or Codex, and store the key there.
  5. Ask your assistant, e.g. “Which relevant stories have appeared in my sources since yesterday?”

Client-specific instructions are available in your workspace after signing in.

Never paste your API key into an AI chat. Set it as an environment variable (PRESSRADAR_API_KEY) or in your client's dedicated settings field. If a key was shared by accident, revoke it and create a new one. Never paste your API key into a chat. It belongs in your client’s settings or configuration file. We only store a hash, and you can revoke the key at any time.

Example questions

  • Read-only“What stories relevant to my company appeared in the latest collection?”
  • Read-only“Which journalists covered this topic?”
  • Read-only“Show the sources and explain why this story is relevant.”
  • Writes to your workspace“Save this journalist to my list and note that she covers energy policy.”
  • Writes to your workspace“Log that I emailed this journalist today and sent our press release.”

Instructions per client

Researched against each vendor's official documentation. The status shows honestly what works directly and what needs a workaround.

Claude CodeSupportedNot tested end-to-end

Claude Code supports remote HTTP MCP servers with custom headers. The API key is sent as an Authorization header.

  1. Set your PressRadar API key as the environment variable PRESSRADAR_API_KEY in your shell (e.g. in ~/.zshrc or ~/.bashrc).
  2. Option A: run `claude mcp add`. Your shell inserts the key and Claude Code stores it in its local configuration.
  3. Option B (for shared projects): create a `.mcp.json` file in the project folder. It only contains `${PRESSRADAR_API_KEY}`; Claude Code expands it from your environment at startup, so the key never lands in the repository.
  4. Restart Claude Code and check the connection with `/mcp`.
Add via CLI
claude mcp add --transport http pressradar https://pressradar.website.cloud.brutal.ai/api/mcp \
  --header "Authorization: Bearer $PRESSRADAR_API_KEY"
.mcp.json in your project
{
  "mcpServers": {
    "pressradar": {
      "type": "http",
      "url": "https://pressradar.website.cloud.brutal.ai/api/mcp",
      "headers": {
        "Authorization": "Bearer ${PRESSRADAR_API_KEY}"
      }
    }
  }
}

Based on official docs as of 2026-11-06; not yet tested end-to-end.

Claude DesktopWorkaroundNot tested end-to-end

Claude Desktop's connector settings are the same as claude.ai's: a fixed API key only works there with the "Request headers" beta. As a workaround, you can add PressRadar as a local server through the open-source tool mcp-remote.

  1. If your organization has the "Request headers" beta, follow the Claude on the web instructions. The setting then applies in Claude Desktop too.
  2. Otherwise, install Node.js so that `npx` is available.
  3. Open Claude Desktop's `claude_desktop_config.json` file and add the entry below.
  4. Replace `$PRESSRADAR_API_KEY` with your key directly in that file. Claude Desktop does not read environment variables from your shell here.
  5. Keep `args` free of spaces around the colon (`Authorization:${AUTH_HEADER}`). According to mcp-remote, spaces in `args` are passed incorrectly on Claude Desktop for Windows.
  6. Fully restart Claude Desktop.
claude_desktop_config.json (via mcp-remote)
{
  "mcpServers": {
    "pressradar": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://pressradar.website.cloud.brutal.ai/api/mcp",
        "--header",
        "Authorization:${AUTH_HEADER}"
      ],
      "env": {
        "AUTH_HEADER": "Bearer $PRESSRADAR_API_KEY"
      }
    }
  }
}

Based on official docs as of 2026-11-06; not yet tested end-to-end.

Claude (claude.ai)Not directly yetNot tested end-to-end

Custom connectors in claude.ai support OAuth or servers without sign-in. Fixed API keys via "Request headers" are a beta for a limited set of organizations. PressRadar does not offer OAuth yet, so the connection only works if your organization has this beta.

  1. In claude.ai, open "Customize > Connectors" and click "Add custom connector". On Team and Enterprise plans, an Owner adds it under "Organization settings > Connectors" (Add > Custom > Web).
  2. Enter the address shown below as the MCP server URL.
  3. Under "Authentication", choose "No sign-in".
  4. Open "Request headers", pick the header name `authorization` and enter `Bearer ` followed by your key (with the space) as the value. Alternatively: header `x-api-key` with the bare key as the value.
  5. If there is no "Request headers" section, your organization does not have the beta yet. Use Claude Code or Claude Desktop with mcp-remote instead.
  6. Note: on Team and Enterprise plans every member shares the stored key. Headers cannot be edited after saving; remove the connector and add it again to change them.
MCP server URL
https://pressradar.website.cloud.brutal.ai/api/mcp
Request header (authorization)
authorization: Bearer $PRESSRADAR_API_KEY

Based on official docs as of 2026-11-06; not yet tested end-to-end.

OpenAI Codex CLISupportedNot tested end-to-end

Codex supports Streamable HTTP MCP servers and reads the bearer token from an environment variable. The key itself is never written to the config file.

  1. Set your PressRadar API key as the environment variable PRESSRADAR_API_KEY.
  2. Run `codex mcp add`. You pass only the variable's name, not its value.
  3. Alternatively, add the server directly to `~/.codex/config.toml` (or `.codex/config.toml` in a trusted project).
  4. Restart Codex. `codex mcp --help` shows the commands for listing and removing servers.
Add via CLI
codex mcp add pressradar --url https://pressradar.website.cloud.brutal.ai/api/mcp \
  --bearer-token-env-var PRESSRADAR_API_KEY
~/.codex/config.toml
# ~/.codex/config.toml
[mcp_servers.pressradar]
url = "https://pressradar.website.cloud.brutal.ai/api/mcp"
bearer_token_env_var = "PRESSRADAR_API_KEY"

Based on official docs as of 2026-11-06; not yet tested end-to-end.

OpenAI Codex (IDE extension)SupportedNot tested end-to-end

The Codex IDE extension shares its configuration with the Codex CLI (`~/.codex/config.toml`). A server you set up once is available there too.

  1. Set up PressRadar as for the Codex CLI, with `codex mcp add` or directly in `~/.codex/config.toml`.
  2. Make sure PRESSRADAR_API_KEY is set in the environment your editor is launched from.
  3. Reload the editor window or restart the extension.
~/.codex/config.toml
# ~/.codex/config.toml
[mcp_servers.pressradar]
url = "https://pressradar.website.cloud.brutal.ai/api/mcp"
bearer_token_env_var = "PRESSRADAR_API_KEY"

Based on official docs as of 2026-11-06; not yet tested end-to-end.

Tool reference

Parameter descriptions come straight from the server's validation schema.

News & sources

list_sourcesRead-only

List the publisher websites this workspace monitors, with collection health (last success, next run, failures, articles in the last 7 days, stale flag) and the plan's source limit.

No parameters.

Returns
sources[]
sourceId, publisherId, name, domain, status, lastSuccessAt, nextCollectAt, consecutiveFailures, lastRunStatus, articles7d, stale
limit / used
Source slots on the plan and how many are in use
Example
list_sources({})
→ {"sources":[{"name":"Handelsblatt","status":"active","lastSuccessAt":"2026-11-06T06:02:11Z","stale":false}],"limit":10,"used":4}

search_newsRead-only

Search stories (clusters of articles about the same event) from this workspace's sources, ranked by the workspace's relevance score, then recency. Returns the top article, outlets, authors, matched keywords, short relevance reasons and a labelled model summary. Paginate with nextCursor.

Parameters: search_news
ParametersTypeDescription
querystringWords to find in title, teaser or text (all must match; max 8 terms; "quoted phrase" allowed). Omit to list the most relevant stories.
sincestringOnly articles published/discovered at or after this time (ISO 8601, e.g. 2026-11-01 or 2026-11-01T08:00:00Z)
untilstringOnly articles published/discovered at or before this time (ISO 8601, e.g. 2026-11-01 or 2026-11-01T08:00:00Z)
sinceHoursintegerShortcut for since: only the last N hours (e.g. 6 for the latest collection, 24 for a day)
publisherIdsstring[]Limit to these sources (publisherId from list_sources)
minScorenumberMinimum relevance score 0..100 for this workspace
includeExcludedbooleandefault: falseAlso return articles that matched an exclusion rule
authorstringOnly articles with an author whose name contains this text
cursorstringnextCursor from the previous result, to get the next page
limitintegerdefault: 10Stories per page (1..25)
Returns
stories[]
storyId, title, score (0..100 or null), topArticle {url, title, outlet, publishedAt, teaser}, articleCount, outlets, authors, matchedKeywords, relevanceReasons, modelSummary
nextCursor
Pass as cursor for the next page; null when done
freshness
When the latest collection ran and when the next is scheduled
Example
search_news({"query":"Wasserstoff Förderung","sinceHours":24,"limit":5})
→ {"stories":[{"storyId":"cm…","title":"Bund stockt Wasserstoff-Förderung auf","score":87,"articleCount":4}],"nextCursor":null}

get_storyRead-only

Get one story with its articles (URL, outlet, dates, teaser, optional full text), authors merged with your own journalist notes and publicly evidenced contacts (with source URL), the workspace's relevance assessment, and an explicit list of missing data.

Parameters: get_story
ParametersTypeDescription
storyIdrequiredstringstoryId from search_news
includeTextbooleandefault: falseInclude the article full text (third-party content, up to 20,000 characters per article)
maxArticlesintegerdefault: 10How many articles of the story to return (1..20)
Returns
articles[]
url, title, outlet, publishedAt, teaser, text/truncated (with includeText), textSource, textStatus, authors[] with merged journalist, missing[]
relevance
score, reasons, matchedKeywords, method, modelSummary (labelled)
missing[]
Data not available, e.g. publishedAt, authors, text, contacts
Example
get_story({"storyId":"cm…","includeText":true,"maxArticles":3})
→ {"title":"…","articles":[{"outlet":"FAZ","textStatus":"full","textSource":"publisher","truncated":false}],"missing":["contacts"]}

get_freshnessRead-only

When the latest scheduled collection finished, when the next one is due (every 6 hours), and which sources are stale, partial or failing.

No parameters.

Returns
lastCollectionAt / nextScheduledAt
ISO timestamps
staleSources / partialSources / failedSources
Sources with problems and the reason
Example
get_freshness({})
→ {"lastCollectionAt":"2026-11-06T06:04:00Z","nextScheduledAt":"2026-11-06T12:00:00Z","staleSources":[]}

Journalists & your own data

search_journalistsRead-only

Find journalists by name, outlet or topic. Ranked by how many matching articles they wrote in your sources in the last 90 days. Your own records and notes take priority over public data.

Parameters: search_journalists
ParametersTypeDescription
querystringName (or part of it)
topicstringTopic words; ranks journalists by recent coverage (90 days) in your sources
outletstringOutlet name or domain
limitintegerdefault: 10Max results (1..25)
Returns
journalists[]
workspaceJournalistId, journalistId, name, outlet, role, notes, tags, doNotContact, contacts[] (origin workspace / public_source), matchingArticles90d
Example
search_journalists({"topic":"Batteriezellen","limit":5})
→ {"journalists":[{"name":"…","outlet":"Handelsblatt","matchingArticles90d":6}]}

get_journalistRead-only

One journalist: your own record (notes, tags, contacts, interactions) first, then publicly evidenced contacts with source URL, and their recent articles in your sources.

Parameters: get_journalist
ParametersTypeDescription
workspaceJournalistIdstringYour workspace's own record id
journalistIdstringGlobal journalist id (from get_story / search_journalists)
Returns
contacts[]
origin 'workspace' (yours, with contactId) first, then 'public_source' with sourceUrl/sourceType
recentArticles[] / interactions[]
Latest coverage and your logged interactions
Example
get_journalist({"journalistId":"cm…"})
→ {"name":"…","contacts":[{"origin":"public_source","kind":"email","sourceUrl":"https://…/autor/…"}]}

save_journalistWrites to your workspace

Create or update your workspace's own record for a journalist (private to your workspace). Link it to a known journalist with journalistId. Only the fields you pass are changed; notes and tags are replaced.

Parameters: save_journalist
ParametersTypeDescription
workspaceJournalistIdstringUpdate this existing workspace record
journalistIdstringGlobal journalist id to link (from get_story / search_journalists)
namestringFull name (required when creating without journalistId)
outletstringOutlet / publication
rolestringRole or beat, e.g. 'Wirtschaftsredakteurin, Energie'
notesstringYour private notes (replaces previous notes)
tagsstring[]Tags (replaces previous tags)
doNotContactbooleanMark as do-not-contact
Returns
created / journalist
Whether a record was created, and the merged record incl. workspaceJournalistId
Example
save_journalist({"journalistId":"cm…","role":"Energie-Ressort","notes":"Bevorzugt Exklusivdaten, nicht vor 10 Uhr anrufen","tags":["energie"]})
→ {"created":true,"journalist":{"workspaceJournalistId":"cm…"}}

add_journalist_contactWrites to your workspace

Add a contact detail to your workspace's journalist record (email, phone, social handle, …). Validated; stored privately.

Parameters: add_journalist_contact
ParametersTypeDescription
workspaceJournalistIdrequiredstringWorkspace record id from save_journalist
kindrequiredemail | phone | website | profile | x | linkedin | bluesky | mastodon | instagram | threads | otherContact type
valuerequiredstringEmail, phone, URL or handle
labelstringe.g. 'work', 'newsroom'
sourcestringWhere this contact came from (e.g. 'email signature', a URL)
Returns
contactId
Id for remove_journalist_contact
Example
add_journalist_contact({"workspaceJournalistId":"cm…","kind":"email","value":"name@example.org","source":"E-Mail-Signatur"})
→ {"contactId":"cm…","kind":"email"}

remove_journalist_contactWrites to your workspace

Remove one of your workspace's own contact entries. Public contacts cannot be removed here.

Parameters: remove_journalist_contact
ParametersTypeDescription
contactIdrequiredstringcontactId of a workspace contact (origin 'workspace' in get_journalist)
Returns
removed
true when deleted
Example
remove_journalist_contact({"contactId":"cm…"})
→ {"removed":true}

log_interactionWrites to your workspace

Record a pitch, email, call, meeting, coverage or note with a journalist in your workspace.

Parameters: log_interaction
ParametersTypeDescription
workspaceJournalistIdrequiredstringWorkspace record id from save_journalist
kindrequiredemail_sent | email_received | call | meeting | pitch | coverage | noteInteraction type
occurredAtstringWhen it happened; default now (ISO 8601, e.g. 2026-11-01 or 2026-11-01T08:00:00Z)
subjectstringShort subject
summarystringWhat happened / was agreed
articleIdstringRelated article (e.g. resulting coverage)
Returns
interactionId
Id of the logged entry
Example
log_interaction({"workspaceJournalistId":"cm…","kind":"pitch","subject":"Studie Q4","summary":"Interesse, Rückmeldung bis Freitag"})
→ {"interactionId":"cm…","kind":"pitch"}

request_journalist_enrichmentWrites to your workspace

Queue a background lookup of publicly listed contact details for a journalist (author pages). Returns 'queued' immediately; results appear in get_journalist after a later run. Limited to 20 per workspace per day.

Parameters: request_journalist_enrichment
ParametersTypeDescription
journalistIdrequiredstringGlobal journalist id (from get_story / search_journalists)
Returns
status
queued | already_queued, remainingToday
Example
request_journalist_enrichment({"journalistId":"cm…"})
→ {"status":"queued","remainingToday":19}