Skip to main content
Glama
okfn
by okfn

MCP IATI

Note: Local proof of concept. Starting point for a future mcp-server plugin that processes files following the IATI standard (activities and organisations): documented Python tools, with plugin_info/instructions/sample_questions, a no_tool_disponible fallback tool and a tools module separate from the registration wiring.

It defines tools for exploring activities, organisations, recipient countries, sectors and transactions from a configured IATI XML.

Available tools:

  • search_activities(text, limit=10): search activities by title.

  • list_activity_statuses(): list available activity statuses and counts.

  • list_reporting_organisations(): list reporting organisations and their number of activities.

  • list_recipient_countries(): list recipient countries and activity counts.

  • filter_activities_by_country(country, limit=10): filter activities by recipient-country code or name.

  • list_sectors(limit=100): list sector codes, names and vocabularies.

  • activity_summary(iati_identifier): show the main information and financial totals for one activity.

  • activity_transactions(iati_identifier, limit=50): list an activity's transactions in chronological order.

  • transaction_totals_by_year(year_from=None, year_to=None): group commitment and disbursement totals by year, transaction type and currency, while ignoring invalid dates/values and using the activity default currency when a transaction currency is missing.

  • transaction_totals_by_organisation(limit=50): group commitments and disbursements by reporting organisation, keeping transaction types and currencies separate and clarifying that the reporting organisation is the publisher of the activity data, not necessarily the funder or implementer.

  • transaction_totals_by_country(transaction_type="2", currency=None, limit=50): group commitments and disbursements by recipient country, keeping transaction types and currencies separate and using a clear fallback label when country details are missing.

  • transaction_totals_by_sector(transaction_type="2", currency=None, vocabulary=None, limit=50): allocate commitment or disbursement totals across sectors using the published percentages, keeping vocabularies and currencies separate and adding an Unallocated sector bucket when percentages do not total 100%.

  • top_activities_by_amount(transaction_type="2", currency=None, limit=10): list activities with the highest commitment or disbursement totals, ranked independently for each currency.

  • define_term(term): explain an IATI term using the central glossary.

Guiding principle: these tools only use generic IATI standard fields (identifiers, statuses, organisations, recipient countries, sectors and transactions), never Brazil- or IADB-specific logic - they must work just as well with any other IATI XML (see the configuration variables below).

Where the data comes from

The XML files are official IATI publications of the Inter-American Development Bank, not versioned in this repo: they are downloaded on demand from the bank's own hosting at webimages.iadb.org/iati (the same URLs the IATI registry indexes; the IADB refreshes them monthly) into the user data directory (~/.local/share/mcp-iati/xml/ on Linux, via platformdirs) and refreshed when the configured TTL expires. The .gitignore excludes any *.xml just in case.

Related MCP server: XRPL Data MCP

How the XML is processed

  1. mcp_iati/activities/data.py converts the configured XML to flat CSVs and reuses the source-specific cache until its TTL expires, using okfn_iati.IatiMultiCsvConverter().xml_to_csv_folder(...) (the same library ckanext-iati-generator uses in production, but in the XML -> CSV direction instead of CSV -> XML).

  2. The tools (mcp_iati/activities/queries.py) query those CSVs with pandas, not the XML - this avoids reparsing a multi-MB file on every call.

  3. It uses iadb-Brazil.xml by default. To use another official IADB country file, a remote URL or a local file, without touching code:

    # another IADB country file from https://webimages.iadb.org/iati/
    export MCP_IATI_SAMPLE=iadb-Argentina.xml
    
    # or any remote IATI XML
    export MCP_IATI_XML_URL=https://example.org/activities.xml
    
    # or any local file (downloads nothing)
    export MCP_IATI_XML_PATH=/path/to/another-iati-file.xml

Configuration

Configuration is read once when the process starts. Restart the server after changing the source, data directory or cache duration.

Variable

Description

Default

MCP_IATI_XML_PATH

Path to a local XML. It has priority and performs no download.

Not set.

MCP_IATI_XML_URL

HTTP(S) URL of a remote XML, used when no local path is configured.

Not set.

MCP_IATI_SAMPLE

Name of an official IADB country file (from https://webimages.iadb.org/iati/), used when neither a path nor URL is configured.

iadb-Brazil.xml.

MCP_IATI_DATA_DIR

Directory for downloaded XML files and generated CSV files.

User data directory provided by platformdirs.

MCP_IATI_CACHE_TTL_SECONDS

Configurable cache duration in seconds; must be greater than zero.

2592000 (30 days; IATI files are typically updated yearly).

MCP_IATI_STALE_RETRY_SECONDS

How long to keep serving a stale CSV cache after a failed refresh before retrying the conversion; must be greater than zero.

3600 (1 hour).

Downloaded XML files and converted CSV folders are reused while they remain inside this TTL. Once it expires, the XML is downloaded again and the CSVs are regenerated. CSV caches use a key derived from the configured origin, so Argentina, Brazil and custom URLs never share the same converted files. If a remote refresh fails and a previous XML exists, that stale copy is used with a runtime warning instead of making the tools unavailable.

The source precedence is:

  1. MCP_IATI_XML_PATH.

  2. MCP_IATI_XML_URL.

  3. MCP_IATI_SAMPLE.

  4. The default iadb-Brazil.xml sample.

Example:

export MCP_IATI_XML_URL=https://example.org/iadb-Argentina.xml
export MCP_IATI_DATA_DIR=/var/cache/mcp-iati
export MCP_IATI_CACHE_TTL_SECONDS=2592000
uv run mcp-server

CSV tables used by the plugin

Table

Columns currently used

Relationship

activities.csv

activity_identifier, title, activity_status, reporting_org_name, reporting_org_ref, default_currency, recipient_country_code, recipient_country_name

activity_identifier identifies the activity

transactions.csv

activity_identifier, transaction_type, transaction_date, value, currency, description

activity_identifier references activities.csv

sectors.csv

activity_identifier, sector_code, sector_name, vocabulary, percentage

activity_identifier references activities.csv

The three CSV files are loaded as shared pandas DataFrames. Repeated tool calls reuse the same instances and do not download the XML, run the conversion or read the CSV files again.

The data preparation and conversion logic is kept separate from the query logic. Additional CSV tables can be added through DATAFRAME_SPECS.

Development

# Install dependencies (mcp-server from git, okfn-iati from PyPI;
# the dev extra brings ruff and pytest)
uv sync --extra dev

# Lint
uv run ruff check src

Adding this to a local mcp-server

From the mcp-server/ folder, install this package into the same virtual environment:

uv pip install -e ../mcp-iati
uv run mcp-server

The tools become available with the mcp_iati_ prefix.

IATI glossary

The tool descriptions and the plugin instructions share a central glossary defined in src/mcp_iati/glossary.py. Its goal is that the model interprets the standard's terms consistently and explains the distinctions that tend to be ambiguous, especially between reporting, funding and implementing organisations, and between commitment, disbursement and expenditure. The define_term tool exposes it directly, so questions like "what does 'disbursement' mean?" are answered from the glossary (with the IATI standard as the cited source) instead of from the model's own knowledge.

The glossary covers the whole IATI 2.03 activity standard as modelled by the okfn/okfn_iati library (its enums mirror the IATI codelists and its converter flattens each element to a CSV), grouped in these areas:

Area

Terms

Identification and lifecycle

IATI activity, IATI identifier, activity status, activity date, description, hierarchy, related activity, activity scope, humanitarian flag

Organisations

reporting organisation, participating organisation, organisation role, organisation type, provider organisation, receiver organisation, contact information

Financial data

transaction, transaction type, transaction value, commitment, disbursement, expenditure, budget, planned disbursement, default currency, country budget item

Aid classifications

aid type, finance type, flow type, tied status, collaboration type, disbursement channel, policy marker

Sectors and geography

sector, recipient country or region, location

Results and monitoring

result, indicator, indicator period

Documentation and cross-cutting

document link, condition, vocabulary, codelist, narrative

When adding a new tool, reuse the definitions from the central module instead of duplicating them in its docstring (via glossary_text(...) for the relevant terms). When the underlying library starts exposing a new IATI element, add its term to the glossary in the matching group.

Tests

uv run pytest

The tests run offline: tests/conftest.py preloads the data cache with synthetic DataFrames and sets MCP_IATI_XML_PATH, so nothing is downloaded. They cover:

  • that the glossary includes the minimum concepts and that the tool descriptions expose the relevant terms to the model;

  • regression of the queries (tables, sources, empty cases);

  • the raw-data contract (test_raw_data_in_ai_response.py): the gateway sends the AI only the text of the response, so every tool that returns a table must embed it verbatim in that text (done by helpers.text_result). When adding a new tool with a table, add it to the DATA_TOOLS list in that test.

On GitHub, .github/workflows/python-lint.yml runs ruff + pytest on every push.

Install Server
A
license - permissive license
A
quality
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • UN FAOSTAT global food & agriculture statistics over a local SQLite mirror, via MCP.

  • World Bank MCP — wraps the World Bank Data API v2 (free, no auth)

  • USAspending MCP — Federal spending data from USAspending.gov API

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/okfn/mcp-iati'

If you have feedback or need assistance with the MCP directory API, please join our Discord server