pathways-mcp-server
Provides tools for exploring health population segmentation data from the Pathways platform via its Strapi CMS API, including listing segmentations, retrieving segment details, filtering segments, accessing profiles, metrics, variables, themes, domains, regions, and geographic distributions.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@pathways-mcp-serverList segments for the Senegal 2019 DHS study"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Pathways MCP Server
A Model Context Protocol (MCP) server that exposes the Pathways health segmentation platform as structured tools. Pathways provides woman-centered data and insights to help global health organizations design targeted interventions.
What it does
This server connects to the Pathways Strapi CMS API and provides tools that let Claude (or any MCP client) explore population segmentation data:
Tool | Description |
| Discover available country studies (Senegal, Kenya, Nigeria, etc.) |
| Full details and segments for a specific study |
| Filter segments by vulnerability level or stratum (urban/rural) |
| Comprehensive "who are these women?" view with metrics by theme/domain |
| Quantitative indicators for a segment, filterable by health theme |
| Search indicators by name, theme, domain, or data type |
| Reference list of health themes and vulnerability domains |
| Sub-national regions for a country |
| Geographic distribution of segments across regions |
Example query this enables: "What is the best way to reach out to women in R4 in Tambacounda to improve family planning outcomes?"
Related MCP server: DHIS2 MCP Server
Prerequisites
Python 3.10+
A Pathways API token (read-only Bearer token for the Strapi CMS)
Installation
cd pathways-mcp-server
python3 -m venv .venv
source .venv/bin/activate
pip install -e .Configuration
Copy the example env file and add your token:
cp .env.example .env
# Edit .env and set PATHWAYS_API_TOKENVariable | Default | Description |
| (required) | Strapi read-only API token |
|
| Strapi API base URL |
Running standalone
PATHWAYS_API_TOKEN=<your-token> python -m pathways_mcp.serverThe server communicates over stdio using the MCP protocol. To test interactively, use the MCP Inspector:
npx @modelcontextprotocol/inspectorUsing with Claude
Claude Desktop
Add this to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"pathways": {
"command": "<path-to-repo>/pathways-mcp-server/.venv/bin/python",
"args": ["-m", "pathways_mcp.server"],
"cwd": "<path-to-repo>/pathways-mcp-server",
"env": {
"PATHWAYS_API_TOKEN": "<your-token>",
"PATHWAYS_API_URL": "https://api.staging.withpathways.org"
}
}
}
}Project structure
pathways-mcp-server/
├── pyproject.toml
├── requirements.txt
├── .env.example
├── .gitignore
├── README.md
└── src/
└── pathways_mcp/
├── __init__.py
├── __main__.py # python -m entry point
├── server.py # FastMCP server + tool registration
├── api.py # Strapi API client (httpx, auth, pagination)
└── tools/
├── __init__.py
├── segmentations.py
├── segments.py
├── metrics.py
├── variables.py
├── reference.py
└── geography.pyThe Pathways Data Model
Understanding this hierarchy is key to understanding all the tools.
Geography (e.g., Senegal)
└── Segmentation (e.g., SEN_2019DHS8_v1 — "Senegal 2019 DHS study")
├── Segments (e.g., R1, R2, R3, R4, U1, U2... — distinct groups of women)
│ └── Metrics (a segment × variable pair = one data point)
│
└── Variables (the indicators measured, e.g., "Modern contraceptive use")
├── linked to Themes → describe Health Outcomes
└── linked to Domains → describe Vulnerability Factors
Themes = categories of Health Outcomes (e.g., Maternal Health, Nutrition)
Domains = categories of Vulnerability Factors (e.g., Household Economics, Social Support)
Regions = sub-national administrative areas within a Geography
Geographic Distributions = what % of each region's population belongs to each segmentThe API Client (api.py)
This is the most important infrastructure file. It handles all HTTP communication.
The StrapiClient class
When instantiated, it reads two environment variables — both are now required:
PATHWAYS_API_TOKEN— the Bearer token (raises an error immediately if missing)PATHWAYS_API_URL— the base URL (raises an error immediately if missing; there is no default fallback)
self._headers = {"Authorization": f"Bearer {token}"}Every request includes this header, which Strapi uses to verify access.
fetch_collection — one page of results
This is the main method. It:
Builds the query string parameters (filters, pagination, populate, fields)
Makes an async HTTP GET request using
httpxReturns the parsed JSON
async with httpx.AsyncClient(...) as client:
resp = await client.get(url, params=params)
resp.raise_for_status()
return resp.json()resp.raise_for_status() checks the HTTP status code. If the server returned a 4xx or 5xx error, it raises a Python exception immediately rather than silently returning broken data. Before calling that, the code also checks for specific codes to give actionable error messages:
if resp.status_code == 403:
raise RuntimeError("Access denied... Check your PATHWAYS_API_TOKEN.")
if resp.status_code == 404:
raise RuntimeError(f"Endpoint '{endpoint}' not found on the Strapi API.")A 403 means the token is wrong or expired. A 404 means the endpoint path itself doesn't exist — usually a typo in the collection name.
fetch_all — auto-pagination
Some tools need all records, not just a page. fetch_all calls fetch_collection in a loop, advancing the page number on each iteration:
while True:
result = await self.fetch_collection(..., page=page, ...)
data = result.get("data", [])
all_data.extend(data)
page_count = result["meta"]["pagination"]["pageCount"]
if page >= page_count or len(all_data) >= max_records:
break
page += 1Strapi tells you how many pages exist in the meta.pagination.pageCount field. The loop stops when you've fetched the last page, or when you've hit max_records (a safety cap to prevent fetching thousands of records if the data grows unexpectedly).
This is used by get_segment_profile for both its metrics fetch and variables fetch — both can be very large datasets.
The populate parameter — what Strapi relations are
In relational databases, a foreign key is when one table stores only the ID of a record from another table — not the full data. For example, a metrics record stores a variable_id: 42 rather than copying all the variable's fields.
Strapi works the same way. By default, when you fetch a metric, you get:
{ "id": 1, "percentage": 0.34, "variable": null }To get the actual variable data embedded in the response, you pass populate:
populate=["variable", "categorical_level"]Strapi then does a database JOIN behind the scenes and returns:
{
"id": 1,
"percentage": 0.34,
"variable": { "code": "fp.mod.use", "name_en": "Modern FP use", ... },
"categorical_level": { "name_en": "Yes", ... }
}Without populate, the tool code would have to make a separate API call for every variable — which would be hundreds of extra requests. Populate fetches them all in one go.
The singleton pattern
_client: StrapiClient | None = None
def get_client() -> StrapiClient:
global _client
if _client is None:
_client = StrapiClient()
return _clientThe client is created once and reused across all tool calls. This avoids re-reading environment variables and re-allocating memory on every request.
RESPONSE_CHAR_LIMIT
Set to 25,000 characters. All tool responses are truncated to this length before being returned to Claude:
return json.dumps(output, indent=2)[:RESPONSE_CHAR_LIMIT]This is a practical guard: MCP responses that are too large can cause problems for the AI client or hit context limits.
Available Tools
5 toolsget_geographic_distributionA
Get the geographic distribution of population segments across regions.
Each record shows what percentage of a region's population belongs to a given segment. Use this to answer questions like:
"Which regions have the highest concentration of the most vulnerable segment?"
"How are the segments distributed across Dakar?"
"Where is segment R2 most prevalent?"
Supply only segmentation_code to get the full distribution matrix. Filter by segment_code to rank regions for a specific segment. Filter by region_code to see the segment breakdown within one region. Both filters can be combined.
Results are sorted by percentage descending (highest concentration first).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max records to return per page (default 50, max 100). | |
| offset | No | Number of records to skip for pagination (default 0). | |
| region_code | No | Optional region code to filter by (e.g., "dakar"). Use list_regions to find available codes. | |
| segment_code | No | Optional segment code to filter by (e.g., "R4"). Use list_segments to find available codes. | |
| segmentation_code | Yes | Segmentation code (e.g., "SEN_2019DHS8_v1"). |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must fully disclose behavior. It mentions sorting by percentage descending, but does not discuss idempotency, rate limits, authentication, or data freshness. The basic read behavior is clear but lacks some depth.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is moderately long but well-organized: purpose, data format, example questions, parameter usage, sorting. It is front-loaded with the most important information. Minor redundancy could be trimmed, but it remains efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that a separate output schema exists, the description does not need to detail return values. It covers all essential aspects: what the tool does, what the records represent, how to filter, and how results are sorted. The tool is simple and the description is complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions for all 5 parameters. The description adds value by explaining how parameters work together (e.g., combining filters, default behavior when only segmentation_code is supplied). This goes beyond the schema's per-parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool gets the geographic distribution of population segments across regions, provides a clear data format (percentage per region per segment), and includes example questions that distinguish its use from sibling tools like list_segments or get_segmentation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete usage scenarios via example questions and explains how to use filters (segment_code, region_code) to answer different queries. It does not explicitly mention when not to use it, but the context of sibling tools provides implicit alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_segmentationA
Get full details of a segmentation including all its segments.
Returns segmentation metadata (country, source, methodology) plus a list of all population segments with their vulnerability levels and prevalence.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | Segmentation code (e.g., "SEN_2019DHS8_v1"). Use list_segmentations to find available codes. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It states returns metadata and segments but omits behavioral traits like idempotency, side effects, or error conditions, which is inadequate for a read operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler: the first states purpose, the second details output. Every sentence is necessary and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the one parameter, clear output schema, and the description's coverage of metadata and segment details, the description fully informs the agent's decision-making.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already describes the code parameter well, but the description adds the tip 'Use list_segmentations to find available codes', which adds meaningful guidance beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly specifies 'Get full details of a segmentation including all its segments', indicating a specific verb and resource. It distinguishes itself from siblings like list_segments and get_segment_profile by focusing on the entire segmentation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description advises using list_segmentations to find available codes, providing a prerequisite. While it does not explicitly exclude other tools, this is sufficient context for typical use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_segment_profileA
Get a comprehensive profile for a specific population segment.
This is the "who are these women?" view — returns the segment's vulnerability level, prevalence, and key metrics organized into:
health_outcomes: metrics linked to Themes (measurable health results such as maternal health, nutrition, sexual and reproductive health).
vulnerability_factors: metrics linked to Domains (structural and social determinants such as household economics, social support).
To compare a segment against the sample total, call get_segment_metrics without a segment_code to retrieve the weighted sample-aggregate baseline.
Use this to understand the characteristics, health outcomes, and vulnerability profile of a specific segment.
| Name | Required | Description | Default |
|---|---|---|---|
| segment_code | Yes | Segment code (e.g., "R4" for Rural-4). | |
| segmentation_code | Yes | Segmentation code (e.g., "SEN_2019DHS8_v1"). |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries burden. It details the output structure (health_outcomes, vulnerability_factors) and clarifies it is a read-only profile view, but could mention idempotency or lack of side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with bullet points and front-loaded purpose. One sentence could be slightly more concise, but overall efficient and clear.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has only 2 parameters and an output schema exists, the description sufficiently covers what the tool returns and how it is organized, making it complete for an agent to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions already adequate. Description does not add additional meaning beyond the schema, so baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verbs ('Get a comprehensive profile') and resources ('population segment') and clearly distinguishes from siblings by mentioning get_segment_metrics for comparative analysis.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use this tool ('to understand the characteristics, health outcomes, and vulnerability profile') and provides an alternative ('to compare against the sample total, call get_segment_metrics').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_segmentationsA
List all available Pathways segmentations (country-level studies).
Each segmentation represents a population segmentation study for a specific country, based on survey data (e.g., DHS). Use this to discover which countries and studies are available. Only returns active, published segmentations.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description carries full burden. It discloses that only 'active, published segmentations' are returned, which is a key behavioral trait. No further details (e.g., pagination) are needed for a parameterless list tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences with no waste. Key information is front-loaded: the verb, resource, and supplementary details about data sources and constraints are presented efficiently.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters and an output schema exists, the description fully explains what the tool does, when to use it, and the constraint on returned data. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so schema coverage is 100%. The description does not need to add parameter details. Baseline score of 4 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') and resource ('Pathways segmentations'), further clarifying it as country-level studies. It effectively distinguishes from siblings like 'list_segments' and 'get_segmentation'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use this to discover which countries and studies are available,' providing clear context. It lacks explicit when-not-to-use or direct alternatives, but the context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_segmentsA
List population segments for a segmentation, with optional filters.
Each segment represents a distinct group of women identified through cluster analysis, with a vulnerability level (least/less/more/most) and stratum (urban/rural).
| Name | Required | Description | Default |
|---|---|---|---|
| stratum | No | Filter by stratum: "urban" or "rural". | |
| segmentation_code | Yes | Segmentation code (e.g., "SEN_2019DHS8_v1"). | |
| vulnerability_level | No | Filter by vulnerability level: "least", "less", "more", or "most". |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description carries full burden. It describes the nature of segments and filtering, but does not explicitly state that the operation is read-only or disclose any effects like pagination or empty results. The name 'list' implies reading, but more transparency would be beneficial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences: first states the action and optional filters, second explains what segments represent. No wasted words, efficiently informative.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists, the description does not need to detail return values. It covers the basic functionality and parameter meanings. However, it lacks details on ordering or pagination, which are common for list tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with parameter descriptions already present. The description adds context about segment characteristics (vulnerability levels and strata) but does not provide additional meaning beyond what the schema offers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it lists population segments for a segmentation with optional filters. This distinguishes it from siblings like list_segmentations (lists segmentations) and get_segment_profile (gets details of a single segment).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use versus alternatives like get_segment_profile or get_geographic_distribution. The context indicates it is for listing segments within a segmentation, but usage boundaries are not described.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool targets a distinct operation: listing segmentations, getting segmentation details, listing segments, getting segment profile, and geographic distribution. Descriptions clearly differentiate them, preventing functional overlap.
All tools follow a consistent 'verb_noun' pattern with 'list_' for enumeration and 'get_' for retrieval. No mixing of conventions.
5 tools is well-scoped for exploring population segmentation data. It covers the necessary query operations without being excessive or too sparse.
Core read operations are present, but the description of 'get_segment_profile' references a non-existent 'get_segment_metrics' tool for sample baselines, indicating a gap. Additionally, there is no tool to list regions, though geographic distribution relies on region codes.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Ask data questions in natural language. Get SQL, insights, and charts from your databases.
Normalized official data with provenance, aggregations, insights, free samples and agent access.
Normalized official data with provenance, aggregations, insights, free samples and agent access.
Query your org's data in natural language — read-only MCP access to SQL, NoSQL, files & warehouses.
Related MCP Servers
- AlicenseBqualityDmaintenanceProvides access to the World Health Organization's Global Health Observatory data, enabling AI assistants to search, retrieve, and analyze comprehensive health indicators, country statistics, disease burden data, and regional health trends through WHO's OData API.1MIT
- AlicenseAqualityCmaintenanceConnects DHIS2 health information systems to AI assistants via the Model Context Protocol, enabling natural language queries for analytics, metadata, and tracker data.13MIT
- AlicenseNot gradedqualityCmaintenanceEnables querying World Health Organization Global Health Observatory data via natural language, free and without authentication.15MIT
- AlicenseAqualityAmaintenanceEnables AI agents to query Kenya health facilities, maternal health indicators, immunization coverage, and disease surveillance data via the DHIS2 public API.3MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/claude-marie/pathways-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server