PM Context MCP Server
A Python MCP server that gives Claude access to PM workflow data (sprints, roadmap, blockers, workload) so you can ask it questions a PM actually needs answered.
No API keys required. Runs entirely on synthetic fixture data representing a fictional product team ("Petal & Co"). Designed to be forked and connected to a real Linear or Jira workspace privately.
<img src="Demo-mcp.jpg" alt="Demo of Claude answering a sprint question using the MCP server" width="50%">
---
The Problem
PMs spend a disproportionate amount of time context-switching: checking Linear for sprint status, Confluence for the roadmap, Slack for who's blocked. Each lookup is a tab, a search, a few seconds of reorientation.
The bigger problem is that the questions PMs ask are aggregate and cross-cutting ("what should I focus on today?", "who's overloaded?", "what's actually blocking us?") but the tools expose raw CRUD. You have to do the aggregation yourself.
This MCP server exposes PM-oriented tools to Claude so those questions get answered in one place, with actual data behind them.
---
Architecture
Claude (Desktop or CLI)
│
│ MCP (stdio transport)
▼
pm-mcp-server (FastMCP)
│
│ loads
▼
data/fixture.json ← synthetic Petal & Co dataset
(or real Linear / Jira API in a private fork)
The server runs as a local subprocess. Claude calls tools over stdio; no network, no auth for the demo.
---
Tools
| Tool | What Claude can ask | |------|---------------------| | get_current_sprint_tool | "What's in the current sprint?" / "How close are we to done?" | | get_my_issues_tool | "What's on Priya's plate right now?" | | get_blockers_tool | "What's blocking the team?" / "What should we unblock first?" | | search_issues_tool | "Find all issues related to payments" | | get_roadmap_tool | "How far along are we on each epic?" | | get_team_workload_tool | "Who has the most issues assigned?" / "Show me the Growth team's workload" | | get_velocity_tool | "What's our sprint velocity trend?" |
---
How to Run
Requirements: Python 3.10+, uv
# Clone and enter the repo
git clone https://github.com/jackhendon/pm-mcp-server
cd pm-mcp-server
# Install dependencies
uv sync
# Test a tool directly
uv run python -c "from tools.sprints import get_current_sprint; import json; print(json.dumps(get_current_sprint(), indent=2))"
# Run the MCP inspector (requires mcp[cli])
uv run mcp dev server.py
Connect to Claude Desktop
Add this to your claude_desktop_config.json:
{
"mcpServers": {
"pm-context": {
"command": "/Users/yourname/.local/bin/uv",
"args": ["--directory", "/path/to/pm-mcp-server", "run", "python", "server.py"]
}
}
}
Note: Claude Desktop on macOS doesn't inherit your shell PATH, so
uvmust be an absolute path. Runwhich uvin your terminal to find it.
Config location:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Restart Claude Desktop. You should see pm-context listed under connected tools.
Connect to Claude Code (CLI)
claude mcp add pm-context uv run python server.py --cwd /path/to/pm-mcp-server
Try these prompts
- "What's in the current sprint and how close are we to finishing?"
- "Who has the most work on their plate right now?"
- "What's blocking the team and what should we unblock first?"
- "How has our sprint velocity trended over the last few sprints?"
- "What's the roadmap looking like across all epics?"
- "Find all issues related to API authentication"
---
Fixture Data: Petal & Co
The synthetic dataset represents a fictional gift-card startup's product team:
- 6 team members across 2 teams (Growth, Core)
- 3 projects: Checkout Redesign, API Platform v2, Gifting Suite
- 3 epics at different stages of completion
- 17 issues in the active sprint (Sprint 14) with realistic statuses and blockers
- 4 completed sprints for velocity calculation
The data is rich enough that all 7 tools return genuinely interesting and differentiated results.
---
Real API Mode
This repo is designed to be forked privately and connected to a real Linear or Jira workspace.
- Fork the repo
- Copy
.env.exampleto.envand add your credentials - Implement
tools/integrations/linear.pyortools/integrations/jira.pythat returns data in the same shape as the fixture - Update
tools/__init__.pyto route to the real integration based onDATA_SOURCEenv var
The tool signatures and return shapes stay the same. Claude doesn't know or care whether the data comes from a fixture or a live API.











