{
  "markdown": "<div align=\"center\">\n  <h1>@cyanheads/reliefweb-mcp-server</h1>\n  <p><b>Search ReliefWeb humanitarian reports, disasters, jobs, training, and country profiles via MCP. STDIO or Streamable HTTP.</b>\n  <div>11 Tools • 3 Resources • 1 Prompt</div>\n  </p>\n</div>\n\n<div align=\"center\">\n\n[![Version](https://img.shields.io/badge/Version-0.2.1-blue.svg?style=flat-square)](./CHANGELOG.md) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE) [![Docker](https://img.shields.io/badge/Docker-ghcr.io-2496ED?style=flat-square&logo=docker&logoColor=white)](https://github.com/users/cyanheads/packages/container/package/reliefweb-mcp-server) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^2.0.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![npm](https://img.shields.io/npm/v/@cyanheads/reliefweb-mcp-server?style=flat-square&logo=npm&logoColor=white)](https://www.npmjs.com/package/@cyanheads/reliefweb-mcp-server) [![TypeScript](https://img.shields.io/badge/TypeScript-^7.0.2-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Bun](https://img.shields.io/badge/Bun-v1.4.0-blueviolet.svg?style=flat-square)](https://bun.sh/)\n\n</div>\n\n<div align=\"center\">\n\n[![Install in Claude Desktop](https://img.shields.io/badge/Install_in-Claude_Desktop-D97757?style=for-the-badge&logo=anthropic&logoColor=white)](https://github.com/cyanheads/reliefweb-mcp-server/releases/latest/download/reliefweb-mcp-server.mcpb) [![Install in Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=reliefweb-mcp-server&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBjeWFuaGVhZHMvcmVsaWVmd2ViLW1jcC1zZXJ2ZXIiXSwiZW52Ijp7IlJFTElFRldFQl9BUFBfTkFNRSI6InlvdXItYXBwLW5hbWUifX0=) [![Install in VS Code](https://img.shields.io/badge/VS_Code-Install_Server-0098FF?style=for-the-badge&logo=visualstudiocode&logoColor=white)](https://vscode.dev/redirect?url=vscode:mcp/install?%7B%22name%22%3A%22reliefweb-mcp-server%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40cyanheads%2Freliefweb-mcp-server%22%5D%2C%22env%22%3A%7B%22RELIEFWEB_APP_NAME%22%3A%22your-app-name%22%7D%7D)\n\n[![Framework](https://img.shields.io/badge/Built%20on-@cyanheads/mcp--ts--core-67E8F9?style=flat-square)](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)\n\n</div>\n\n<div align=\"center\">\n\n**Public Hosted Server:** [https://reliefweb.caseyjhand.com/mcp](https://reliefweb.caseyjhand.com/mcp)\n\n</div>\n\n---\n\n## Tools\n\n11 tools for working with ReliefWeb humanitarian data:\n\n| Tool | Description |\n|:---|:---|\n| `reliefweb_search_reports` | Search humanitarian reports with filtering by country, disaster, format, theme, language, source, and date |\n| `reliefweb_get_report` | Fetch a single report by numeric ID with full body text and metadata |\n| `reliefweb_search_disasters` | Search disasters by type, country, status, GLIDE number, and date range |\n| `reliefweb_get_disaster` | Fetch a disaster record with profile, key content links, appeals, and response plans |\n| `reliefweb_get_country` | Fetch a country profile by ISO3 code with overview, appeals, and curated links |\n| `reliefweb_list_countries` | List all countries tracked by ReliefWeb, filterable to active humanitarian situations |\n| `reliefweb_search_jobs` | Search humanitarian job listings by country, organization, career category, and experience level |\n| `reliefweb_get_job` | Fetch a job posting by numeric ID with the full vacancy description and application instructions |\n| `reliefweb_search_training` | Search training and learning opportunities by format, country, career category, and date — upcoming starts by default |\n| `reliefweb_get_training` | Fetch a training listing by numeric ID with the full description, registration instructions, and cost detail |\n| `reliefweb_list_sources` | Browse contributing organizations by name and type |\n\n### Oversized records\n\nThe five `reliefweb_get_*` tools never truncate. Under a fixed byte budget they return the record whole; over it they return a complete section outline — every section, its real serialized size, and how to reach it — and a `sections: [...]` re-call returns exactly the named sections plus identity metadata. The re-call is self-contained: the record is re-fetched from its ID and sliced, so nothing has to be replayed. Both modes carry the same information in `structuredContent` and `content[]`.\n\nThe resources always return the whole record — a resource read has no way to name sections, so reach for the tool when a record is too large.\n\n### Curated-profile archives\n\nA country or disaster profile returns only what ReliefWeb currently curates in each of its three link lists. Each list also has an archive, thousands of entries deep for a long-running crisis — Syria carries 2,328 archived key content links and 120 archived appeals and response plans. `reliefweb_get_country` and `reliefweb_get_disaster` page that archive on request:\n\n```jsonc\n{ \"iso3\": \"SYR\", \"archive\": { \"list\": \"keyContent\", \"offset\": 0, \"limit\": 25 } }\n```\n\nThe response replaces the profile with one page: the list it came from, the true total, how many entries it holds, its offset, the entries, and the next offset while more remain — absent once the page reaches the end. Lists are `keyContent`, `appealsResponsePlans`, and `usefulLinks`, named for the fields the active half lands on.\n\n`sections` and `archive` are alternative modes and a call carrying both is rejected: `sections` slices the record, `archive` replaces it with a page. A record over the response budget still answers an archive call with the page — a page is bounded by `limit` and carries no record prose, so it never outlines.\n\n### `reliefweb_search_reports`\n\nSearch humanitarian reports on ReliefWeb with rich filtering.\n\n- Full-text search across title, body, and key metadata fields\n- Filtering by country (ISO3), disaster ID, format, theme, language, and source organization\n- Date range filtering on source publication date — a bare `2024-01-15` is accepted alongside full ISO 8601\n- Raw filter object for compound conditions not covered by named params\n- Pagination via offset and limit (up to 1,000 per call)\n- Format is a closed set: `News and Press Release`, `Situation Report`, `Map`, `Infographic`, `Analysis`, `Other`, `Assessment`, `Manual and Guideline`, `Appeal`, `UN Document`, `Evaluation and Lessons Learned` — matched ignoring case, spacing, and punctuation; anything else is rejected with the list\n- `include_archived` has no effect here — reports have no archived class, so all of them are in scope by default\n- Returns paginated summaries — use `reliefweb_get_report` to fetch full body text\n- Rate limit: 1,000 calls/day\n\n---\n\n### `reliefweb_get_report`\n\nFetch a single ReliefWeb report by its numeric ID with full body text.\n\n- Full body HTML, all metadata, and file attachment URLs\n- Use after `reliefweb_search_reports` to retrieve document content (10–100KB each)\n- Over the response budget, returns a section outline instead; `sections: [\"body\"]` pulls the body back on its own\n- Returns structured `not_found` when the ID doesn't exist\n\n---\n\n### `reliefweb_search_disasters`\n\nSearch active and historical disasters on ReliefWeb.\n\n- Filtering by disaster type (Earthquake, Flood, Cyclone, etc.), country, and status\n- GLIDE number lookup for cross-system disaster correlation\n- Date range filtering on disaster creation date — a bare `2024-01-15` is accepted alongside full ISO 8601\n- Status values: `alert`, `ongoing`, `past`, `alert-archive`; multiple values comma-separated, matched ignoring case, spacing, and punctuation\n- Optional `include_archived=true` to reach `alert-archive` entries, which the default preset hides\n- Returns IDs for use with `reliefweb_get_disaster` and as `disaster_id` filter in `reliefweb_search_reports`\n\n---\n\n### `reliefweb_get_disaster`\n\nFetch a disaster record by ReliefWeb numeric ID with full details.\n\n- Full description, profile overview, affected countries, and GLIDE number\n- Currently-active curated key content links from the ReliefWeb editorial team (the present set, not the full archive)\n- Currently-active appeals and response plans linked to the disaster\n- Currently-active useful external links curated by ReliefWeb editors\n- Major disasters run to tens of KB of prose; over the response budget the record comes back as a section outline, and `sections: [\"description\"]` or `sections: [\"profileOverview\"]` pulls one narrative at a time\n- `archive: { list: \"keyContent\" }` pages the archived entries each curated list leaves out\n\n---\n\n### `reliefweb_get_country`\n\nFetch a country profile from ReliefWeb by ISO3 code.\n\n- Situation overview text curated by OCHA editors\n- Currently-active key content links maintained by ReliefWeb editors (the present curated set, not the full archive)\n- Currently-active humanitarian appeals and response plans\n- Currently-active useful external links for the country\n- Country profiles are the authoritative situation summary for humanitarian responders\n- `archive: { list: \"keyContent\" }` pages the archived entries each curated list leaves out — 2,328 of them for Syria\n- Carries the same outline-and-`sections` behavior as the other detail tools, though an active-only profile is small enough that it rarely reaches the budget\n\n---\n\n### `reliefweb_list_countries`\n\nList all countries and territories tracked by ReliefWeb.\n\n- Optional `crisis_only=true` to limit to active humanitarian situations (status ongoing)\n- Returns ISO3 codes, status, and canonical URLs — use ISO3 with `reliefweb_get_country`\n- Pagination up to 1,000 entries per call\n\n---\n\n### `reliefweb_search_jobs`\n\nSearch humanitarian job listings on ReliefWeb.\n\n- Filtering by country, organization short name, career category, theme, and experience level\n- Career category values: Programme and Project Management, Information and Communications Technology, Logistics and Telecommunications, and others\n- Returns current open positions — expired postings excluded by default\n- Optional `include_archived=true` to search expired postings too; the archive dwarfs the open set, so use it for labour-market history rather than a hiring snapshot\n- Sortable by newest posting (`date.created:desc`, default) or soonest closing (`date.closing:asc`)\n- Pagination with closing date and canonical URL per listing\n- Returns IDs for use with `reliefweb_get_job`\n\n---\n\n### `reliefweb_get_job`\n\nFetch a job posting by ReliefWeb numeric ID with everything needed to evaluate and apply.\n\n- Full vacancy description and application instructions — neither is in search results\n- Posting status, indexed / closing / last-modified dates, hiring organization, countries, career category, experience level, and job type\n- Both canonical URLs (the readable alias and the node URL)\n- Reaches expired postings as well as open ones\n- Over the response budget, returns a section outline; `sections: [\"howToApply\"]` pulls the instructions without the whole description\n- Returns structured `not_found` pointing back at `reliefweb_search_jobs`\n\n---\n\n### `reliefweb_search_training`\n\nSearch humanitarian training and learning opportunities.\n\n- Covers on-site and online capacity-building events\n- Filtering by country, source, format, career category, and language\n- Date range filtering on training start date (`date_start_from` / `date_start_to`) — a bare `2024-06-01` is accepted alongside full ISO 8601\n- Scoped to training starting from now when neither bound is given; supply either one to search an explicit range, including a historical one\n- Optional `include_archived=true` to search concluded listings too; it also drops the start-from-now default bound, so an otherwise unbounded search reaches the whole record\n- Ordered by soonest start date by default (`date.start:asc`); override with `sort`\n- Distinct from report date fields — uses `date.start` / `date.end`\n- Returns IDs for use with `reliefweb_get_training`\n\n---\n\n### `reliefweb_get_training`\n\nFetch a training listing by ReliefWeb numeric ID with everything needed to evaluate and register.\n\n- Full description and registration instructions — neither is in search results\n- Cost class and the organizer's fee detail, plus the organizer's own event URL\n- Listing status, start / end / registration / indexed dates, host cities, format, type, listing and delivery languages, and organizing source\n- Both canonical URLs (the readable alias and the node URL)\n- Reaches concluded listings as well as current ones\n- Over the response budget, returns a section outline; `sections: [\"cost\", \"feeInformation\", \"howToRegister\"]` pulls just the practicalities\n- Returns structured `not_found` pointing back at `reliefweb_search_training`\n\n---\n\n### `reliefweb_list_sources`\n\nBrowse organizations that contribute content to ReliefWeb.\n\n- Optional filtering by name text or organization type (Government, International Organization, Non-governmental Organization, Academic and Research Institution, Media, Red Cross/Red Crescent Movement, Other)\n- Returns short names, types, organization URLs, and homepage URLs\n- Use `shortname` with the `source` filter in `reliefweb_search_reports`, `reliefweb_search_jobs`, and `reliefweb_search_training`\n\n## Resources and prompt\n\n| Type | Name | Description |\n|:---|:---|:---|\n| Resource | `reliefweb://reports/{id}` | Full report record by numeric ID — metadata, body text, and file URLs. The ID segment must be digits only |\n| Resource | `reliefweb://disasters/{id}` | Disaster record by numeric ID — type, status, GLIDE, description, and content links. The ID segment must be digits only |\n| Resource | `reliefweb://countries/{iso3}` | Country profile by ISO3 code — overview, situation summary, and active response plans |\n| Prompt | `reliefweb_crisis_briefing` | Generate a structured humanitarian briefing for a country or disaster |\n\n## Features\n\nBuilt on [`@cyanheads/mcp-ts-core`](https://github.com/cyanheads/mcp-ts-core):\n\n- Declarative tool definitions — single file per tool, framework handles registration and validation\n- Unified error handling across all tools\n- Pluggable auth (`none`, `jwt`, `oauth`)\n- Swappable storage backends: `in-memory`, `filesystem`, `Supabase`, `Cloudflare KV/R2/D1`\n- Structured logging with optional OpenTelemetry tracing\n- Runs locally (stdio/HTTP) or on Cloudflare Workers from the same codebase\n\nReliefWeb-specific:\n\n- Full coverage of six ReliefWeb content types: reports, disasters, countries, jobs, training, sources\n- Compound filter builder supporting nested AND/OR conditions for the ReliefWeb API v2\n- `RELIEFWEB_APP_NAME` validated at startup (required by the API since November 2025)\n- 1,000 calls/day quota awareness — prominently documented on each tool\n\nAgent-friendly output:\n\n- Body text excluded from search results by design — agents fetch it explicitly with the matching `reliefweb_get_*` tool to control context budget\n- Oversized records outline rather than truncate, with a section selector to retrieve what's needed\n- Curated-profile archives are paged rather than dropped, with honest totals and a next offset\n- Recovery hints on empty results — echoes applied filters and suggests how to broaden\n- Typed `not_found` error contracts on get-by-ID tools with actionable recovery text\n\n## Getting started\n\n### Prerequisites\n\n- [Bun v1.3.2](https://bun.sh/) or higher.\n- A **pre-approved ReliefWeb appname** — register at [ReliefWeb API](https://reliefweb.int/help/api) and set `RELIEFWEB_APP_NAME`. The API has required pre-approved appnames since November 2025; requests without one are rejected.\n\n### Public Hosted Instance\n\nA public instance is available at `https://reliefweb.caseyjhand.com/mcp` — no installation required. Point any MCP client at it via Streamable HTTP:\n\n```json\n{\n  \"mcpServers\": {\n    \"reliefweb-mcp-server\": {\n      \"type\": \"streamable-http\",\n      \"url\": \"https://reliefweb.caseyjhand.com/mcp\"\n    }\n  }\n}\n```\n\n### Self-Hosted / Local\n\nAdd the following to your MCP client configuration file.\n\n```json\n{\n  \"mcpServers\": {\n    \"reliefweb-mcp-server\": {\n      \"type\": \"stdio\",\n      \"command\": \"bunx\",\n      \"args\": [\"@cyanheads/reliefweb-mcp-server@latest\"],\n      \"env\": {\n        \"MCP_TRANSPORT_TYPE\": \"stdio\",\n        \"MCP_LOG_LEVEL\": \"info\",\n        \"RELIEFWEB_APP_NAME\": \"your-app-name\"\n      }\n    }\n  }\n}\n```\n\nOr with npx (no Bun required):\n\n```json\n{\n  \"mcpServers\": {\n    \"reliefweb-mcp-server\": {\n      \"type\": \"stdio\",\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@cyanheads/reliefweb-mcp-server@latest\"],\n      \"env\": {\n        \"MCP_TRANSPORT_TYPE\": \"stdio\",\n        \"MCP_LOG_LEVEL\": \"info\",\n        \"RELIEFWEB_APP_NAME\": \"your-app-name\"\n      }\n    }\n  }\n}\n```\n\nFor Streamable HTTP, set the transport and start the server:\n\n```sh\nMCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 RELIEFWEB_APP_NAME=your-app-name bun run start:http\n# Server listens at http://localhost:3010/mcp\n```\n\n### Installation\n\n1. **Clone the repository:**\n\n```sh\ngit clone https://github.com/cyanheads/reliefweb-mcp-server.git\n```\n\n2. **Navigate into the directory:**\n\n```sh\ncd reliefweb-mcp-server\n```\n\n3. **Install dependencies:**\n\n```sh\nbun install\n```\n\n## Configuration\n\nAll configuration is validated at startup via Zod schemas. Key environment variables:\n\n| Variable | Description | Default |\n|:---|:---|:---|\n| `RELIEFWEB_APP_NAME` | **Required.** Pre-approved appname for the ReliefWeb API v2. Register at reliefweb.int/help/api. | — |\n| `MCP_TRANSPORT_TYPE` | Transport: `stdio` or `http` | `stdio` |\n| `MCP_HTTP_PORT` | HTTP server port | `3010` |\n| `MCP_HTTP_ENDPOINT_PATH` | HTTP endpoint path where the MCP server is mounted | `/mcp` |\n| `MCP_PUBLIC_URL` | Public origin override for TLS-terminating reverse-proxy deployments | none |\n| `MCP_AUTH_MODE` | Authentication: `none`, `jwt`, or `oauth` | `none` |\n| `MCP_SESSION_MODE` | HTTP session handling: `stateless`, `stateful`, or `auto`. Shipped as `stateless` — no handler needs a session. | `auto` (resolves to `stateful`) |\n| `MCP_LOG_LEVEL` | Log level (`debug`, `info`, `warning`, `error`, etc.) | `info` |\n| `MCP_GC_PRESSURE_INTERVAL_MS` | Opt-in Bun-only forced-GC pressure loop (ms). Try `60000` if heap growth is observed under sustained HTTP load. | `0` (disabled) |\n| `LOGS_DIR` | Directory for log files (Node.js only). | `<project-root>/logs` |\n| `STORAGE_PROVIDER_TYPE` | Storage backend: `in-memory`, `filesystem`, `supabase`, `cloudflare-kv/r2/d1` | `in-memory` |\n| `OTEL_ENABLED` | Enable OpenTelemetry | `false` |\n\n## Running the server\n\n### Local development\n\n- **Build and run the production version**:\n\n  ```sh\n  # One-time build\n  bun run rebuild\n\n  # Run the built server\n  bun run start:http\n  # or\n  bun run start:stdio\n  ```\n\n- **Run checks and tests**:\n  ```sh\n  bun run devcheck  # Lints, formats, type-checks, and more\n  bun run test      # Runs the test suite\n  ```\n\n## Project structure\n\n| Directory | Purpose |\n|:---|:---|\n| `src/mcp-server/tools` | Tool definitions (`*.tool.ts`). Eleven tools across reports, disasters, countries, jobs, training, and sources, plus the shared pagination, section-outline, and profile-archive helpers. |\n| `src/mcp-server/resources` | Resource definitions. Report, disaster, and country resources. |\n| `src/mcp-server/prompts` | Prompt definitions. Crisis briefing prompt. |\n| `src/services/reliefweb` | ReliefWeb API service layer — HTTP client, filter builder, and response normalizers for all six content types. |\n| `src/config` | Server-specific environment variable parsing and validation with Zod. |\n| `tests/` | Unit and integration tests, mirroring the `src/` structure. |\n\n## Development guide\n\nSee [`CLAUDE.md`](./CLAUDE.md) for development guidelines and architectural rules. The short version:\n\n- Handlers throw, framework catches — no `try/catch` in tool logic\n- Use `ctx.log` for logging, `ctx.state` for storage\n- Register new tools and resources in the `createApp()` arrays\n\n## Contributing\n\nIssues and pull requests are welcome. Run checks and tests before submitting:\n\n```sh\nbun run devcheck\nbun run test\n```\n\n## License\n\nThis project is licensed under the Apache 2.0 License. See the [LICENSE](./LICENSE) file for details.\n",
  "bytes": 20172,
  "sha": "b62c8c2d012d0c8467787c68e9f9da7aa43bf5728186ed8178a950d6d007912d",
  "repo_slug": "cyanheads/reliefweb-mcp-server",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_cyanheads_reliefweb_mcp_server_e6756e49/readme"
}