Skip to main content
Glama
Malja MCP

Malja MCP

Official

Malja MCP — ملجأ

بيانات إنسانية بمصادرها، داخل أدوات البحث ومساعدك الذكي.

Read-only access to humanitarian data through the Model Context Protocol, with Arabic and English output, source attribution and reproducible exports.

CI License: MIT

Current Malja dashboard showing a successful Egypt country search

جرّبه فعليًا · See it work

Actual local dashboard before and after running search_country for Egypt

Captured from the local application on 24 October 2026. The GIF shows search_country resolving Egypt to EGY. Provider status, latency, counters and available resources reflect this capture and configuration; they are not service guarantees or current humanitarian statistics.

Related MCP server: Globalpulse-MCP

What it does

  • Resolve country names in Arabic and English to ISO3 codes.

  • Query displacement, demographics, asylum and durable solutions data from UNHCR.

  • Add population and economic context from World Bank indicators.

  • Enable HDX crisis datasets and ReliefWeb reports with their required provider configuration.

  • Compare countries, inspect trends, generate charts and export data or reports with citations.

  • Connect over stdio or Streamable HTTP; inspect tools and run queries in the built-in dashboard.

ملجأ يربط بيانات المفوضية والبنك الدولي، ومع الإعداد المناسب HDX وReliefWeb، بأدوات بحث للقراءة فقط. يدعم أسماء الدول والإجابات بالعربية، ويرفق مصادر البيانات بالتقارير والتصدير. التغطية وتاريخ البيانات يعتمدان على المصدر والإعداد.

Run locally

The following source workflow was verified with Node.js 24. Use this checkout for the current implementation; published packages, images and release tags may lag behind the source.

git clone https://github.com/marsaplatform/malja-mcp.git
cd malja-mcp
npm ci
npm run build
node dist/index.js --http

Open http://127.0.0.1:8642/ for the dashboard. The local MCP endpoint is http://127.0.0.1:8642/mcp. Select search_country, enter {"query":"egypt"}, then select RUN.

For stdio, use node dist/index.js without --http. For Docker, build the checked-in configuration with docker compose up -d --build; see compose.yaml and .env.example.

This README documents self-hosting. It does not assume an available public hosted endpoint. HTTP access has no built-in authentication; configure access controls before exposing it. See SECURITY.md.

Connect your client (self-hosted, stdio)

{
  "mcpServers": {
    "malja": {
      "command": "node",
      "args": ["/absolute/path/to/malja-mcp/dist/index.js"]
    }
  }
}

Sample with cache tuning: examples/claude-desktop-config.json.

claude mcp add malja -- node /absolute/path/to/malja-mcp/dist/index.js
{
  "mcpServers": {
    "malja": {
      "command": "node",
      "args": ["/absolute/path/to/malja-mcp/dist/index.js"]
    }
  }
}
{
  "servers": {
    "malja": {
      "type": "stdio",
      "command": "node",
      "args": ["/absolute/path/to/malja-mcp/dist/index.js"]
    }
  }
}
{
  "mcpServers": {
    "malja": {
      "command": "node",
      "args": ["/absolute/path/to/malja-mcp/dist/index.js"]
    }
  }
}

Then ask: "What are the top refugee-hosting countries this year?"

Configuration and data boundaries

UNHCR and World Bank are enabled by default. HDX needs an app identifier; ReliefWeb needs an approved appname. Provider credentials and environment settings are documented in .env.example.

  • Use locale: "ar" per tool call or MALJA_LOCALE=ar for Arabic output.

  • Offline mode needs a previously warmed cache; missing cached requests fail explicitly.

  • Data freshness follows the original publisher and cache settings. On upstream failure, cached results can be stale.

  • Distinguish stocks from flows, and check category, reference year and extraction date before comparing figures.

  • Forecasts are labelled extrapolations, not operational planning estimates.

Architecture

flowchart LR
    Client["MCP client / dashboard"] --> Server["Malja tools and resources"]
    Server --> Shared["Provider registry, cache and request limits"]
    Shared --> UNHCR["UNHCR"]
    Shared --> WB["World Bank"]
    Shared --> Optional["HDX / ReliefWeb when configured"]

Development

npm run check          # types, lint, formatting and tests
npm run build          # production output
npm audit              # dependency advisories at the time of the check

Validation records are dated rather than embedded as permanent marketing counts: 24 October 2026 review. The CI badge links to actual workflow results.

Documentation

Attribution

Independent project; not an official UN or World Bank product. Data retains its original publishers' attribution and terms. Cite both the software and the original datasets; preserve the extraction manifest when sharing results. The source code is MIT licensed.

Company container image

The maintained container is published under the company account and linked to marsaplatform/malja-mcp.

docker pull ghcr.io/marsaplatform/malja-mcp:latest

Use the Publish company container workflow to publish the current source. latest tracks stable releases and manual snapshots; sha-… tags identify the source commit. The old personal-account packages have been removed; use the company installation URL above. Publishing does not change repository visibility.

Versioned updates

See container releases and migration for numbered versions, automatic release publishing, runtime verification, and the updated company installation commands.

Available Tools

24 tools
asylum_applicationsAsylum applicationsA
Read-only

Individual asylum applications lodged per year. role "asylum" (default) = applications filed IN the country; "origin" = filed BY nationals of the country abroad.

Inputs: country (required), role, locale, year_to, +1 more. Returns: role, source, yearly, country, +1 more

asylum_decisionsAsylum decisionsA
Read-only

Decisions on individual asylum applications per year — recognized, complementary protection, rejected, otherwise closed — plus the recognition rate. role "asylum" (default) = decided IN the country.

Inputs: country (required), role, locale, year_to, +1 more. Returns: role, source, yearly, country, +1 more

compare_countriesCompare countriesA
Read-only

Compare a displacement metric across 2–5 countries over a year range. Defaults to refugees hosted (role "asylum") over the last 10 years. Set normalize_by to compare per 1,000 residents or per US$1bn GDP instead of absolute numbers.

Inputs: countries (required), role, locale, metric, +3 more. Returns: role, unit, metric, series, +3 more

conflict_eventsConflict eventsA
Read-only

Annual conflict event counts and fatalities for a country (ACLED via HDX). Pairs with refugee_population/trend_analysis to relate violence and displacement.

Inputs: country (required), locale, year_to, year_from. Returns: source, country, records, country_code

country_profileCountry profileA
Read-only

One-call humanitarian snapshot of a country: latest displaced population hosted (by category), population displaced FROM the country, and its top origin countries.

Inputs: country (required), locale. Returns: year, hosted, region, source, +4 more

demographicsDemographicsA
Read-only

Latest age/sex breakdown of displaced people connected to a country (role "asylum" = hosted there, default; "origin" = from there). UNHCR publishes demographics for recent years only.

Inputs: country (required), role, locale. Returns: male, year, total, female, +3 more

durable_solutionsDurable solutionsA
Read-only

UNHCR durable solutions per year: refugee returns, resettlement, naturalisation and IDP returns. These are FLOWS during each year (not end-year stocks), so a period total is reported. role "origin" (default) = solutions for people FROM the country (returns home, resettled/naturalised abroad); role "asylum" = refugees who left the country to return home, people resettled TO it, naturalised IN it. Optional other_country cross-filter and normalize_by ("population" → per 1,000 residents of the country).

Inputs: country (required), role, locale, year_to, +3 more. Returns: role, unit, years, source, +8 more

export_dataExport dataA
Read-only

Export normalized records from any dataset as csv, json, markdown or geojson (geojson only makes sense with group_by set, so rows map to countries). Use this when the user wants raw data to download or paste elsewhere.

Inputs: format (required), dataset (required), role, limit, +7 more. Returns: data, format, dataset, codebook, +3 more

export_reportExport formatted report (HTML / PDF)A
Read-only

Export a print-ready, self-contained document: the full country report (pass country) or any tool’s markdown output (pass markdown, e.g. from trend_analysis or durable_solutions). format "html" (default) = one file with embedded Arabic/Latin font, inline SVG charts, citations and the extraction manifest; "pdf" = the same rendered by a local headless Chrome/Chromium/Edge (falls back to HTML with an explanation if none is available). Arabic output (locale "ar") is right-to-left. Returns a resource link (export://…) unless inline is true.

Inputs: title, format, inline, locale, +5 more. Returns: uri, bytes, title, format, +8 more

food_securityFood security (IPC)B
Read-only

Latest IPC food-insecurity phase breakdown for a country: people per phase 1–5, with phase 3+ ("crisis or worse") as the headline. Data: IPC via HDX.

Inputs: country (required), year, locale. Returns: year, phases, source, country, +2 more

forecastForecast (naive, with prediction intervals)A
Read-only

Naive linear projection of a displacement metric 1–5 years ahead, based on the last 10 years, with 80% and 95% OLS prediction intervals. Structural breaks in the history are detected and reported; since_break=true fits only the data after the latest break. Optional chart (svg / chartjs / vega-lite) with the interval band. This is a statistical extrapolation, NOT a UNHCR planning figure — always present it with that caveat.

Inputs: country (required), role, chart, locale, +3 more. Returns: chart, caveat, fit_to, method, +8 more

generate_chartGenerate chartA
Read-only

Render a displacement metric for one or more countries as a chart specification. Formats: "chartjs" (Chart.js v4 config JSON), "vega-lite" (v5 spec), "mermaid" (xychart block), "svg" (standalone image markup). Set normalize_by to plot per 1,000 residents or per US$1bn GDP. show_changepoints=true marks detected structural breaks (svg, vega-lite; Chart.js via chartjs-plugin-annotation).

Inputs: format (required), countries (required), kind, role, +6 more. Returns: spec, unit, title, format

generate_country_reportGenerate country reportA
Read-only

Compose a full markdown humanitarian situation report for a country: key figures, refugee trend with an embedded chart, origins of hosted refugees, asylum decisions and demographics. Reports progress while assembling.

Inputs: country (required), locale, year_to, year_from. Returns: country, year_to, markdown, year_from, +1 more

generate_mapGenerate map (GeoJSON)A
Read-only

GeoJSON FeatureCollection of country centroid points sized by a displacement metric — drop it into any GeoJSON viewer (geojson.io, Leaflet, Kepler). by="asylum" maps host countries, by="origin" maps origins.

Inputs: by, year, limit, locale, +1 more. Returns: year, metric, geojson, feature_count, +1 more

get_metadataGet metadataA
Read-only

Describe the connected data providers: datasets served, metrics available, attribution and terms. Call this to learn what data exists before querying.

Inputs: locale. Returns: providers

humanitarian_fundingHumanitarian fundingA
Read-only

Humanitarian appeal requirements vs funding received per year for a country, with coverage percentage (OCHA FTS via HDX).

Inputs: country (required), locale, year_to, year_from. Returns: source, country, records, country_code

latest_statisticsLatest statisticsA
Read-only

Most recent displacement figures. With a country: its latest hosted figures. Without: the latest global totals.

Inputs: role, locale, country. Returns: year, scope, source, figures

monitor_changesMonitor changesA
Read-only

Check a country's UNHCR displacement figures for changes worth attention: compares the latest year with the previous one (significant jumps, threshold crossings, record highs/lows) and, against an earlier snapshot, detects new data releases and revisions of past years. Returns alert-ready events with stable ids and severities plus a snapshot to compare against next time. Read-only: never contacts anyone; the snapshot is kept in the server cache and/or returned to the caller.

Inputs: country (required), role, locale, metrics, +7 more. Returns: role, events, source, country, +10 more

provider_healthProvider healthA
Read-only

Liveness check of every connected data provider (latency, reachability). Use when queries fail to distinguish upstream outages from bad parameters.

Inputs: locale. Returns: healthy, providers

refugee_populationRefugee populationA
Read-only

Yearly displacement figures for a country: refugees, asylum-seekers, IDPs, stateless and others. role "asylum" (default) = hosted in the country; role "origin" = displaced from it. Optionally cross-filter by a second country (e.g. Syrians hosted in Egypt). Paginated.

Inputs: country (required), page, role, limit, +4 more. Returns: source, records, page_info

search_countrySearch countryA
Read-only

Resolve a free-text country query ("egypt", "DRC", "syria") to canonical names and ISO3 codes. Use this first when unsure how a country is spelled in the data.

Inputs: query (required), limit, locale. Returns: matches

situation_reportsSituation reportsA
Read-only

Situation reports published about a country: yearly counts plus the most recent report titles and links (ReliefWeb). Use it to ground trends and anomalies from other tools in what was actually reported at the time.

Inputs: country (required), query, locale, year_to, +2 more. Returns: latest, source, country, records, +1 more

top_host_countriesTop host / origin countriesA
Read-only

Rank countries by a displacement metric for a year. by="asylum" (default) ranks host countries; by="origin" ranks countries people fled from. Set normalize_by="population" to rank per 1,000 residents (or "gdp" per US$1bn) — the ranking that shows Lebanon and Chad ahead of large economies.

Inputs: by, year, limit, locale, +2 more. Returns: by, unit, year, metric, +3 more

trend_analysisTrend analysisA
Read-only

Analyse how a displacement metric evolved for a country: yearly series, year-over-year changes, linear trend (slope, R²), CAGR, statistically anomalous years (z-scores of yearly changes) and changepoints (structural breaks in level/slope, exact penalised segmentation). Default: refugees hosted, last 10 years — widen year_from for better changepoint power.

Inputs: country (required), role, locale, metric, +2 more. Returns: role, trend, metric, series, +7 more

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.8/5.0

    Scored across 24 tools

    Disambiguation4/5

    Most tools target a clearly distinct action (trend_analysis vs forecast vs monitor_changes vs durable_solutions are well separated), and descriptions explicitly state defaults and roles to steer selection. Minor overlap remains: latest_statistics duplicates what country_profile and refugee_population already return, and compare_countries vs top_host_countries both rank the same metrics, so an agent may hesitate between them.

    Naming Consistency4/5

    All names are snake_case with no style mixing, and there is a readable convention: verb_noun for actions (search_country, generate_chart, export_data, monitor_changes) and plain dataset nouns for data retrieval (refugee_population, asylum_decisions, food_security). The split is sensible but not stated, so a couple of names like country_profile and situation_reports sit ambiguously between the two patterns.

    Tool Count3/5

    24 tools is at the heavy end for a single server, even a broad humanitarian-data one. Each tool does earn a place (query, context, analysis, output, meta are all represented), but consolidation is possible — several dataset tools could collapse into one parameterised retrieval, and latest_statistics largely duplicates existing coverage.

    Completeness5/5

    The surface covers the full workflow: name resolution, country snapshots, per-dataset time series, demographic and asylum breakdowns, contextual indicators (conflict, food security, funding, situation reports), analysis (trends, changepoints, forecasts, change monitoring), and multiple output formats (chart, map, report, HTML/PDF, raw CSV/JSON/GeoJSON), plus metadata and provider health. No obvious dead ends for a read-only data server.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      D
      maintenance
      Exposes World Bank development data and country information via MCP resources and tools, enabling AI agents to query historical indicators and live API data.
      -
    • A
      license
      A
      quality
      D
      maintenance
      A Model Context Protocol server that provides real-world intelligence including macroeconomics, climate, disasters, aviation, trade, and country data from globally trusted open APIs with no proprietary subscriptions required.
      11
      46 npm
      1
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Enables AI assistants to discover, retrieve, and compare official international development indicators from sources such as the World Bank, FAOSTAT, WHO, UNICEF, and IMF, while preserving source identifiers, units, and citations.
      10
      2
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables searching and retrieving Humanitarian Data Exchange datasets, locations, and publishing organizations via CKAN, supporting discovery of data on displacement, refugees, food security, conflict, disasters, health, and population.
      308 npm
      MIT