{
  "markdown": "# Newscatcher CatchAll MCP Server\n\nMCP server for the NewsCatcher CatchAll Web Search API.\n\n## Quick Start — Use Our Hosted Server\n\nYou don't need to clone or run this repo to use the MCP — NewsCatcher runs a hosted instance:\n\n```\nhttps://catchall-mcp.newscatcherapi.com/mcp?apiKey=YOUR_CATCHALL_API_KEY\n```\n\nGet a CatchAll API key at [platform.newscatcherapi.com](https://platform.newscatcherapi.com/), then connect:\n\n```json\n{\n  \"mcpServers\": {\n    \"catchall\": {\n      \"type\": \"http\",\n      \"url\": \"https://catchall-mcp.newscatcherapi.com/mcp?apiKey=YOUR_CATCHALL_API_KEY\"\n    }\n  }\n}\n```\n\nOr via Claude Code CLI:\n\n```bash\nclaude mcp add --transport http catchall \"https://catchall-mcp.newscatcherapi.com/mcp?apiKey=YOUR_CATCHALL_API_KEY\"\n```\n\nFull integration docs: https://www.newscatcherapi.com/docs/web-search-api/integrations/mcp\n\nPrefer to run the server yourself (locally or self-hosted)? See [Running](#running) below.\n\n## Tool To Endpoint Mapping\n\n### Jobs\n\n| MCP Tool | Method | Endpoint |\n| --- | --- | --- |\n| `initialize_query` | `POST` | `/catchAll/initialize` |\n| `submit_query` | `POST` | `/catchAll/submit` |\n| `validate_query` | `POST` | `/catchAll/validate` |\n| `continue_job` | `POST` | `/catchAll/continue` |\n| `list_user_jobs` | `GET` | `/catchAll/jobs/user` |\n| `get_job_status` | `GET` | `/catchAll/status/{job_id}` |\n| `pull_results` | `GET` | `/catchAll/pull/{job_id}` |\n| `pull_job_csv` | `GET` | `/catchAll/pull/{job_id}/csv` |\n| `delete_job` | `DELETE` | `/catchAll/jobs/{job_id}` |\n\n> **Job listing filters:** `list_user_jobs` supports `search`, `ownership`, `project_id`,\n> and `mode` (`base` or `lite`) filters in addition to `page`/`page_size`.\n\n### Monitors\n\n| MCP Tool | Method | Endpoint |\n| --- | --- | --- |\n| `create_monitor` | `POST` | `/catchAll/monitors/create` |\n| `update_monitor` | `PATCH` | `/catchAll/monitors/{monitor_id}` |\n| `delete_monitor` | `DELETE` | `/catchAll/monitors/{monitor_id}` |\n| `list_monitors` | `GET` | `/catchAll/monitors/` |\n| `list_monitor_jobs` | `GET` | `/catchAll/monitors/{monitor_id}/jobs` |\n| `get_monitor_status` | `GET` | `/catchAll/monitors/{monitor_id}/status` |\n| `pull_monitor_results` | `GET` | `/catchAll/monitors/pull/{monitor_id}` |\n| `pull_monitor_csv` | `GET` | `/catchAll/monitors/pull/{monitor_id}/csv` |\n| `enable_monitor` | `POST` | `/catchAll/monitors/{monitor_id}/enable` |\n| `disable_monitor` | `POST` | `/catchAll/monitors/{monitor_id}/disable` |\n\n### Webhooks\n\n| MCP Tool | Method | Endpoint |\n| --- | --- | --- |\n| `list_webhooks` | `GET` | `/catchAll/webhooks` |\n| `create_webhook` | `POST` | `/catchAll/webhooks` |\n| `get_webhook` | `GET` | `/catchAll/webhooks/{webhook_id}` |\n| `update_webhook` | `PATCH` | `/catchAll/webhooks/{webhook_id}` |\n| `delete_webhook` | `DELETE` | `/catchAll/webhooks/{webhook_id}` |\n| `test_webhook` | `POST` | `/catchAll/webhooks/{webhook_id}/test` |\n| `assign_webhook_resource` | `POST` | `/catchAll/webhooks/{webhook_id}/resources` |\n| `list_webhook_resources` | `GET` | `/catchAll/webhooks/{webhook_id}/resources` |\n| `remove_webhook_resource` | `DELETE` | `/catchAll/webhooks/{webhook_id}/resources/{resource_type}/{resource_id}` |\n| `list_resource_webhooks` | `GET` | `/catchAll/resources/{resource_type}/{resource_id}/webhooks` |\n| `get_webhook_history` | `GET` | `/catchAll/webhook-history` |\n| `trigger_webhook` | `POST` | `/catchAll/webhook/trigger/{resource_type}/{resource_id}` |\n\n> **Webhook notes:** `create_webhook` accepts an optional `project_id` to attach the\n> webhook to a project on creation. `list_webhooks` also accepts an optional `project_id`\n> to filter to webhooks belonging to a specific project. `get_webhook_history` queries in\n> one of two modes — pass `resource_type` + `resource_id` for a job/monitor/monitor_group's\n> deliveries, or pass `webhook_id` for everything delivered through one webhook (exactly\n> one mode per call). Manual test deliveries (`test_webhook`) only appear in webhook mode\n> and are recorded with `resource_type: \"test\"`.\n\n### Projects\n\n| MCP Tool | Method | Endpoint |\n| --- | --- | --- |\n| `create_project` | `POST` | `/catchAll/projects/` |\n| `list_projects` | `GET` | `/catchAll/projects/` |\n| `get_project` | `GET` | `/catchAll/projects/{project_id}` |\n| `update_project` | `PATCH` | `/catchAll/projects/{project_id}` |\n| `delete_project` | `DELETE` | `/catchAll/projects/{project_id}` |\n| `get_project_overview` | `GET` | `/catchAll/projects/{project_id}/overview` |\n| `add_project_resources` | `POST` | `/catchAll/projects/{project_id}/resources` |\n| `list_project_resources` | `GET` | `/catchAll/projects/{project_id}/resources` |\n| `remove_project_resource` | `DELETE` | `/catchAll/projects/{project_id}/resources/{resource_type}/{resource_id}` |\n\n> **Project resources:** `resource_type` is one of `job`, `monitor`, `dataset`,\n> `monitor_group`, or `webhook`. A webhook can belong to several projects at once.\n> `delete_project` with `delete_resources=true` deletes the contained jobs, monitors,\n> datasets, and monitor groups, but webhooks are only detached — never deleted — and the\n> response's `deleted_resources` reports them under a `webhook_unlinked` count.\n\n### Datasets\n\n| MCP Tool | Method | Endpoint |\n| --- | --- | --- |\n| `create_dataset` | `POST` | `/catchAll/datasets/` |\n| `list_datasets` | `GET` | `/catchAll/datasets/` |\n| `get_dataset` | `GET` | `/catchAll/datasets/{dataset_id}` |\n| `update_dataset` | `PATCH` | `/catchAll/datasets/{dataset_id}` |\n| `delete_dataset` | `DELETE` | `/catchAll/datasets/{dataset_id}` |\n| `add_dataset_entities` | `POST` | `/catchAll/datasets/{dataset_id}/entities` |\n| `remove_dataset_entities` | `DELETE` | `/catchAll/datasets/{dataset_id}/entities` |\n| `list_dataset_entities` | `POST` | `/catchAll/datasets/{dataset_id}/entities/list` |\n| `get_dataset_status` | `GET` | `/catchAll/datasets/{dataset_id}/status` |\n| `create_dataset_from_csv` | `POST` | `/catchAll/datasets/upload` |\n| `append_csv_to_dataset` | `POST` | `/catchAll/datasets/{dataset_id}/upload` |\n\n> **CSV uploads (v1.6.1):** `create_dataset_from_csv` and `append_csv_to_dataset` take\n> the CSV **content** in the `file` parameter — raw CSV text or standard base64. They\n> never read a path from the server's filesystem, so they stay safe on a remote/hosted\n> MCP. Inline CSV content is capped at a hard 10 MB (after base64 decoding).\n> `create_dataset_from_csv` also accepts the new optional `project_id` field.\n\n### Entities\n\n| MCP Tool | Method | Endpoint |\n| --- | --- | --- |\n| `create_entity` | `POST` | `/catchAll/entities/` |\n| `list_entities` | `GET` | `/catchAll/entities/` |\n| `create_entities_batch` | `POST` | `/catchAll/entities/batch` |\n| `get_entity` | `GET` | `/catchAll/entities/{entity_id}` |\n| `update_entity` | `PATCH` | `/catchAll/entities/{entity_id}` |\n| `delete_entity` | `DELETE` | `/catchAll/entities/{entity_id}` |\n\n> **`external_entity_id` (v1.6.3):** `create_entity` and `update_entity` accept an optional\n> `external_entity_id` string — a customer-supplied identifier that links the entity to a\n> record in an external system. **`project_id` (v1.8.0):** `list_entities` accepts an\n> optional `project_id` to filter to entities belonging to a specific project.\n\n### Source Groups\n\n| MCP Tool | Method | Endpoint |\n| --- | --- | --- |\n| `list_source_groups` | `GET` | `/catchAll/source-groups` |\n\n> **Source groups (v1.8.0):** named, reusable domain allowlists (public groups plus any\n> organization-visibility groups your organization can access). `list_source_groups`\n> returns each group's `slug`, `name`, and `description`. The direct API's `POST /catchAll/submit`\n> now accepts a `source_groups` field of slugs to scope fetching to a domain allowlist;\n> `submit_query` does not yet expose this parameter — use the direct API for that until\n> a future release adds it here.\n\n### User & Meta\n\n| MCP Tool | Method | Endpoint |\n| --- | --- | --- |\n| `get_user_limits` | `POST` | `/catchAll/user/limits` |\n| `check_health` | `GET` | `/health` |\n| `get_version` | `GET` | `/version` |\n\n## Authentication\n\nAPI key precedence (highest to lowest):\n\n1. `api_key` tool parameter\n2. `x-api-key` request header\n3. `Authorization: Bearer <key>` request header\n4. URL query parameter `?apiKey=...`\n5. `CATCHALL_API_KEY` environment variable\n\n`check_health` and `get_version` do not require API key auth.\n\n### Hosted deployment (FastMCP Gateway)\n\nWhen deployed via fastmcp.app, a stateless gateway sits in front of the server. The gateway\nforwards HTTP headers to the backend but **not** URL query parameters. Use the `x-api-key`\nheader or `CATCHALL_API_KEY` environment variable instead of `?apiKey=`.\n\n**Claude Code / Cursor:**\n\n```json\n{\n  \"mcpServers\": {\n    \"catchall\": {\n      \"type\": \"http\",\n      \"url\": \"https://YOUR-DEPLOYMENT.fastmcp.app/mcp\",\n      \"headers\": { \"x-api-key\": \"YOUR_API_KEY\" }\n    }\n  }\n}\n```\n\nOr via CLI:\n\n```bash\nclaude mcp add --transport http catchall \"https://YOUR-DEPLOYMENT.fastmcp.app/mcp\" \\\n  --header \"x-api-key: YOUR_API_KEY\"\n```\n\n**Direct server access** (no gateway): `?apiKey=YOUR_KEY` in the URL still works.\n\n## Core Workflow (Jobs)\n\n1. Optional: call `initialize_query` to preview validators/enrichments/date window.\n2. `initialize_query` is preview-only (it does not create a job) and suggestions are non-deterministic.\n3. Submit with `submit_query` (`query` required). You can send only `query`; omitted optional fields are auto-selected/generated.\n4. Optional fields are independent: provide any subset (for example, custom `validators` only), omitted ones are still auto-generated.\n5. `start_date`/`end_date` filter web page discovery dates, not event dates in extracted content.\n6. For event-time accuracy, use event-focused validators/enrichments and verify `event_date` in pulled results.\n7. Poll `get_job_status`: first check after ~1-2 minutes, then every 30-60 seconds, stop on `completed` or `failed`.\n8. Pull with `pull_results`; partial data appears during `enriching`.\n9. Paginate while `page < total_pages` to retrieve all available records.\n10. Use `continue_job` only to process more records (cost-affecting). It applies only to jobs originally submitted with `limit`.\n11. `continue_job.new_limit` is optional; if omitted, API defaults to your plan maximum.\n12. `page/page_size/total_pages` represent already-available records; use `progress_validated < candidate_records` to detect if more records may still appear.\n\n## Limit vs Page Size\n\n- `limit` (`submit_query`, `continue_job`) controls how many records are processed and therefore affects cost. If provided, must be >= 10. Omit to retrieve everything up to your plan's maximum.\n- `page_size` (`pull_results`, `list_user_jobs`) controls pagination only and does not affect processing cost.\n- `pull_results.page_size` default is `100`.\n- `page_size` range is `1..1000`.\n- `pull_results` response includes `error` (failed jobs) and `limit` (applied job limit).\n\n## API-Enforced Monitor Constraints\n\n- `create_monitor.backfill=true`: reference job `end_date` must be within the last 7 days.\n- `create_monitor.backfill=false`: reference job age constraint does not apply.\n- Monitor minimum schedule frequency depends on plan.\n- `create_monitor` supports optional `limit` (minimum `10`), `backfill` (default `true`), `timezone`, `webhook_ids`, and `project_id`.\n- Webhooks are centralized in v1.5.3: register them with `create_webhook`, then attach by ID via `create_monitor.webhook_ids` / `update_monitor.webhook_ids` (no inline webhook config).\n- Monitors are only supported for `base` jobs (not `lite`).\n- `enable_monitor` supports optional `backfill`.\n- `update_monitor` updates `webhook_ids` and/or run `limit` (pass `webhook_ids=[]` to clear assignments).\n- `list_monitors` supports pagination via `page` and `page_size` plus `search`, `ownership`, and `project_id` filters; it returns `total`, `page`, `page_size`, `total_pages`, `monitors`.\n\n## Enrichment Output Notes\n\n- `enrichment.enrichment_confidence` is always present.\n- Company enrichments are structured objects with:\n  - `source_text`\n  - `confidence`\n  - `metadata.name`\n  - `metadata.domain_url`\n  - `metadata.domain_url_confidence`\n\n## Error Handling\n\nTools return:\n\n- Pretty JSON string on success.\n- **(v1.8.0)** An MCP tool error (`isError=True`) for any upstream non-2xx response\n  (bad `api_key`, invalid/foreign `project_id`, not-found ids, validation failures,\n  etc.) or unhandled exception. The error message carries the upstream status code\n  and message, for example `API Error (401): Api key not found`. Before v1.8.0, tools\n  swallowed these failures and returned a plain `\"Error: ...\"` string as a *successful*\n  tool result — clients checking only `isError` would see a false success. That has\n  been fixed: every tool now raises a `ToolError` instead of returning an error string,\n  so failures are always reported as real tool errors.\n\n## Running\n\nInstall dependencies:\n\n```bash\npip install -r requirements.txt\n```\n\nRun over stdio:\n\n```bash\npython server.py\n```\n\nRun over HTTP (if `fastmcp` CLI is available):\n\n```bash\nfastmcp run server.py:mcp --transport streamable-http --host 0.0.0.0 --port 8000\n```\n",
  "bytes": 13136,
  "sha": "9ce3a8f832895a5713a78c21872b08b88b5181c9cec056e9762898fdf7f1cc4c",
  "repo_slug": "newscatcher/catchall-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_com_newscatcherapi_catchall_abef2d3c/readme"
}