Skip to main content
Glama

unhcr-refugees-mcp-server

Server Details

Query UNHCR refugee, IDP, and stateless populations, asylum decisions, returns, and resettlement.

If you are the author of this connector, you can claim ownership by verifying the domain or GitHub account it belongs to. Claimed connector authors can inspect health checks, view analytics, and manage their listing.
Status
Healthy
Uptime
99.9% over 25 days
Last Tested
Transport
Streamable HTTP · MCP 2025-11-25
URL
Repository
cyanheads/unhcr-refugees-mcp-server
GitHub Stars
1
Server Listing
@cyanheads/unhcr-refugees-mcp-server

TDQS

A4.3/5.0

Scored across 8 tools

Disambiguation4/5

Each unhcr_get_* tool targets a distinct UNHCR dataset (applications, decisions, demographics, population, solutions), and descriptions explicitly cross-reference to prevent confusion between similar-sounding pairs like population vs demographics and applications vs decisions. The two dataframe tools (describe vs query) are cleanly separated by read-schema vs run-SQL. Only minor residual overlap between the asylum applications/decisions and population/demographics pairs keeps it from a perfect score.

Naming Consistency5/5

All tools share a consistent unhcr_ prefix followed by a predictable verb_noun pattern: unhcr_get_*, unhcr_list_*, and unhcr_dataframe_describe/query. The convention is uniform and readable throughout.

Tool Count5/5

Eight tools is well-scoped for a domain-focused data retrieval server: five get_* dataset accessors, a reference decoder, and two dataframe helpers that generalize any dataset spanning them. Each tool earns its place without redundancy.

Completeness5/5

The surface covers the core UNHCR data domains (applications, decisions, demographics, population stocks, solutions), a reference/code-lookup tool for the controlled vocabularies, and a describe/query pair that lets agents work with any staged dataset. As a read-only data service, no create/update/delete operations are needed, so there are no obvious dead ends.

Available Tools

8 tools
unhcr_dataframe_describeDescribe staged dataframesA
Read-onlyIdempotent
Inspect

Describe a dataframe (df_XXXXX_XXXXX) staged by the unhcr_get_* tools — any response carrying a dataset handle staged its full result here — or list them all where this deployment allows listing. Each entry gives the source tool, query parameters, creation and expiry time, row count, whether the upstream fetch was complete, and the column schema. Read the columns here before writing SQL for unhcr_dataframe_query.

NameRequiredDescriptionDefault
nameNoOne dataframe to describe, as df_XXXXX_XXXXX (uppercase letters and digits): the dataset.name a unhcr_get_* result returned, or a register_as name. Omit to list every staged dataframe; a deployment that serves unauthenticated callers over HTTP turns listing off, and there the name is required.

Output Schema

NameRequiredDescription
errorNoPresent when the call failed. Absent on success.
noticeNoGuidance when nothing is staged or the named dataframe is gone.
dataframesNoStaged dataframes, newest first. Empty when none are staged.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint/idempotentHint/openWorldHint=false, so the safety profile is covered. The description adds genuinely new behavior: staged results expire, listing can be disabled in unauthenticated HTTP deployments, and completeness of the upstream fetch is surfaced. It does not mention pagination or size limits, keeping it short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded and the two sentences are dense with useful content. The opening sentence is somewhat convoluted with its em-dash aside ('— any response carrying a dataset handle staged its full result here —'), but nothing is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values needn't be explained, yet the description enumerates the entry fields (source tool, query params, creation/expiry, row count, completeness, column schema), which is slightly redundant but helps the agent know what it can rely on. The full describe→query workflow is covered.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single 'name' parameter is fully documented in the schema, including the pattern and the listing fallback. The description restates the staging origin (dataset.name / register_as name) and the listing-off case rather than adding new syntax or format detail, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Describe a dataframe (df_XXXXX_XXXXX) staged by the unhcr_get_* tools') and explicitly names the sibling it feeds into (unhcr_dataframe_query). An agent can distinguish it from the query tool and from the unhcr_get_* producers without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit routing: 'Read the columns here before writing SQL for unhcr_dataframe_query.' It also states the when-not condition — omit name to list, but name is required in deployments serving unauthenticated HTTP callers. Both the action and the exclusion are spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unhcr_dataframe_queryQuery staged dataframesA
Read-onlyIdempotent
Inspect

Run a single-statement SELECT against the dataframes staged by the unhcr_get_* tools. Check a dataframe’s columns with unhcr_dataframe_describe first. Writes, DDL, DROP, COPY, PRAGMA, ATTACH, file references, external-data functions, engine introspection, dynamic table lookup, and system catalogs are rejected; query() accepts only a single SQL string literal, checked by the same gate. Optional register_as saves the result as a new dataframe with a fresh TTL. Recompute rates from summed counts rather than averaging rate columns.

NameRequiredDescriptionDefault
sqlYesOne DuckDB SELECT against df_XXXXX_XXXXX tables, at most 20,000 characters — joins, aggregates, window functions, and CTEs work. SUM and COUNT results come back as JSON strings (BIGINT); CAST(… AS DOUBLE) for inline arithmetic. Staged tables add origin/asylum UNHCR and UN region columns for regional GROUP BY.
previewNoRequested inline rows, 0–1000000. Values above row_limit are clamped to row_limit with disclosure. Omit to return every row up to row_limit; the serialized byte ceiling may withhold whole rows or metadata, preserving the result as lossless chunks.
row_limitNoMost rows the query materializes (1–10000, default 1000). When more match, row_count_capped is true; use register_as to keep the full result.
register_asNoSave the result as a new dataframe under this name (df_ plus two groups of 5 uppercase letters or digits, e.g. df_ABCDE_12345) with a fresh TTL, to chain analyses. The name must not already be staged. The saved rows count toward the 1,000,000-row staging budget: the oldest other dataframes are evicted to make room, and a result larger than the budget is not saved.

Output Schema

NameRequiredDescription
capNoThe cap that bound: preview when lower than row_limit, otherwise row_limit.
rowsNoResult rows, one object per row keyed by column name, bounded by preview and row_limit. BIGINT values (SUM, COUNT) arrive as strings.
errorNoPresent when the call failed. Absent on success.
shownNoRows returned inline.
noticeNoGuidance when the query returned no rows or rows were withheld.
columnsNoColumn names in projection order.
evictedNoOlder dataframes dropped, oldest first, to keep the staged total within the 1,000,000-row budget once register_as saved this result; they can no longer be queried. Present only when any were evicted.
completeNoFalse when any original source fetch was incomplete, independently of display truncation.
row_countNoRows the query produced, up to row_limit. When row_count_capped is true this is the cap, not the full size.
truncatedNoTrue when rows were withheld by a cap.
expires_atNoISO 8601 expiry of the new dataframe, when register_as was set.
attributionNoAttribution UNHCR requires when these figures are reused.
registered_asNoThe new dataframe, when register_as was set.
result_chunksNoLossless materialized result snapshot when the byte ceiling withholds rows or metadata.
row_count_cappedNoTrue when more rows matched than row_limit allowed through.
metadata_withheldNoTrue when oversized column names or incomplete-source metadata are withheld inline and retained in result_chunks.
incomplete_sourcesNoOriginal incomplete upstream dataframe handles; retained through saved descendants. If metadata_withheld is true, consult the result snapshot for the full list.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint/idempotentHint/openWorldHint, but the description adds substantial non-obvious behavior: the full list of rejected statements (writes, DDL, COPY, PRAGMA, ATTACH, external functions, catalogs), the single-string-literal gate, and register_as semantics including fresh TTL, 1M-row staging budget, eviction of the oldest dataframes, and non-save on overflow.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then the prerequisite, then constraints, then the optional save behavior. The enumeration of rejected constructs is long but each item carries real invocation-relevant information; only the trailing rate-recomputation sentence feels like an aside rather than core guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need no explanation, and the description still covers constraints, prerequisites, staging-budget side effects, and the chaining path via register_as. An agent has everything needed to call this correctly and safely.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the parameter descriptions are already rich (clamping behavior, row_limit caps, register_as naming pattern). The description's mention that register_as 'saves the result as a new dataframe with a fresh TTL' largely restates the schema, so it adds only marginal meaning; the rate-averaging note is analytical advice rather than parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Run a single-statement SELECT against the dataframes staged by the unhcr_get_* tools') and scopes it to staged dataframes, which cleanly separates it from the unhcr_get_* staging tools and unhcr_dataframe_describe.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It prescribes the workflow order explicitly ('Check a dataframe's columns with unhcr_dataframe_describe first') and names register_as as the path for chaining analyses. The rejection list tells the agent precisely which SQL constructs will fail, which is actionable when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unhcr_get_asylum_applicationsUNHCR asylum applicationsA
Read-onlyIdempotent
Inspect

Get asylum applications lodged per year (2000 to the latest year) by country of origin and/or asylum, split by default into application stage — new, repeat, appeal, and the combined stages some countries report — so new claims are not added to appeals of old ones. Counts given as cases are never added to counts of persons; each row states its unit. Decode stage, authority, and decision-level codes with unhcr_list_reference (topic asylum_codes).

NameRequiredDescriptionDefault
limitNoRequested inline rows, 1–1000000 (default 100); values above 500 are clamped to 500 with disclosure. Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled.
stageNoStage the full result as a dataframe even when it fits inline, e.g. to join it with another unhcr_get_* result in unhcr_dataframe_query. Where dataframes are unavailable it is ignored, and the notice says so.
asylumNoCountry of asylum — where people sought or hold protection; for returns, the country they returned from — as ISO3 codes (DEU, TUR), case-insensitive, same rules as origin. At most 50 codes. Omit to sum every asylum country into one row, or set expand to list each.
expandNoList every country, one row each, for a dimension that origin or asylum leaves unfiltered: origin, asylum, or both. Default none, where an unfiltered dimension is summed into one row. Expanding a dimension that origin or asylum already filters is rejected.none
originNoCountry of origin — where people fled from — as ISO3 codes (SYR, AFG), case-insensitive. ISO 3166 alpha-2 codes (SY) are rewritten to ISO3 and echoed in applied_scope. UNHCR's own codes (GFR) are rejected with the ISO3 to pass instead, and country names are rejected: resolve a name with unhcr_list_reference (topic countries, name_contains). Each listed code returns its own rows; codes are never summed together. At most 50 codes. Omit to sum every origin into one row, or set expand to list each.
stagesNoKeep only these application stages before summing, case-insensitive: N new, R repeat, A appeal, NA new and appeal together, NR new and repeat together, FA first and appeal, J judiciary, BL backlog, SP subsidiary protection; V and RA appear in the data without a published definition. ["N"] gives new applications only, the basis of UNHCR's headline figure. Omit for every stage.
sort_byNoOrder of the full result before the inline cut. year (default) orders by year, then origin ISO3, then asylum ISO3; applied orders largest first, nulls last.year
year_toNoLast year of the window. When omitted, the window runs to the latest published year (latest_year in the result). A year past the latest published year is clamped to it and the clamp is reported.
split_byNoProcedure dimensions kept as separate rows: authority (government, UNHCR, or joint), stage (new, repeat, appeal, …), decision_level. Every dimension left out is summed. Default ["stage"]; [] gives one total per year and scope for each unit. Unit is always kept separate.
year_fromNoFirst year of the window. When omitted, the window starts at the dataset's first year. A year before the dataset's first year is clamped to it and the clamp is reported; a window entirely outside the dataset's years is rejected.

Output Schema

NameRequiredDescription
capNoThe limit that was applied.
rowsNoInline rows, sorted, up to limit.
errorNoPresent when the call failed. Absent on success.
shownNoRows returned inline.
noticeNoGuidance for this result: empty-result hints, year clamps, where the full set was staged, or how to narrow.
datasetNoPresent when the full result was staged as a dataframe; read its columns with unhcr_dataframe_describe, then query it with unhcr_dataframe_query.
measureNostock: people in a situation on 31 December; flow: events during the year.
completeNoFalse when the server row cap stopped the upstream fetch; the notice says how many upstream rows were fetched and how to narrow.
truncatedNoTrue when rows were cut at limit.
data_notesNoHow to read the counts: stock or flow, rounding, the meaning of null, caveats.
total_rowsNoRows in the full result before the inline cut. When complete is false, the result is built from only the upstream rows fetched before the cap, so rows and summed counts can fall short of the complete result.
attributionNoAttribution UNHCR requires when these figures are reused.
latest_yearNoNewest year this dataset publishes.
applied_scopeNoThe scope actually sent upstream, including clamped years and code rewrites.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnly, idempotent, open-world, so safety is covered. The description adds real behavioral value beyond that: it warns that case counts are never added to person counts and that each row declares its unit, and that the stage split prevents new claims being merged into old appeals. It omits discussion of rate limits or response size behavior, which the schema covers.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with purpose and scope, then the unit-mixing caveat, then the helper-tool pointer. Dense but every sentence carries a distinct payload; the first sentence is long but earns its length by packing scope, dimension, and default behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 10-parameter, all-optional aggregation tool with a full output schema and supporting annotations, the description supplies the key interpretive context (unit mixing, default stage split, code decoding). Nothing critical is missing, though it does not touch on the clamping/disclosure mechanics that an agent would only learn from the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all ten parameters in detail (clamping, expand rejection rules, ISO3 rewriting, enum codes). The description reinforces the default stage split and code-decoding path but adds little syntax or format meaning beyond what the schema states; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get asylum applications lodged per year'), gives the temporal scope (2000 to latest), and names the two filterable dimensions (origin and/or asylum). An agent can distinguish this from the sibling unhcr_get_asylum_decisions purely from the description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the default splitting behavior and routes to unhcr_list_reference (topic asylum_codes) for decoding stage/authority/decision-level codes, which is actionable context. It does not, however, explicitly say when to prefer this tool over unhcr_get_asylum_decisions or unhcr_get_demographics, so the guidance is clear but not exclusionary.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unhcr_get_asylum_decisionsUNHCR asylum decisionsA
Read-onlyIdempotent
Inspect

Get asylum decisions per year (2000 to the latest year) by country of origin and/or asylum: recognized as refugees, complementary protection, rejected, and otherwise closed, with UNHCR's Refugee Recognition Rate and Total Protection Rate computed over substantive decisions (otherwise-closed cases excluded). By default all decision levels are summed and each row lists the levels it includes; appeal-stage decisions can concern people already decided at first instance, so split_by decision_level or filter decision_levels to FI for first-instance rates. Cases and persons are never added together.

NameRequiredDescriptionDefault
limitNoRequested inline rows, 1–1000000 (default 100); values above 500 are clamped to 500 with disclosure. Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled.
stageNoStage the full result as a dataframe even when it fits inline, e.g. to join it with another unhcr_get_* result in unhcr_dataframe_query. Where dataframes are unavailable it is ignored, and the notice says so.
asylumNoCountry of asylum — where people sought or hold protection; for returns, the country they returned from — as ISO3 codes (DEU, TUR), case-insensitive, same rules as origin. At most 50 codes. Omit to sum every asylum country into one row, or set expand to list each.
expandNoList every country, one row each, for a dimension that origin or asylum leaves unfiltered: origin, asylum, or both. Default none, where an unfiltered dimension is summed into one row. Expanding a dimension that origin or asylum already filters is rejected.none
originNoCountry of origin — where people fled from — as ISO3 codes (SYR, AFG), case-insensitive. ISO 3166 alpha-2 codes (SY) are rewritten to ISO3 and echoed in applied_scope. UNHCR's own codes (GFR) are rejected with the ISO3 to pass instead, and country names are rejected: resolve a name with unhcr_list_reference (topic countries, name_contains). Each listed code returns its own rows; codes are never summed together. At most 50 codes. Omit to sum every origin into one row, or set expand to list each.
sort_byNoOrder of the full result before the inline cut. year (default) orders by year, then origin ISO3, then asylum ISO3; a count field orders largest first, nulls last. Rates are not sortable, since rates on small rounded counts would crowd the top.year
year_toNoLast year of the window. When omitted, the window runs to the latest published year (latest_year in the result). A year past the latest published year is clamped to it and the clamp is reported.
split_byNoProcedure dimensions kept as separate rows: authority (government, UNHCR, or joint) and decision_level (first instance, administrative review, …). Every dimension left out is summed. Default [] sums all authorities and levels, as UNHCR does for its rates. Unit is always kept separate.
year_fromNoFirst year of the window. When omitted, the window starts at the dataset's first year. A year before the dataset's first year is clamped to it and the clamp is reported; a window entirely outside the dataset's years is rejected.
decision_levelsNoKeep only these decision levels before summing, case-insensitive: NA new applications, FI first instance, AR administrative review, RA repeat/reopened, IN US Citizenship and Immigration Services, EO US Executive Office for Immigration Review, JR judicial review, SP subsidiary protection, FA first instance and appeal, TP temporary protection, TA temporary asylum, BL backlog, TR temporary leave to remain, CA cantonal regulations (Switzerland). ["FI"] gives first-instance decisions. Omit for every level.

Output Schema

NameRequiredDescription
capNoThe limit that was applied.
rowsNoInline rows, sorted, up to limit.
errorNoPresent when the call failed. Absent on success.
shownNoRows returned inline.
noticeNoGuidance for this result: empty-result hints, year clamps, where the full set was staged, or how to narrow.
datasetNoPresent when the full result was staged as a dataframe; read its columns with unhcr_dataframe_describe, then query it with unhcr_dataframe_query.
measureNostock: people in a situation on 31 December; flow: events during the year.
completeNoFalse when the server row cap stopped the upstream fetch; the notice says how many upstream rows were fetched and how to narrow.
truncatedNoTrue when rows were cut at limit.
data_notesNoHow to read the counts: stock or flow, rounding, the meaning of null, caveats.
total_rowsNoRows in the full result before the inline cut. When complete is false, the result is built from only the upstream rows fetched before the cap, so rows and summed counts can fall short of the complete result.
attributionNoAttribution UNHCR requires when these figures are reused.
latest_yearNoNewest year this dataset publishes.
applied_scopeNoThe scope actually sent upstream, including clamped years and code rewrites.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, openWorld). The description adds substantive behavioral context beyond them: rates are computed over substantive decisions with otherwise-closed cases excluded, all decision levels are summed by default with each row listing its levels, and cases vs persons are never combined. This materially helps correct interpretation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the resource and scope, then defaults and the important caveat. Dense but every sentence earns its place; the multi-clause sentences are slightly heavy but not wasteful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need no explanation. The description supplies the defaults, the rate-computation caveat, and the splitting nuance an agent needs to call this correctly, though pagination/limit behavior is left entirely to the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaning the schema does not: the default summing of decision levels, the risk that appeal-stage rows double-count, and the interplay of split_by/decision_levels for first-instance rates. It does not walk through each parameter, but it enriches the most consequential ones.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get asylum decisions per year ... by country of origin and/or asylum') and enumerates the decision categories returned, plus the derived rates. An agent can tell this apart from siblings like unhcr_get_asylum_applications without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete conditional guidance: use split_by decision_level or filter decision_levels to FI to get first-instance rates, and notes that appeal-stage decisions overlap with first-instance populations. Does not explicitly name sibling tools or exclusions, but the when-to-use context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unhcr_get_demographicsUNHCR demographicsA
Read-onlyIdempotent
Inspect

Get UNHCR year-end stocks (2001 to the latest year) broken down by population type, sex, and age band (0–4, 5–11, 12–17, 18–59, 60+, unknown age), by country of origin and/or asylum. Coverage is partial: each row gives the share of its total that UNHCR could disaggregate by sex, and age bands are null where no breakdown exists. These totals come from a separate collection and need not match unhcr_get_population.

NameRequiredDescriptionDefault
limitNoRequested inline rows, 1–1000000 (default 100); values above 500 are clamped to 500 with disclosure. Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled.
stageNoStage the full result as a dataframe even when it fits inline, e.g. to join it with another unhcr_get_* result in unhcr_dataframe_query. Where dataframes are unavailable it is ignored, and the notice says so.
asylumNoCountry of asylum — where people sought or hold protection; for returns, the country they returned from — as ISO3 codes (DEU, TUR), case-insensitive, same rules as origin. At most 50 codes. Omit to sum every asylum country into one row, or set expand to list each.
expandNoList every country, one row each, for a dimension that origin or asylum leaves unfiltered: origin, asylum, or both. Default none, where an unfiltered dimension is summed into one row. Expanding a dimension that origin or asylum already filters is rejected.none
originNoCountry of origin — where people fled from — as ISO3 codes (SYR, AFG), case-insensitive. ISO 3166 alpha-2 codes (SY) are rewritten to ISO3 and echoed in applied_scope. UNHCR's own codes (GFR) are rejected with the ISO3 to pass instead, and country names are rejected: resolve a name with unhcr_list_reference (topic countries, name_contains). Each listed code returns its own rows; codes are never summed together. At most 50 codes. Omit to sum every origin into one row, or set expand to list each.
sort_byNoOrder of the full result before the inline cut. year (default) orders by year, then origin ISO3, then asylum ISO3, then population type; total orders largest first, nulls last.year
year_toNoLast year of the window. When omitted, the window runs to the latest published year (latest_year in the result). A year past the latest published year is clamped to it and the clamp is reported.
year_fromNoFirst year of the window. When omitted, the window starts at the dataset's first year. A year before the dataset's first year is clamped to it and the clamp is reported; a window entirely outside the dataset's years is rejected.
population_typesNoKeep only these population types, case-insensitive: REF refugees, ASY asylum-seekers, OIP other people in need of international protection, IDP internally displaced, STA stateless, OOC others of concern, HST host community, RET returned refugees, RDP returned IDPs. Decode them with unhcr_list_reference (topic population_types). Omit for every type.

Output Schema

NameRequiredDescription
capNoThe limit that was applied.
rowsNoInline rows, sorted, up to limit.
errorNoPresent when the call failed. Absent on success.
shownNoRows returned inline.
noticeNoGuidance for this result: empty-result hints, year clamps, where the full set was staged, or how to narrow.
datasetNoPresent when the full result was staged as a dataframe; read its columns with unhcr_dataframe_describe, then query it with unhcr_dataframe_query.
measureNostock: people in a situation on 31 December; flow: events during the year.
completeNoFalse when the server row cap stopped the upstream fetch; the notice says how many upstream rows were fetched and how to narrow.
footnotesNoUNHCR caveats matching rows of the full result, country-specific first; at most 20.
truncatedNoTrue when rows were cut at limit.
data_notesNoHow to read the counts: stock or flow, rounding, the meaning of null, caveats.
total_rowsNoRows in the full result before the inline cut. When complete is false, the result is built from only the upstream rows fetched before the cap, so rows and summed counts can fall short of the complete result.
attributionNoAttribution UNHCR requires when these figures are reused.
latest_yearNoNewest year this dataset publishes.
applied_scopeNoThe scope actually sent upstream, including clamped years and code rewrites.
footnotes_totalNoCaveats matching the full result, before the cap.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/idempotent annotations, the description discloses substantive behavioral traits: coverage is partial, each row carries the share of its total that UNHCR could disaggregate by sex, age bands are null where no breakdown exists, and the figures may diverge from a sibling data source. These caveats materially affect interpretation of results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tightly packed sentences, front-loaded with what the tool returns, then coverage caveats, then the cross-tool reconciliation warning. No sentence is filler and each adds decision-relevant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is not the description's burden. For a 9-parameter, all-optional read tool, the description supplies the critical interpretation context (partial disaggregation, null age bands, provenance mismatch) that an agent needs to use results correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents every parameter including code formats, expand semantics, clamping, and sorting. The description adds the year-window origin (2001) and the age-band cohorts, but no syntax or behavior beyond the schema, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete verb and resource (year-end stocks) plus the exact disaggregation dimensions (population type, sex, age band) and the geographic axes (origin and/or asylum), with the time span (2001 to latest). It explicitly names the sibling unhcr_get_population as a distinct data source, so an agent can separate the two without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context for what the tool is for and warns that its totals come from a separate collection and may not reconcile with unhcr_get_population, which helps an agent choose between them. It stops short of an explicit 'use X instead when you want whole-population totals' rule, so the alternative selection is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unhcr_get_populationUNHCR displacement stocksA
Read-onlyIdempotent
Inspect

Get UNHCR year-end displacement stocks (1951 to the latest year) by country of origin and/or asylum: refugees, asylum-seekers, other people in need of international protection, IDPs, stateless people, others of concern, and host communities, plus refugees and IDPs who returned during the year. Stocks count people in a situation on 31 December, not arrivals. Palestine refugees under UNRWA's mandate and IDMC's conflict-IDP estimate are separate series shown beside each row. Set include_nowcast for UNHCR's current-year estimate by asylum country; for sex and age breakdowns, use unhcr_get_demographics.

NameRequiredDescriptionDefault
limitNoRequested inline rows, 1–1000000 (default 100); values above 500 are clamped to 500 with disclosure. Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled.
stageNoStage the full result as a dataframe even when it fits inline, e.g. to join it with another unhcr_get_* result in unhcr_dataframe_query. Where dataframes are unavailable it is ignored, and the notice says so.
asylumNoCountry of asylum — where people sought or hold protection; for returns, the country they returned from — as ISO3 codes (DEU, TUR), case-insensitive, same rules as origin. At most 50 codes. Omit to sum every asylum country into one row, or set expand to list each.
expandNoList every country, one row each, for a dimension that origin or asylum leaves unfiltered: origin, asylum, or both. Default none, where an unfiltered dimension is summed into one row. Expanding a dimension that origin or asylum already filters is rejected.none
originNoCountry of origin — where people fled from — as ISO3 codes (SYR, AFG), case-insensitive. ISO 3166 alpha-2 codes (SY) are rewritten to ISO3 and echoed in applied_scope. UNHCR's own codes (GFR) are rejected with the ISO3 to pass instead, and country names are rejected: resolve a name with unhcr_list_reference (topic countries, name_contains). Each listed code returns its own rows; codes are never summed together. At most 50 codes. Omit to sum every origin into one row, or set expand to list each.
sort_byNoOrder of the full result before the inline cut. year (default) orders by year, then origin ISO3, then asylum ISO3; a count field orders largest first, nulls last.year
year_toNoLast year of the window. When omitted, the window runs to the latest published year (latest_year in the result). A year past the latest published year is clamped to it and the clamp is reported.
year_fromNoFirst year of the window. When omitted, the window starts at the dataset's first year. A year before the dataset's first year is clamped to it and the clamp is reported; a window entirely outside the dataset's years is rejected.
include_nowcastNoAppend UNHCR's latest monthly estimate of refugees and asylum-seekers by asylum country: one current-year snapshot, independent of the year window. The nowcast has no origin dimension, so it is skipped when origin lists codes. When origin lists no codes, a window entirely after the latest published year returns the nowcast alone instead of failing.

Output Schema

NameRequiredDescription
capNoThe limit that was applied.
rowsNoInline rows, sorted, up to limit.
errorNoPresent when the call failed. Absent on success.
shownNoRows returned inline.
noticeNoGuidance for this result: empty-result hints, year clamps, where the full set was staged, or how to narrow.
datasetNoPresent when the full result was staged as a dataframe; read its columns with unhcr_dataframe_describe, then query it with unhcr_dataframe_query.
measureNostock: people in a situation on 31 December; flow: events during the year.
nowcastNoPresent when include_nowcast was set and origin lists no codes.
completeNoFalse when the server row cap stopped the upstream fetch; the notice says how many upstream rows were fetched and how to narrow.
footnotesNoUNHCR caveats matching rows of the full result, country-specific first; at most 20.
truncatedNoTrue when rows were cut at limit.
data_notesNoHow to read the counts: stock or flow, rounding, the meaning of null, caveats.
total_rowsNoRows in the full result before the inline cut. When complete is false, the result is built from only the upstream rows fetched before the cap, so rows and summed counts can fall short of the complete result.
attributionNoAttribution UNHCR requires when these figures are reused.
latest_yearNoNewest year this dataset publishes.
applied_scopeNoThe scope actually sent upstream, including clamped years and code rewrites.
footnotes_totalNoCaveats matching the full result, before the cap.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only/idempotent, and the description adds genuinely non-obvious semantics: stocks count people in a situation on 31 December rather than arrivals, UNRWA and IDMC series appear as separate columns beside each row, and nowcast is a current-year snapshot independent of the year window. These are behaviors an agent could not infer from the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the resource and its scope before moving to caveats and sibling routing. It is a dense paragraph rather than a list, but nearly every clause carries distinct semantic information (stocks-vs-flows, separate series, nowcast, demographics alternative).

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 9 optional parameters, an output schema, and full annotation coverage, the description supplies exactly the missing pieces: what the counts mean, which series are bundled in, and which sibling to use for demographic breakdowns. Return values are covered by the output schema, so nothing essential is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3; the description still adds meaning by explaining what include_nowcast produces ('UNHCR's current-year estimate by asylum country') and that an unfiltered dimension is summed unless expanded. It does not elaborate on limit/stage/sort_by beyond the schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('Get UNHCR year-end displacement stocks') and enumerates exactly which series are covered (refugees, asylum-seekers, OIP, IDPs, stateless, OOC, host communities, returns). It also distinguishes itself from siblings by naming unhcr_get_demographics as the tool for sex/age breakdowns.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit routing rule: 'for sex and age breakdowns, use unhcr_get_demographics', plus a conditional usage hint for include_nowcast. It does not address overlap with other count-oriented siblings like unhcr_get_solutions or unhcr_get_asylum_applications, so it falls short of full when/when-not coverage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unhcr_get_solutionsUNHCR durable solutionsA
Read-onlyIdempotent
Inspect

Get durable solutions per year (1959 to the latest year) by country of origin and/or asylum: refugees who returned home, refugees resettled to a third country, refugees naturalised, and IDPs who returned. The asylum country means something different per column: the country refugees returned from, the country they were resettled to, the country that naturalised them; IDP returns sit on the origin country itself. Null means the figure was not collected for that country and year, not zero.

NameRequiredDescriptionDefault
limitNoRequested inline rows, 1–1000000 (default 100); values above 500 are clamped to 500 with disclosure. Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled.
stageNoStage the full result as a dataframe even when it fits inline, e.g. to join it with another unhcr_get_* result in unhcr_dataframe_query. Where dataframes are unavailable it is ignored, and the notice says so.
asylumNoCountry of asylum — where people sought or hold protection; for returns, the country they returned from — as ISO3 codes (DEU, TUR), case-insensitive, same rules as origin. At most 50 codes. Omit to sum every asylum country into one row, or set expand to list each.
expandNoList every country, one row each, for a dimension that origin or asylum leaves unfiltered: origin, asylum, or both. Default none, where an unfiltered dimension is summed into one row. Expanding a dimension that origin or asylum already filters is rejected.none
originNoCountry of origin — where people fled from — as ISO3 codes (SYR, AFG), case-insensitive. ISO 3166 alpha-2 codes (SY) are rewritten to ISO3 and echoed in applied_scope. UNHCR's own codes (GFR) are rejected with the ISO3 to pass instead, and country names are rejected: resolve a name with unhcr_list_reference (topic countries, name_contains). Each listed code returns its own rows; codes are never summed together. At most 50 codes. Omit to sum every origin into one row, or set expand to list each.
sort_byNoOrder of the full result before the inline cut. year (default) orders by year, then origin ISO3, then asylum ISO3; a count field orders largest first, nulls last.year
year_toNoLast year of the window. When omitted, the window runs to the latest published year (latest_year in the result). A year past the latest published year is clamped to it and the clamp is reported.
year_fromNoFirst year of the window. When omitted, the window starts at the dataset's first year. A year before the dataset's first year is clamped to it and the clamp is reported; a window entirely outside the dataset's years is rejected.

Output Schema

NameRequiredDescription
capNoThe limit that was applied.
rowsNoInline rows, sorted, up to limit.
errorNoPresent when the call failed. Absent on success.
shownNoRows returned inline.
noticeNoGuidance for this result: empty-result hints, year clamps, where the full set was staged, or how to narrow.
datasetNoPresent when the full result was staged as a dataframe; read its columns with unhcr_dataframe_describe, then query it with unhcr_dataframe_query.
measureNostock: people in a situation on 31 December; flow: events during the year.
completeNoFalse when the server row cap stopped the upstream fetch; the notice says how many upstream rows were fetched and how to narrow.
footnotesNoUNHCR caveats matching rows of the full result, country-specific first; at most 20.
truncatedNoTrue when rows were cut at limit.
data_notesNoHow to read the counts: stock or flow, rounding, the meaning of null, caveats.
total_rowsNoRows in the full result before the inline cut. When complete is false, the result is built from only the upstream rows fetched before the cap, so rows and summed counts can fall short of the complete result.
attributionNoAttribution UNHCR requires when these figures are reused.
latest_yearNoNewest year this dataset publishes.
applied_scopeNoThe scope actually sent upstream, including clamped years and code rewrites.
footnotes_totalNoCaveats matching the full result, before the cap.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnly/idempotent/openWorld, so the safety profile is covered. The description adds genuinely useful behavioral context beyond that: the coverage window (1959 to latest), the per-column meaning of the asylum dimension, and the critical null-vs-zero semantics. It does not mention pagination/clamping or rate limits, but the important semantic traps are disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, no filler; the scope and the four measures are front-loaded, followed by the two highest-risk clarifications (asylum column semantics, null vs zero). Every sentence carries information an agent would otherwise have to guess.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema, 100% parameter coverage, and read-only annotations, the description only needs to resolve domain traps — and it does: the per-column asylum semantics and null-not-zero convention are the two most likely sources of misinterpretation. Nothing essential for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so baseline is 3, but the description adds real meaning by explaining that 'asylum country' denotes a different country per measure (returned-from, resettlement destination, naturalising country, IDP return on origin) — a semantic distinction the schema only partially implies. It does not elaborate on expand/sort_by/stage behavior, which stays in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get durable solutions per year ... by country of origin and/or asylum') and enumerates the four measure columns (returned refugees, resettlement, naturalisation, returned IDPs), which implicitly but clearly separates it from siblings like unhcr_get_population, unhcr_get_asylum_applications, and unhcr_get_demographics. An agent can tell what data this returns without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description never states when to choose this tool over alternatives or what conditions make it the right call. Routing hints (resolve names via unhcr_list_reference, join via unhcr_dataframe_query) exist only in the parameter schema, not the description, so the description itself offers no usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unhcr_list_referenceUNHCR reference vocabularyA
Read-onlyIdempotent
Inspect

Decode the vocabulary the unhcr_* tools take as input: countries (ISO3, ISO2, UNHCR code, names, UNHCR and UN regions), UNHCR’s regional bureaus, each dataset’s first and latest year, population-type definitions, and the asylum authority, stage, decision-level, and unit codes. Filter countries with name_contains to turn a country name into the ISO3 code that origin and asylum take.

NameRequiredDescriptionDefault
topicYescountries: every queryable country with its codes, names, and regions. regions: UNHCR's regional bureaus. coverage: first and latest year of each dataset, plus the current nowcast month. population_types: what each population type counts and which output column carries it. asylum_codes: asylum authority, application stage, decision level, and unit codes.
name_containsNoFor topic countries only: keep countries whose names, in UNHCR’s English spelling, contain every word given, ignoring case, accents, and punctuation, or whose ISO3, ISO2, or UNHCR code equals a word ("syria", "turkiye", "britain", "deu"). Words match every name variant UNHCR records, including short and formal names the output does not list. No fuzzy matching.

Output Schema

NameRequiredDescription
errorNoPresent when the call failed. Absent on success.
topicNoThe topic returned.
noticeNoGuidance when name_contains matched nothing or does not apply to the topic.
nowcastNoPresent for topic coverage: the single current-year estimate unhcr_get_population's include_nowcast returns.
regionsNoPresent for topic regions.
coverageNoPresent for topic coverage.
countriesNoPresent for topic countries, sorted by name.
totalCountNoCountries returned, after any name_contains filter.
asylum_codesNoPresent for topic asylum_codes.
population_typesNoPresent for topic population_types.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the safety profile is covered. The description adds content-scope context (what vocabulary is decoded) but no behavioral detail such as caching, latency, or result completeness beyond the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the purpose and followed by the practical name_contains use case. Dense but every clause maps to a covered topic or usage instruction; no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return-value detail is unnecessary, and the description covers the topic space and the code-conversion use case. Adequate for a reference-lookup tool, though it could note whether results are static or refreshed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the nested enum descriptions already document each topic exhaustively. The description echoes the topic list and mentions name_contains' role, adding only a light usage hint over what the schema provides, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Decode') and resource ('the vocabulary the unhcr_* tools take as input'), then enumerates exactly what it returns: countries/codes, regional bureaus, dataset year coverage, population types, and asylum codes. This clearly distinguishes it from the data-returning siblings like unhcr_get_population or unhcr_get_asylum_applications.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete usage path: 'Filter countries with name_contains to turn a country name into the ISO3 code that origin and asylum take,' which tells the agent why it would call this before other tools. It stops short of explicitly stating when NOT to use it or naming a sibling as an alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

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

  1. 7 tool updates
    • Changedunhcr_dataframe_describe2 fields changed
      • addedOutput schema / properties / dataframes / items / properties / incomplete_sources
        Added value: +{
        +  "description": "Original incomplete upstream handles retained through saved descendants, even after those ancestors expire or are evicted.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • changedOutput schema / properties / dataframes / items / required
        Previous value: -[
        -  "name",
        -  "source_tool",
        -  "query_params",
        -  "created_at",
        -  "expires_at",
        -  "row_count",
        -  "complete",
        -  "providers",
        -  "column_schema"
        -]New value: +[
        +  "name",
        +  "source_tool",
        +  "query_params",
        +  "created_at",
        +  "expires_at",
        +  "row_count",
        +  "complete",
        +  "incomplete_sources",
        +  "providers",
        +  "column_schema"
        +]
    • Changedunhcr_dataframe_query9 fields changed
      • changedInput schema / properties / preview / description
        Previous value: -"Rows to return inline when that should be fewer than the query materializes, e.g. a small sample while register_as keeps the whole result; a value above row_limit is treated as row_limit. Omit to return every row up to row_limit."New value: +"Requested inline rows, 0–1000000. Values above row_limit are clamped to row_limit with disclosure. Omit to return every row up to row_limit; the serialized byte ceiling may withhold whole rows or metadata, preserving the result as lossless chunks."
      • changedInput schema / properties / preview / maximum
        Previous value: -10000New value: +1000000
      • changedOutput schema / anyOf
        Previous value: -[
        -  {
        -    "not": {
        -      "required": [
        -        "error"
        -      ]
        -    },
        -    "required": [
        -      "columns",
        -      "row_count",
        -      "row_count_capped",
        -      "rows",
        -      "attribution"
        -    ]
        -  },
        -  {
        -    "required": [
        -      "error"
        -    ]
        -  }
        -]New value: +[
        +  {
        +    "not": {
        +      "required": [
        +        "error"
        +      ]
        +    },
        +    "required": [
        +      "complete",
        +      "incomplete_sources",
        +      "columns",
        +      "row_count",
        +      "row_count_capped",
        +      "rows",
        +      "attribution"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "error"
        +    ]
        +  }
        +]
      • addedOutput schema / properties / complete
        Added value: +{
        +  "description": "False when any original source fetch was incomplete, independently of display truncation.",
        +  "type": "boolean"
        +}
      • changedOutput schema / properties / error / properties / data / properties / reason / description
        Previous value: -"Machine-readable failure mode. Declared by this tool: `canvas_unavailable`: Dataframes are turned off in this deployment, or the SQL engine behind them could not load. `missing_table`: A df_<id> the SQL names is not staged: it never existed, its TTL expired, or it was evicted to make room for newer dataframes. `invalid_sql`: A statement starting with SELECT, WITH, or FROM does not parse, or the SELECT fails to prepare: an unknown column, table, or function, or an invalid expression. `sql_execution_error`: The SELECT prepared but failed on the data it read: a cast or conversion that does not fit, an out-of-range value, or invalid input to a function. `register_as_clash`: The register_as name is already a staged dataframe. `register_as_too_large`: The register_as result alone holds more rows than the 1,000,000-row staging budget, so it was not saved. `non_select_statement`: The statement is not a read-only SELECT: an INSERT, UPDATE, DDL, PRAGMA, or other write the engine refuses, or SQL that fails to parse and does not start with SELECT, WITH, or FROM (such as a misspelled SELEC). `multi_statement`: The SQL holds more than one statement. `denied_function`: The SQL calls a file-reading or external-data table function such as read_csv, read_parquet, or glob. `plan_operator_not_allowed`: The query plan uses an operator outside the read-only allowlist, such as the range() or generate_series() table functions. `system_catalog_access`: The SQL references a system catalog (information_schema, pg_catalog, sqlite_master, duckdb_*). Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `result_storage_unavailable`: The lossless result snapshot cannot be retained within the staging budget or storage fails. `canvas_unavailable`: Dataframes are turned off in this deployment, or the SQL engine behind them could not load. `missing_table`: A df_<id> the SQL names is not staged: it never existed, its TTL expired, or it was evicted to make room for newer dataframes. `invalid_sql`: A statement starting with SELECT, WITH, or FROM does not parse, or the SELECT fails to prepare: an unknown column, table, or function, or an invalid expression. `sql_execution_error`: The SELECT prepared but failed on the data it read: a cast or conversion that does not fit, an out-of-range value, or invalid input to a function. `register_as_clash`: The register_as name is already a staged dataframe. `register_as_too_large`: The register_as result alone holds more rows than the 1,000,000-row staging budget, so it was not saved. `non_select_statement`: The statement is not a read-only SELECT: an INSERT, UPDATE, DDL, PRAGMA, or other write the engine refuses, or SQL that fails to parse and does not start with SELECT, WITH, or FROM (such as a misspelled SELEC). `multi_statement`: The SQL holds more than one statement. `denied_function`: The SQL calls a denied external-data or introspection function, uses query_table, or passes query() anything other than a single SQL string literal. `plan_operator_not_allowed`: The query plan uses an operator outside the read-only allowlist, such as the range() or generate_series() table functions. `system_catalog_access`: The SQL references a system catalog (information_schema, pg_catalog, sqlite_master, duckdb_*). Other values are possible when a failure originates below the handler."
      • changedOutput schema / properties / error / properties / data / properties / reason / examples
        Previous value: -[
        -  "canvas_unavailable",
        -  "missing_table",
        -  "invalid_sql",
        -  "sql_execution_error",
        -  "register_as_clash",
        -  "register_as_too_large",
        -  "non_select_statement",
        -  "multi_statement",
        -  "denied_function",
        -  "plan_operator_not_allowed",
        -  "system_catalog_access"
        -]New value: +[
        +  "result_storage_unavailable",
        +  "canvas_unavailable",
        +  "missing_table",
        +  "invalid_sql",
        +  "sql_execution_error",
        +  "register_as_clash",
        +  "register_as_too_large",
        +  "non_select_statement",
        +  "multi_statement",
        +  "denied_function",
        +  "plan_operator_not_allowed",
        +  "system_catalog_access"
        +]
      • addedOutput schema / properties / incomplete_sources
        Added value: +{
        +  "description": "Original incomplete upstream dataframe handles; retained through saved descendants. If metadata_withheld is true, consult the result snapshot for the full list.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / metadata_withheld
        Added value: +{
        +  "description": "True when oversized column names or incomplete-source metadata are withheld inline and retained in result_chunks.",
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / result_chunks
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Lossless materialized result snapshot when the byte ceiling withholds rows or metadata.",
        +  "properties": {
        +    "chunk_count": {
        +      "description": "Chunks numbered from zero, with at most 6144 source bytes each.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "encoding": {
        +      "const": "base64-json-utf8",
        +      "description": "Decode each base64 chunk, concatenate bytes in index order, then decode UTF-8 and JSON.",
        +      "type": "string"
        +    },
        +    "expires_at": {
        +      "description": "ISO 8601 expiry of the chunk dataframe.",
        +      "type": "string"
        +    },
        +    "name": {
        +      "description": "Tenant-scoped dataframe holding chunk_index and base64 chunk columns.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "name",
        +    "encoding",
        +    "chunk_count",
        +    "expires_at"
        +  ],
        +  "type": "object"
        +}
    • Changedunhcr_get_asylum_applications2 fields changed
      • changedInput schema / properties / limit / description
        Previous value: -"Rows returned inline, 1–500 (default 100). Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled."New value: +"Requested inline rows, 1–1000000 (default 100); values above 500 are clamped to 500 with disclosure. Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled."
      • changedInput schema / properties / limit / maximum
        Previous value: -500New value: +1000000
    • Changedunhcr_get_asylum_decisions2 fields changed
      • changedInput schema / properties / limit / description
        Previous value: -"Rows returned inline, 1–500 (default 100). Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled."New value: +"Requested inline rows, 1–1000000 (default 100); values above 500 are clamped to 500 with disclosure. Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled."
      • changedInput schema / properties / limit / maximum
        Previous value: -500New value: +1000000
    • Changedunhcr_get_demographics2 fields changed
      • changedInput schema / properties / limit / description
        Previous value: -"Rows returned inline, 1–500 (default 100). Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled."New value: +"Requested inline rows, 1–1000000 (default 100); values above 500 are clamped to 500 with disclosure. Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled."
      • changedInput schema / properties / limit / maximum
        Previous value: -500New value: +1000000
    • Changedunhcr_get_population2 fields changed
      • changedInput schema / properties / limit / description
        Previous value: -"Rows returned inline, 1–500 (default 100). Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled."New value: +"Requested inline rows, 1–1000000 (default 100); values above 500 are clamped to 500 with disclosure. Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled."
      • changedInput schema / properties / limit / maximum
        Previous value: -500New value: +1000000
    • Changedunhcr_get_solutions2 fields changed
      • changedInput schema / properties / limit / description
        Previous value: -"Rows returned inline, 1–500 (default 100). Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled."New value: +"Requested inline rows, 1–1000000 (default 100); values above 500 are clamped to 500 with disclosure. Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled."
      • changedInput schema / properties / limit / maximum
        Previous value: -500New value: +1000000
  2. 8 tool updates
    • First observedunhcr_dataframe_describe
    • First observedunhcr_dataframe_query
    • First observedunhcr_get_asylum_applications
    • First observedunhcr_get_asylum_decisions
    • First observedunhcr_get_demographics
    • First observedunhcr_get_population
    • First observedunhcr_get_solutions
    • First observedunhcr_list_reference

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Enables querying and analyzing humanitarian data, such as refugee statistics, through semantic tools like country comparisons, trend analysis, and report generation, using the UNHCR API.
    21
    25 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to query keyless UNHCR statistics on forcibly displaced and stateless persons, including refugees, asylum seekers, IDPs, and returnees, plus asylum applications and decisions, filtered by year, country of origin, or country of asylum, with a country-code lookup for resolving UNHCR codes. It can be reached through the hosted Pipeworx gateway or run locally over stdio.
    7 npm
    MIT
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.