Walkthrough A: an indicator for one place
The first research pattern, run for real: what is the total population of Rwanda over
time? Every cell on this page is executed against the live MCP server when the site
is built, so the numbers are what the server returned at build time (see the
release’s version.json for when that was). The pattern is the general playbook’s:
discover → assess → retrieve.
import sys
from pathlib import Path
sys.path.insert(0, str(Path.cwd().parents[1])) # the book's own MCP client
from plugins.mcp_client import McpClient, call_tool
from plugins import walkthrough as wt
client = McpClient()
client.initialize()["serverInfo"]Output
{'name': 'DC MCP Server', 'version': '1.3.0'}1. Discover: search_indicators¶
One concept, qualified with the place we care about. The playbook says to search one semantic concept at a time and to treat the results as candidates, not answers.
found = call_tool(
client,
"search_indicators",
query="total population",
places=["Rwanda"],
include_topics=False,
per_search_limit=10,
)
wt.candidates(found)The results are UNICEF’s population series for Rwanda, in several age and sex
breakdowns. The headline series is undata/unicef/DM_POP, Total population; we
proceed with that DCID explicitly rather than with “the first result”, because result
order is not a contract. It is also an identifier the search returned, not one typed
from memory, which is the first of the research rules.
2. Assess: get_variable_metadata¶
Before pulling a time series, check what it is: which source publishes it, over what dates, how many observations, in what unit.
variable = "undata/unicef/DM_POP"
meta = call_tool(client, "get_variable_metadata", variable_dcids=[variable], entity_dcids=["country/RWA"])
wt.facets(meta, variable)One facet: a single source series, so there is no choice of provenance to make here.
When a variable has several facets, this is the table you choose from; the facet
column is the id that source_override takes in the next step.
3. Retrieve: get_observations¶
The default is the latest value; date="all" asks for the whole series.
obs = call_tool(client, "get_observations", variable_dcid=variable, place_dcid="country/RWA", date="all")
series = wt.observations(obs)
series.tail(8)first, last = series.index[0], series.index[-1]
print(f"{len(series)} observations from {first} to {last}; "
f"source {obs['sourceMetadata']['provenanceUrl']} ({obs['sourceMetadata']['observationPeriod']})")26 observations from 2000 to 2025; source https://data.unicef.org/ (P1Y)
That is the whole single-place pattern: three tool calls, each answering a different question — which variable, how good is it, what are the values. The other two patterns change the middle and the end of that sequence, not its shape.