Skip to content

Commit 111839d

Browse files
Merge pull request #8 from PolicyEngine/mcp
Add MCP server
2 parents 50328d5 + 3581746 commit 111839d

File tree

7 files changed

+357
-2
lines changed

7 files changed

+357
-2
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: Test
33
on:
44
pull_request:
55
push:
6-
branches-ignore:
6+
branches:
77
- main
88

99
jobs:

docs/src/app/mcp/page.tsx

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
export default function McpPage() {
2+
return (
3+
<div className="max-w-4xl">
4+
<h1 className="text-3xl font-semibold text-[var(--color-text-primary)] mb-4">
5+
MCP integration
6+
</h1>
7+
<p className="text-lg text-[var(--color-text-secondary)] mb-8">
8+
Use the PolicyEngine API as an MCP server for AI assistants like Claude.
9+
</p>
10+
11+
<div className="space-y-8">
12+
<section className="p-6 border border-[var(--color-border)] rounded-xl bg-white">
13+
<h2 className="text-xl font-semibold text-[var(--color-text-primary)] mb-4">
14+
What is MCP?
15+
</h2>
16+
<p className="text-sm text-[var(--color-text-secondary)] mb-4">
17+
The Model Context Protocol (MCP) is a standard for AI assistants to interact with external tools and data sources.
18+
The PolicyEngine API exposes all endpoints as MCP tools at <code className="px-1.5 py-0.5 bg-[var(--color-surface-sunken)] rounded text-xs">/mcp</code>,
19+
allowing AI assistants to calculate taxes and benefits, run economic impact analyses, and query policy data.
20+
</p>
21+
</section>
22+
23+
<section className="p-6 border border-[var(--color-border)] rounded-xl bg-white">
24+
<h2 className="text-xl font-semibold text-[var(--color-text-primary)] mb-4">
25+
Add to Claude Code
26+
</h2>
27+
<p className="text-sm text-[var(--color-text-secondary)] mb-4">
28+
Run this command:
29+
</p>
30+
<pre className="p-4 bg-[var(--color-code-bg)] text-[var(--color-code-text)] rounded-lg text-sm overflow-x-auto">
31+
{`claude mcp add --transport http policyengine https://v2.api.policyengine.org/mcp/`}
32+
</pre>
33+
</section>
34+
35+
<section className="p-6 border border-[var(--color-border)] rounded-xl bg-white">
36+
<h2 className="text-xl font-semibold text-[var(--color-text-primary)] mb-4">
37+
Add to Claude Desktop
38+
</h2>
39+
<p className="text-sm text-[var(--color-text-secondary)] mb-4">
40+
Add this to your <code className="px-1.5 py-0.5 bg-[var(--color-surface-sunken)] rounded text-xs">claude_desktop_config.json</code> file:
41+
</p>
42+
<pre className="p-4 bg-[var(--color-code-bg)] text-[var(--color-code-text)] rounded-lg text-sm overflow-x-auto">
43+
{`{
44+
"mcpServers": {
45+
"policyengine": {
46+
"type": "url",
47+
"url": "https://v2.api.policyengine.org/mcp/"
48+
}
49+
}
50+
}`}
51+
</pre>
52+
</section>
53+
54+
<section className="p-6 border border-[var(--color-border)] rounded-xl bg-white">
55+
<h2 className="text-xl font-semibold text-[var(--color-text-primary)] mb-4">
56+
Available tools
57+
</h2>
58+
<p className="text-sm text-[var(--color-text-secondary)] mb-4">
59+
All API endpoints are exposed as MCP tools. Key capabilities include:
60+
</p>
61+
<ul className="text-sm text-[var(--color-text-secondary)] space-y-2 list-disc list-inside">
62+
<li><strong>household_calculate</strong> — calculate taxes and benefits for a household</li>
63+
<li><strong>household_impact</strong> — compare baseline vs reform policy impact</li>
64+
<li><strong>analysis_economic_impact</strong> — run population-wide economic analysis</li>
65+
<li><strong>policies_list</strong> / <strong>policies_create</strong> — manage policy reforms</li>
66+
<li><strong>variables_list</strong> / <strong>parameters_list</strong> — query tax-benefit system metadata</li>
67+
<li><strong>datasets_list</strong> — list available population datasets</li>
68+
</ul>
69+
</section>
70+
71+
<section className="p-6 border border-[var(--color-border)] rounded-xl bg-white">
72+
<h2 className="text-xl font-semibold text-[var(--color-text-primary)] mb-4">
73+
Example prompts
74+
</h2>
75+
<p className="text-sm text-[var(--color-text-secondary)] mb-4">
76+
Once connected, you can ask Claude things like:
77+
</p>
78+
<div className="space-y-3">
79+
<div className="p-3 bg-[var(--color-surface-sunken)] rounded-lg text-sm text-[var(--color-text-secondary)]">
80+
"Calculate the net income for a UK household with two adults earning £40,000 and £30,000"
81+
</div>
82+
<div className="p-3 bg-[var(--color-surface-sunken)] rounded-lg text-sm text-[var(--color-text-secondary)]">
83+
"What would happen to this household's benefits if we increased the personal allowance to £15,000?"
84+
</div>
85+
<div className="p-3 bg-[var(--color-surface-sunken)] rounded-lg text-sm text-[var(--color-text-secondary)]">
86+
"List all the parameters related to child benefit"
87+
</div>
88+
</div>
89+
</section>
90+
</div>
91+
</div>
92+
);
93+
}

docs/src/components/sidebar.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const navigation = [
1010
{ name: "Introduction", href: "/" },
1111
{ name: "Architecture", href: "/architecture" },
1212
{ name: "Quick start", href: "/quickstart" },
13+
{ name: "MCP integration", href: "/mcp" },
1314
],
1415
},
1516
{

docs/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"moduleResolution": "bundler",
1616
"resolveJsonModule": true,
1717
"isolatedModules": true,
18-
"jsx": "preserve",
18+
"jsx": "react-jsx",
1919
"incremental": true,
2020
"plugins": [
2121
{

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ dependencies = [
2121
"logfire[fastapi,httpx,sqlalchemy]>=0.60.0",
2222
"fastapi-cache2>=0.2.1",
2323
"boto3>=1.41.1",
24+
"fastapi-mcp>=0.4.0",
2425
]
2526

2627
[project.optional-dependencies]

src/policyengine_api/main.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from fastapi.middleware.cors import CORSMiddleware
66
from fastapi_cache import FastAPICache
77
from fastapi_cache.backends.inmemory import InMemoryBackend
8+
from fastapi_mcp import FastApiMCP
89
from rich.console import Console
910

1011
from policyengine_api.api import api_router
@@ -60,6 +61,10 @@ async def lifespan(app: FastAPI):
6061

6162
app.include_router(api_router)
6263

64+
# Mount MCP server - exposes all API endpoints as MCP tools at /mcp
65+
mcp = FastApiMCP(app)
66+
mcp.mount()
67+
6368

6469
@app.get("/health")
6570
def health_check():

0 commit comments

Comments
 (0)