Skip to main content
Glama
MapleStats MCP

MapleStats MCP

MapleStats MCP gives AI agents (Claude, Cursor and any MCP client) typed access to Canadian open data through one server: Statistics Canada (tables, Census, public use microdata), the Bank of Canada, CMHC, federal agencies, and federal, provincial, territorial and municipal open-data portals, in English and French. Every result carries its source.

MapleStats MCP donne aux agents IA un accès structuré aux données ouvertes canadiennes par un seul serveur, en français et en anglais.

Why MapleStats

Built by a statistician, for anyone who works with the numbers: economists, demographers, policy analysts, researchers, journalists, students, anyone who needs a Canadian figure they can trust and cite. MapleStats is designed around the mistakes people actually make with official data, and we test it against other tools on public benchmarks: see how it does.

  • It knows the traps. Constant vs current dollars, family vs individual income, annual average vs December over December, survey rent vs listing rent: it warns in plain language, and each fitness-for-use caution rests on the publisher's own documentation.

  • Every number names its source: every StatCan series carries a citation (table, vector, release date, with the period, unit, geography and a link to the official table); every other result names its source and licence.

  • It says when data do not exist. A series that is not published, a period not released yet or a date with no data gets a plain no, and the nearest figure that does exist.

  • The answer can be checked. Before replying, the assistant can send the StatCan and Bank of Canada figures it cites to check_answer, which re-reads them from the source.

  • Your work stays reproducible. It writes the R, Python, Stata or Julia script, or the Excel query, that pulls the same data from the source.

  • Quality flags and revisions, shown: "use with caution", "too unreliable to be published", preliminary and revised are spelled out on every StatCan value.

  • It only reads, in English and French. The server only reads from public sources. The scripts it writes run only if you run them (the full-table ones then save the download under data/raw/), and saving a workbook to disk is opt-in (MAPLE_EXPORT_DIR, on a local server).

Project vision: docs/PROJECT_GUIDE.md. Source coverage: docs/ROADMAP.md. Website: https://maplestats.danielstats.io/.

Related MCP server: mcp-statscan

The easiest way: ask your agent

  1. Copy this prompt.

  2. Paste it into Claude Code, Codex, Cursor or any agent that can run commands on your computer.

  3. Restart the agent when it says so, then ask for data.

Connect the MapleStats MCP server to this agent. Follow the setup steps in https://github.com/dsanchezp18/maplestats-mcp

Instructions for the agent doing the setup

The default is the hosted server: nothing to install, no account, no key.

  1. Register this remote (HTTP) MCP server under the name maplestats:

    • Claude Code: claude mcp add --transport http --scope user maplestats https://mcp.maplestats.danielstats.io/mcp

    • Codex CLI: codex mcp add maplestats --url https://mcp.maplestats.danielstats.io/mcp

    • Cursor, Claude Desktop and other mcpServers clients: add the entry below to the client's config file (Cursor: ~/.cursor/mcp.json; Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows), keeping any servers already there.

    • claude.ai and the Claude phone app: on the web, open Settings → Connectors → Add custom connector, name it MapleStats, and enter https://mcp.maplestats.danielstats.io/mcp. Then switch it on from the tools menu in a chat, on the web or in the phone app. Claude asks for approval before each call by default; every tool is read-only, so set them to always allow in the connector's tool permissions.

    • ChatGPT (web): turn on Settings → Security and login → Developer mode, then create a developer-mode app for a remote MCP server with the same address and No Authentication. Every tool is read-only, so ChatGPT should not ask to confirm calls. OpenAI documents this feature for the web.

    • A whole organization: on Claude Team or Enterprise, an Owner adds it once under Organization settings → Connectors → Add custom connector, and each member then connects it. On ChatGPT Business, Enterprise or Edu, an admin turns on Developer mode (Workspace Settings → Permissions & Roles → Connected Data), creates the app, and publishes it (Workspace settings → Apps → Drafts → Publish). The hosted server is shared and limits each client to 60 requests a minute, so a large organization should run its own copy.

    • VS Code: the same entry under a servers key, with "type": "http", in .vscode/mcp.json.

    {
      "mcpServers": {
        "maplestats": {
          "url": "https://mcp.maplestats.danielstats.io/mcp"
        }
      }
    }
  2. Tell the user to restart or reload the client, then check that the search_tools tool is listed.

  3. Only if the client cannot use remote servers, or the user wants the microdata tabulation tool or everything kept on their own machine, run it locally instead: claude mcp add --scope user maplestats -- uvx maplestats-mcp (needs uv), or the equivalent uvx maplestats-mcp entry for other clients (see Install).

Each client gets 60 requests a minute, and the microdata tabulation tool is switched off there. Your agent's tool calls (a search phrase, a table number) reach the server and its host, Microsoft Azure (Canada Central). The code keeps no log of them, but its in-memory cache can hold a search phrase or filter in a key or a response until the entry expires or the server restarts. Check Microsoft's terms and privacy statement; for full privacy, run it locally. What it logs: FAQ. Other clients: the Connect page.

Install locally (optional)

Prefer to run it on your machine? It works over stdio with no account or key.

uvx maplestats-mcp                 # run without installing
uv tool install maplestats-mcp     # or install the command once (pip works too)
uv tool upgrade maplestats-mcp     # update

For the development version: uv tool install git+https://github.com/dsanchezp18/maplestats-mcp.git. If you installed the command, use "command": "maplestats-mcp" with no args in the JSON above. On Windows, make sure the directory where uv installs tools is on PATH, and restart the client afterwards.

Using it

Tools are found through search rather than listed flat: call search_tools with a plain-language query (English or French), then call_tool with the name it returns.

{"name": "search_tools", "arguments": {"query": "consumer price index"}}
{"name": "call_tool", "arguments": {"name": "wds_search_cubes", "arguments": {"query": "consumer price index"}}}

plan_query turns a question into an ordered, multi-source plan, and reproduce_code writes the R, Python, Stata or Julia script (or an Excel Power Query) that fetches the same data straight from the source; reproduce_workbook returns the rows as a formatted Excel workbook. Before replying with figures, the assistant can call check_answer with the StatCan and Bank of Canada figures it cites: it re-reads them from the source and returns only the problems (a different value, a missed scale factor, a newer period, another geography, an unadjusted series), each with a fix. Every tool accepts lang: "en"|"fr"; some sources only publish English content (for example Yukon's CKAN portal, the World Bank's indicator definitions and the PMPRB), so there lang changes the labels MapleStats adds, not the source's own text. Every response has a provenance block: source, URL, query time, freshness and limits. docs://catalogue describes every module in both languages. The guided prompts take lang too, and each docs://<module>/... resource has a French twin at docs://<module>/fr/... (for example docs://statcan/fr/pieges).

To call the sources from Python without MCP, see docs/library.md.

What to watch for

MapleStats retrieves data directly from the original sources and returns values as published. When a result is trimmed, scaled, cleaned or computed, it says so in its provenance block or its notes; series values come unscaled, with the scale factor beside them. When a source is down or blocks the request, the tool returns an error, not a silent gap or a substitute value.

The risk is in the use. An AI assistant can pick the wrong table, geography or reference period, and the answers, summaries and analysis it writes are AI-generated and can contain errors. For anything you would publish, spot-check a few figures against the source's own site and use reproduce_code to fetch them again outside the assistant. Publishers revise their figures, so a value retrieved today can differ from an earlier one.

Each dataset keeps its own licence and attribution terms, shown in the result's provenance; credit the publisher, not MapleStats. MapleStats is an independent project, not affiliated with or endorsed by Statistics Canada, the Bank of Canada, CMHC or any other data provider. It is provided as is, depends on upstream services that can change or go offline, and is not professional, legal or financial advice. Parts of the code and tests were written with AI assistance; the discovery benchmark's questions were written by one AI session and reviewed by a second, independent one, not yet by a person (tests/discovery_benchmark/REVIEW.md).

What it covers

399 tools in 78 modules. Run docs://catalogue for the full, bilingual list.

Area

Tool prefixes

Covers

Statistics Canada

wds_, sdmx_, sdmx_space_, rdaas_, cimt_, statcan_*

Tables and series, the extra SDMX spaces (energy information, shared data), classifications, Census Profiles 2001–2021, public use microdata (codebooks, weighted tables), merchandise trade by commodity (CIMT), open databases (LODE), The Daily, delta files, indicators, surveys, census geography

Bank of Canada

boc_

Valet series, groups, observations

CMHC

cmhc_, cmhc_dt_

Housing Market Information Portal and Excel data tables

Federal agencies

eccc_, eccc_coverages_, eccc_datamart_, ised_*, gazette_, tc_recalls_, recalls_, cdc_, cfia_, fcac_, finance_, cihi_, phac_infobase_, hc_*, pmra_, pmprb_, gc_infobase_, disclosure_, cer_, nrcan_*, dfo_iwls_, cgc_, nfd_, ircc_*, cbsa_, cbsa_tariff_, pbo_, competition_bureau_, elections_results_, elections_financial_returns_, cra_digital_economy_registry_, cra_charities_, jobbank_, telecom_, earthquakes_, borealis_, isc_

Weather, climate and gridded climate projections, pollutant releases and emissions (NPRI, GHGRP, NAPS), corporations and IP, regulations, recalls, dairy, animal disease, consumer banking, federal and provincial fiscal tables, health, drugs, natural health products, medical devices, adverse reactions, pesticides, spending, federal contracts, grants and travel and hospitality disclosures, energy, mineral production, oceans, grain, forestry, immigration and application processing times, Job Bank wages and outlooks by occupation, registered charities, mobile and Internet plan prices, border wait times, customs tariff rates, budgets, mergers, elections, earthquakes, university-library data tables, First Nation profiles, registered population and drinking water advisories

Wildland fire

cwfis_, nrcan_nbac_, ab_wildfire_

NRCan's Canadian Wildland Fire Information System (satellite hotspots, fire danger, weather stations), burned areas, and Alberta Wildfire's live fire status

Electricity

electricity_ontario_, electricity_quebec_, oeb_

IESO (Ontario) demand, generation and prices; Hydro-Québec demand, generation and trade (CC BY-NC 4.0: credit Hydro-Québec, non-commercial use only); Ontario Energy Board datasets

Parliament and elected officials

ourcommons_, senate_, represent_

MPs and their roles, party standings, Cabinet, Senate votes; elected officials and districts for a postal code via Open North's Represent (unofficial)

Provincial agencies

aer_, bcgw_, bc_stats_, bc_env_, bc_lobbyists_, drivebc_, ab_economic_, ab_opendata_, isq_, nl_stats_, yukon_stats_, nwt_stats_, elections_provincial_, on_fir_

Alberta Energy Regulator, BC Geographic Warehouse, BC Stats Excel tables, BC environmental monitoring (air quality, snow, groundwater, streamflow), BC lobbyists registry, DriveBC road events, Alberta Economic Dashboard, Open Alberta files, Institut de la statistique du Québec, the Newfoundland and Labrador, Yukon and Northwest Territories statistics bureaus, provincial general election results (Quebec, Alberta, British Columbia, Saskatchewan, Manitoba), Ontario's municipal Financial Information Return (every schedule of every municipality, 2000 on)

Housing (links only)

crea_

Links, release timing and terms for CREA's MLS® Home Price Index; no values, because CREA's terms allow private, non-commercial analysis only

International

worldbank_, bis_

World Bank World Development Indicators for Canada and peer countries (CC BY 4.0); Bank for International Settlements statistics: policy rates, debt service ratios, credit, house prices, banking and payment statistics (free reuse with citation)

Open-data portals

ckan_, arcgis_hub_, socrata_ + portal

Federal, provincial, territorial and municipal catalogues (*_list_portals names each one)

Other municipal

opendatasoft_vancouver_, nl_opendata_, eps_, ets_, epcor_

Vancouver, Newfoundland and Labrador, Edmonton police, transit and water quality

Transit schedules

transit_ + agency

Static GTFS timetables of the STM (buses), OC Transpo, Calgary Transit, VIA Rail, GO Transit, UP Express, the BC Transit systems and the Quebec networks listed on Données Québec (exo, RTC, STL, STS and others), plus further agencies from Statistics Canada's 2025 Canadian Public Transit Network Database: stops, routes, scheduled departures, frequency by hour

Other federal series (CRA, OSFI, ISED insolvency) are ordinary open.canada.ca datasets, reachable with ckan_search_datasets(portal="federal", fq="organization:<org>").

Not covered: CAPP's Statistics Handbook, Petrinex and Payments Canada were not built, because their terms or download hosts do not permit automated access. CanadaBuys, OpenParliament.ca and the Toronto Transit Commission's own schedule download were removed for the same reason (the TTC schedule is still served from Statistics Canada's national transit database). The City of Hamilton's portal and Niagara Open Data (niagaraopendata.ca) are left out because they answer automated requests with a Cloudflare challenge. The 2006-2016 census data tables and the 2016 Census Profile service were removed because Statistics Canada's www12 host answers automated clients with a bot challenge, 503 errors or timeouts (the 2021 profile and the WDS tables remain). Justice Laws (federal statutes and regulations) is out of scope, because legislation text is not data this server carries, and the Saskatchewan Bureau of Statistics' Provincial Economic Accounts were not built: they are under Crown copyright, for non-commercial reuse only, and the site's terms bar automated access. The roadmap records each decision.

Development

uv sync                          # install
uv run ruff check src tests scripts  # lint
uv run ruff format src tests scripts  # format
uv run pyright                   # type check
uv run pytest                    # unit tests (mocked, no network)

.\scripts\verify.ps1 runs that gate plus every scripts/smoke_test*.py against the live APIs. The website is generated from the tool registry: uv run python scripts/build_site.py writes build/site/. See AGENTS.md for the contributor guide and how to add a source module.

Hosting

MAPLE_TRANSPORT=http MAPLE_HOST=0.0.0.0 MAPLE_PORT=8000 uv run maplestats-mcp serves HTTP instead of stdio. Docker Compose does the same in Docker, but docker-compose.yml sets MAPLE_REQUIRE_AUTH=1, so the server refuses to start until MAPLE_AUTH_TOKEN is set: MAPLE_AUTH_TOKEN=<a long random string> docker compose up --build. Clients then send that token as a bearer token. Docker is optional and unnecessary on a personal computer. If the server is exposed beyond your machine, set MAPLE_AUTH_TOKEN and keep MAPLE_REQUIRE_AUTH=1. GET /health reports uptime and version. GET /stats is public, needs no token and reports calls per tool name and day, each tool's p50 and p95 duration, and each upstream host's error counts and circuit-breaker state (see MAPLE_USAGE_STATS and MAPLE_BREAKER below). After repeated failures (timeouts, connection errors, 5xx answers, Cloudflare challenges) a host is paused for a cooldown: its tools fail at once with an "unavailable" error that says when to retry, instead of waiting for another timeout. The docs://status resource lists the paused hosts.

Env var

Default

Purpose

MAPLE_TRANSPORT

stdio

stdio for local clients, http for hosting

MAPLE_HOST / MAPLE_PORT

127.0.0.1 / 8000

HTTP bind address

MAPLE_AUTH_TOKEN, MAPLE_REQUIRE_AUTH

unset, 0

Bearer token required on /mcp; refuse to start without one if 1. docker-compose.yml defaults MAPLE_REQUIRE_AUTH to 1

MAPLE_RATE_LIMIT_REQUESTS / MAPLE_RATE_LIMIT_WINDOW_SECONDS

120 / 60

Per-client rate limit

MAPLE_MAX_CONCURRENT_REQUESTS

8

In-flight request cap; the excess waits 5 s, then gets 503

MAPLE_SSL_CERTFILE / MAPLE_SSL_KEYFILE

unset

TLS in-process

MAPLE_TRUST_PROXY_HEADERS

0

Rate-limit on X-Forwarded-For; only behind a proxy that sets it

MAPLE_TRUSTED_PROXY_HOPS

1

Proxies that append to X-Forwarded-For; the client address is read that many entries from the right

MAPLE_ALLOWED_ORIGINS

project website, localhost

Browser origins allowed on /mcp (comma-separated, *. and :* wildcards); others get 403, clients without an Origin are allowed

MAPLE_CACHE_MAX_ENTRIES

2000

Response cache size per TTL bucket

MAPLE_CACHE_MAX_MB

128

Estimated memory cap for the response cache, all buckets together

MAPLE_PARSE_WORKERS / MAPLE_PARSE_TIMEOUT_SECONDS

4 / 60

Threads for parsing Excel and CSV files, and the time one parse may take

MAPLE_TOOL_TIMEOUT_SECONDS

120

Longest a tool call may run

MAPLE_BREAKER

1

Pause requests to an upstream host after repeated failures; 0 sends every request

MAPLE_BREAKER_FAILURES / MAPLE_BREAKER_WINDOW_SECONDS / MAPLE_BREAKER_COOLDOWN_SECONDS

5 / 300 / 60

Failures in a row, within the window, that pause a host, and how long before one probe request is sent

MAPLE_PUMF_TABULATE

1

0 hides statcan_pumf_tabulate (it downloads whole PUMF ZIPs); search, listings and codebooks stay

MAPLE_QUERY_SERIES

1 locally, 0 over HTTP

0 hides wds_query_series (server-side SQL): off by default when serving HTTP, since one query could use more memory than a small instance has

MAPLE_PUMF_CACHE_DIR, MAPLE_PUMF_CACHE_MAX_GB

system temp, 5

Downloaded microdata cache; use a persistent volume when hosted

MAPLE_CLIENT_IP_HEADER

unset

Header the outermost proxy sets to the caller's own address (Cloudflare's CF-Connecting-IP), used for the per-client rate limit when MAPLE_TRUST_PROXY_HEADERS is on; set it only when every request passes through that proxy

MAPLE_DUCKDB_MEMORY_LIMIT

unset

Memory limit for DuckDB queries over downloaded files (patents, open databases, microdata), such as 256MB; beyond it DuckDB spills to the temporary folder. Set it on a small hosted instance

MAPLE_DUCKDB_TEMP_DIR, MAPLE_DUCKDB_TEMP_MAX_GB

system temp (maplestats-duckdb), 1

Where DuckDB spills past its memory limit (each query in its own subfolder, removed when it ends), and the most one query may spill

MAPLE_QUERY_MEMORY_MB, MAPLE_QUERY_MAX_CONCURRENT

256, 2

wds_query_series runs each SQL query in its own process: the memory it may use beyond its start (enforced on Linux), and how many run at once

MAPLE_LODE_CACHE_DIR, MAPLE_LODE_CACHE_MAX_GB

system temp, 3

Where StatCan open-database (LODE) archives are unpacked, and the size cap (least recently used files go first); use a persistent volume when hosted

MAPLE_LODE_MAX_DOWNLOAD_MB

300

Largest open-database archive one call may download; 0 turns downloads off

MAPLE_IP_HORIZONS_CACHE_DIR, MAPLE_IP_HORIZONS_CACHE_MAX_GB

system temp, 3

CIPO patent table cache

MAPLE_CBSA_TARIFF_CACHE_DIR

system temp

Customs Tariff editions as Parquet (under 1 MB each, newest 12 kept)

MAPLE_ON_FIR_CACHE_DIR, MAPLE_ON_FIR_CACHE_MAX_MB

system temp, 500

Ontario FIR years kept as Parquet (about 3 MB each); use a persistent volume when hosted

MAPLE_EXPORT_DIR

unset (no files saved)

Folder where reproduce_workbook saves Excel workbooks on a local server. Unset, the workbook comes back as base64 and every tool is read-only

MAPLE_SEARCH, MAPLE_SEMANTIC_DIR

bm25, unset

hybrid fuses BM25 with a local multilingual-e5-small index (needs the [semantic] extra and python -m maplestats_mcp.shared.semantic build); off by default, see tests/discovery_benchmark/phase2.md

MAPLE_RESPONSE_MAX_BYTES

200000

Byte budget for one tool result (minimum 10,000); a larger result has its biggest lists trimmed, and provenance.limits says what was kept and how to get the rest

MAPLE_GOATCOUNTER_URL, MAPLE_GOATCOUNTER_TOKEN

unset

With both set (an https GoatCounter site and an API token allowed to record pageviews), each counted tool call is also sent there as the event mcp/<instance>/<tool> (/error appended on failure), in batches each minute, so counts outlive restarts and several hosts add up; no arguments or addresses, no_sessions on

MAPLE_INSTANCE_NAME

server

The <instance> label in those events (azure, render)

MAPLE_USAGE_STATS

1

Counts calls and durations per tool name and UTC day, and upstream errors per host (never arguments or client addresses), in memory, and serves them at the public /stats route; 0 turns both off

MAPLE_DELTA_MAX_SCAN_MB / MAPLE_DELTA_MAX_SCAN_SECONDS

400 / 75

How much of a Delta File one statcan_delta_read_table call streams (seconds kept 30 under the tool timeout)

MAPLE_DELTA_INDEX_DIR

system temp

Saved Delta File resume points (a few MB per day); off keeps them in memory only

License

MIT. Third-party notices are in THIRD_PARTY_NOTICES.md.

Security and conduct

Report a vulnerability privately through GitHub's private vulnerability reporting; see SECURITY.md. Changes are recorded in CHANGELOG.md, and community expectations in CODE_OF_CONDUCT.md.

Acknowledgments

MapleStats owes its architecture to EcuDataMCP, the MCP server for Ecuador's open data that I help maintain with DweskZ and its other contributors. Its approach to Canadian data owes much to the R developers who got there first: Jens von Bergmann (mountainMath) and his co-authors, including Dmitry Shkolnik (dshkol), Thierry Warin (statcanR), Valentin Lucet (rgovcan), and others. Thanks to them, and to everyone who publishes Canadian data in the open.

For other ways to get Canadian data, see the alternatives.

Available Tools

3 tools
call_toolRun a Canadian data toolA
Read-onlyIdempotent
Inspect

Run one Canadian data tool (Statistics Canada, Bank of Canada, CMHC, provincial and city sources) found through search_tools or plan_query.

Use for: executing a tool by exact name with arguments that match the inputSchema search_tools returned for it. Data tools read public sources (StatCan, Bank of Canada, open-data portals). reproduce_workbook can save an Excel file on a local stdio server; hosted exports return base64. Returns that tool's typed result, including a provenance block (source, URL, query time, freshness). Errors come back as MCP tool errors, not as data: an unknown or misspelled name raises 'Unknown tool' (search again for the exact name), invalid arguments raise a validation error naming the field, and upstream outages or empty matches raise a typed error explaining what to change. search_tools, call_tool and plan_query cannot be called through it; call them directly. Tool calls are subject to the server's timeout (MAPLE_TOOL_TIMEOUT_SECONDS, default 120).

NameRequiredDescriptionDefault
nameYesExact tool name as returned by search_tools or plan_query, e.g. 'boc_get_observations'.
argumentsNoObject matching that tool's inputSchema from search_tools. Omit or pass {} for a tool with no required parameters.

TDQS

A4.4/5.0
Behavior4/5

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

Beyond the annotations, it discloses the return shape (the routed tool's typed result plus a provenance block with source, URL, query time and freshness), the error taxonomy (unknown tool, field-level validation errors, typed upstream/empty-match errors), and the MAPLE_TOOL_TIMEOUT_SECONDS default of 120. The one unreconciled point is the note that reproduce_workbook can write an Excel file to disk while the annotations declare readOnlyHint=true and destructiveHint=false; the write is disclosed, but the description never says whether the wrapper's read-only annotation still applies when delegating to such a tool.

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?

The definition is front-loaded with the purpose and an explicit 'Use for:' clause, then moves to returns, errors, and constraints — a sensible order. It is longer than average and the error paragraph could be tightened (three error classes described at similar length), but nearly every sentence carries operational 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?

Although there is no output schema, the description explains what comes back (typed result plus provenance) and enumerates failure modes, so an agent can both call it and interpret responses. For a two-parameter dispatcher, nothing material is missing.

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 both parameters are already documented, including the 'exact tool name' constraint and the 'omit or pass {}' case. The description restates that arguments must match the inputSchema returned by search_tools but adds no format, size, or nesting guidance beyond the schema, so the baseline of 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?

The first sentence gives a specific verb and resource with scope: 'Run one Canadian data tool (Statistics Canada, Bank of Canada, CMHC, provincial and city sources) found through search_tools or plan_query.' That distinguishes it unambiguously from the two siblings, which are lookup/planning tools rather than execution.

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 states the prerequisite flow (discover with search_tools or plan_query, then call by exact name), the exclusion (search_tools, call_tool and plan_query cannot be invoked through it — call them directly), and the fallback when a name is wrong ('search again for the exact name'). Rarely is routing guidance this explicit.

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

plan_queryPlan queryA
Read-onlyIdempotent
Inspect

Plan how to answer a question about Canadian data from official sources.

Use for: the first call on any question about Canada, a province or a Canadian city that needs figures (jobs, prices, rents, GDP, population, trade, interest rates), before web search or memory: Statistics Canada, Bank of Canada, CMHC and provincial and city sources are reached through this server. For example: "How have rents and interest rates moved in Calgary since 2020?". Returns the topics it touches, the tools to call for each in order, local portals for any province or city named, and caveats on combining them. Then run the steps with call_tool. Read-only and offline: it matches the question against this server's source map and calls no external API. Use search_tools instead to find a single tool for a narrow, single-source need. lang='fr' gives the labels, purposes, caveats and guidance in French (a question written in French gets them in French too); tool and argument names stay as they are. Keywords: plan, which data source, where to find, combine sources, cross-source, question, research, Canada data. Mots-clés : planifier, quelle source de données, où trouver, combiner des sources, question, recherche, données canadiennes, statistiques.

NameRequiredDescriptionDefault
langNoen
questionYes

Output Schema

NameRequiredDescription
placesYes
topicsYesBest match first; at most 4.
guidanceYes
questionYes
provenanceYesWhere a result came from and how fresh/complete it is. Embedded in every module's response models (composition, not inheritance) so a tool can return `MyResult(provenance=..., ...)` without fighting Pydantic's model-inheritance rules for extra fields.
out_of_scopeNoSet when the question is about a place outside Canada that this server has no data for; topics and fallback steps are then empty.
fallback_stepsYesOnly when no topic matched.

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, openWorldHint=false and destructiveHint=false, and the description reinforces this with 'Read-only and offline... calls no external API.' It goes beyond the annotations by describing what the plan contains (topics touched, ordered tools per topic, local portals for named provinces/cities, caveats on combining sources), which tells the agent what to expect before committing to the call.

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 purpose, then a labeled 'Use for:' block, the return shape, the exclusion, and language behavior — a sensible ordering. The trailing bilingual keyword lists are largely expendable padding, but the rest of the text earns its place.

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 and annotations are rich, and the description still supplies everything an agent needs: when to call, what the plan returns, the next action (call_tool), the narrow-need alternative (search_tools), and language behavior. Complete for a two-parameter planning tool.

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 0%, so the description must carry the load. It does for lang: 'lang=fr gives the labels, purposes, caveats and guidance in French (a question written in French gets them in French too); tool and argument names stay as they are' — this explains scope of the switch and a non-obvious auto-detection behavior. The question parameter is not formally described but its semantics are obvious from the opening sentence.

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: 'Plan how to answer a question about Canadian data from official sources.' It enumerates the domains it covers (jobs, prices, rents, GDP, population, trade, interest rates) and names the source institutions reached through the server, so it is unmistakable against the siblings call_tool and search_tools.

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 when-to-use ('the first call on any question about Canada, a province or a Canadian city that needs figures... before web search or memory'), an explicit alternative with a discriminating condition ('Use search_tools instead to find a single tool for a narrow, single-source need'), and the follow-up step ('Then run the steps with call_tool'). Nothing is left to inference.

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

search_toolsSearch Canadian data toolsA
Read-onlyIdempotent
Inspect

Search Canadian official data: Statistics Canada, Bank of Canada, CMHC, provincial statistics agencies, federal departments and city portals.

Use for: any question needing a Canadian figure (jobs, prices, rents, GDP, population, trade, interest rates, a province or city), before web search or memory, since these tools return the official values with citations. Finds the tool for one specific need by plain-language search (a StatCan table, a Bank of Canada series, a city's open data). Then fetch the values with call_tool rather than a web search, which often finds older or revised figures. Returns up to five tool definitions, best match first, each with its name, description and full input schema (annotations only for a tool that is not read-only). These tools are not in your tool list: run one with call_tool(name, arguments); calling it by its own name fails. Read-only; it searches this server's catalogue only and calls no external API. Use plan_query instead when a question may span several sources or you do not know where to start; use call_tool to run a tool once you have its name. Queries in English or French both work. An empty result means no tool matched: rephrase with topic words (e.g. 'housing starts' rather than 'CMHC table').

NameRequiredDescriptionDefault
queryYesWhat you need, in plain English or French, e.g. 'Calgary rent index' or 'taux de chômage Québec'. Topic words work better than tool names.

Output Schema

NameRequiredDescription
resultYes

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, closed-world and idempotent, but the description adds substantial non-structured behavior: it returns up to five tool definitions best-match-first with name, description and full input schema, and that the returned tools are NOT in the caller's tool list and must be invoked via call_tool(name, arguments) — calling by their own name fails. It also discloses language support (English/French) and that it queries only this server's catalogue.

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 purpose, then usage, then return shape and failure handling — a sensible order. It is somewhat long and repeats the web-search point twice ("before web search or memory" and "rather than a web search, which often finds older or revised figures"), which costs a little tightness.

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?

For a one-parameter discovery tool with an output schema and full annotations, nothing an agent needs is missing: purpose, routing to siblings, invocation indirection, return cardinality and ordering, and empty-result recovery are all 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 parameter's description already covers plain-language input, examples and the topic-words-over-tool-names hint. The description restates the same guidance ("plain-language search") plus the rephrasing example, so it adds only marginal meaning beyond the schema. Baseline 3 for a fully documented single parameter.

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 ("Search Canadian official data") and enumerates the covered sources (Statistics Canada, Bank of Canada, CMHC, provincial agencies, city portals). It explicitly distinguishes itself from siblings call_tool and plan_query, so an agent knows this is a discovery/search step rather than an execution step.

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 when-to-use ("any question needing a Canadian figure... before web search or memory") and explicit alternatives: plan_query for multi-source or unknown-start questions, call_tool once a tool name is known. It even handles the failure case (empty result means rephrase with topic words).

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. 1 tool updatev0.4.7
    • Changedplan_query2 fields changed
      • addedOutput schema / properties / provenance / properties / lang
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "The language MapleStats wrote this result's own text in ('en' or 'fr'): notes, limits, caveats, labels. Values and the publisher's own text are as published."
        +}
      • changedOutput schema / properties / provenance / properties / reproduce / default
        Previous value: -"For R, Python, Stata and Julia scripts that fetch and clean these data, call reproduce_code with this tool's name and arguments."New value: +"For scripts, call reproduce_code with this tool's name and arguments."
  2. 1 tool updatev0.4.3
    • Changedplan_query2 fields changed
      • addedOutput schema / properties / provenance / properties / caveats
        Added value: +{
        +  "description": "Fitness-for-use cautions for this table or source, from MapleStats' rules (docs://planner/fitness-rules).",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / provenance / properties / commercial_use
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "allowed",
        +        "not_allowed",
        +        "varies",
        +        "unknown"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Whether the licence allows commercial reuse without asking the publisher: 'allowed', 'not_allowed' (non-commercial use only, or written permission needed), 'varies' (each dataset or feed has its own licence: read licence) or 'unknown' (terms silent, conflicting or not found). Null when no licence applies. The conditions themselves are in licence."
        +}
  3. 1 tool updatev0.4.0
    • Changedplan_query1 field changed
      • changedOutput schema / properties / provenance / properties / reproduce / default
        Previous value: -"For R, Python, Stata and Julia scripts that fetch and clean this data, call reproduce_code with this tool's name and arguments."New value: +"For R, Python, Stata and Julia scripts that fetch and clean these data, call reproduce_code with this tool's name and arguments."
  4. 1 tool updatev0.2.0
    • Changedplan_query2 fields changed
      • addedOutput schema / properties / out_of_scope
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Set when the question is about a place outside Canada that this server has no data for; topics and fallback steps are then empty."
        +}
      • addedOutput schema / properties / provenance / properties / licence
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Licence and attribution the upstream publisher requires, when it has one (set for every Statistics Canada result)."
        +}
  5. 2 tool updatesv0.1.1
    • Changedcall_tool2 fields changed
      • changedInput schema / properties / arguments / description
        Previous value: -"Arguments to pass to the tool"New value: +"Object matching that tool's inputSchema from search_tools. Omit or pass {} for a tool with no required parameters."
      • changedInput schema / properties / name / description
        Previous value: -"The name of the tool to call"New value: +"Exact tool name as returned by search_tools or plan_query, e.g. 'boc_get_observations'."
    • Changedsearch_tools1 field changed
      • changedInput schema / properties / query / description
        Previous value: -"Natural language query to search for tools"New value: +"What you need, in plain English or French, e.g. 'Calgary rent index' or 'taux de chômage Québec'. Topic words work better than tool names."
  6. 3 tool updatesv0.1.0
    • First observedcall_tool
    • First observedplan_query
    • First observedsearch_tools

TDQS

A4.5/5.0

Scored across 3 tools

Disambiguation5/5

The three tools occupy clearly separate stages: plan_query plans a multi-source research path offline, search_tools finds a single tool in the catalogue, and call_tool executes a named tool. Each description explicitly says when to prefer the other two (e.g. 'Use search_tools instead to find a single tool' / 'Use plan_query instead when a question may span several sources'), leaving almost no room for misselection.

Naming Consistency5/5

All three names follow the same snake_case verb_noun pattern (plan_query, search_tools, call_tool) with no stylistic deviation. The verb choice is also semantically parallel, reinforcing the discover-then-execute pipeline.

Tool Count4/5

Three tools is thin in absolute terms, but the design is a deliberate gateway: the real data tools live behind call_tool and are surfaced via search_tools, so each of the three earns its place. The only reservation is that a third of the surface is planning rather than data access.

Completeness4/5

The lifecycle of discover -> plan -> execute -> provenance (source, URL, freshness) is covered, with sensible error semantics documented for call_tool. Minor gaps remain: no way to browse or enumerate the full catalogue beyond a five-result search, and no batch/multi-tool execution despite plan_query returning ordered step lists.

Maintenance

ActivityActive
ResponsivenessSyncing

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    F
    maintenance
    Provides access to Statistics Canada official statistics without authentication, enabling AI agents to query Canadian economic and demographic data.
    2 npm
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Provides LLM agents with live access to Canadian economic and financial data (exchange rates, interest rates, inflation, etc.) through the Bank of Canada Valet API, with no API key required.
    10
    5
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    MCP server serving official statistics from major data agencies (Statistics Canada, FRED, BLS, World Bank, etc.) as tools with provenance and verification, enabling search, retrieval, analysis, and monitoring via natural language.
    11
    63 npm
    MIT