联邦政府数据服务模板

一个用于构建联邦政府数据集服务的模板,支持通过MCP协议向Claude等客户端暴露数据。

  • by GSA-TTS
  • Python
  • 本地部署
  • 2 星标
  • 更新于
在 GitHub 查看 GSA-TTS/fed-gov-mcp-template

使用说明

联邦政府MCP模板

建筑模板 主控程序 将联邦政府数据集暴露给Claude和其他MCP兼容客户端的服务器。

建于 FastMCP 和 紫外线.


回购结构

fed-gov-mcp-template/
├── src/
│   └── fed_gov_mcp/
│       ├── __init__.py
│       ├── server.py          # FastMCP app + registration calls
│       ├── config.py          # Settings loaded from env vars / .env
│       ├── routes.py          # Custom HTTP routes (health check, etc.)
│       ├── tools/
│       │   ├── __init__.py    # register_tools() aggregator
│       │   └── example.py     # Placeholder tool — replace with your API
│       ├── prompts/
│       │   ├── __init__.py    # register_prompts() aggregator
│       │   └── example.py     # Placeholder prompt
│       └── resources/
│           ├── __init__.py    # register_resources() aggregator
│           └── example.py     # Placeholder resource
├── tests/
│   └── test_tools.py
├── .github/
│   └── workflows/ci.yml       # Lint + test on push/PR
├── Dockerfile                 # For remote HTTP deployment
├── .env.example               # Copy to .env and fill in
├── DEPLOYMENT.md              # Remote deployment guide
├── pyproject.toml
└── main.py                    # Root entry point

入门指南

先决条件

  • 紫外线 — pip install uv 或 brew install uv

安装

cp .env.example .env
uv sync

跑

uv run python main.py
# or
uv run fed-gov-mcp

服务器启动于 stdio 默认情况下,它使用JSON-RPC通过stdin/stdout进行通信,这就是Claude Desktop和Claude Code连接到本地MCP服务器的方式。


添加您的第一个工具

每个联邦数据集集成都位于其自己的文件中 src/fed_gov_mcp/tools/.

步骤1——创建工具文件:

# src/fed_gov_mcp/tools/census.py
import httpx
from fastmcp import FastMCP

from ..config import settings


def register_census_tools(mcp: FastMCP) -> None:
    @mcp.tool()
    def get_state_population(state_fips: str, year: int = 2022) -> dict:
        """Get ACS population estimate for a US state.

        Data source: Census Bureau ACS 1-Year Estimates.
        Updated annually; ~1 year lag (2022 data released late 2023).

        Args:
            state_fips: 2-digit FIPS code (e.g. "06" for California).
            year: Survey year (2010–2022).

        Returns:
            Dict with state name and population estimate.
        """
        with httpx.Client(timeout=30.0) as client:
            response = client.get(
                f"https://api.census.gov/data/{year}/acs/acs1",
                params={
                    "get": "B01001_001E,NAME",
                    "for": f"state:{state_fips}",
                    "key": settings.census_api_key,
                },
            )
            response.raise_for_status()
            header, *rows = response.json()
            return dict(zip(header, rows[0])) if rows else {}

第二步——把它连接起来 tools/__init__.py:

from .census import register_census_tools

def register_tools(mcp: FastMCP) -> None:
    register_example_tools(mcp)
    register_census_tools(mcp)

步骤3-将任何API密钥添加到 config.py:

class Settings(BaseSettings):
    ...
    census_api_key: str = ""  # https://api.census.gov/data/key_signup.html

并将其记录在 .env.example:

CENSUS_API_KEY=your_key_here

添加提示

提示是可重用的消息模板——它们在Claude的UI中显示为对话启动器或斜线命令。

步骤1——创建提示文件:

# src/fed_gov_mcp/prompts/census.py
from fastmcp import FastMCP


def register_census_prompts(mcp: FastMCP) -> None:
    @mcp.prompt()
    def explore_census_data(state: str, topic: str = "population") -> str:
        """Start an exploration session for Census Bureau data.

        Args:
            state: State name or abbreviation to focus on.
            topic: What to investigate — e.g. "population", "income", "housing".
        """
        return (
            f"I want to explore {topic} data for {state} using the Census Bureau ACS. "
            "Please start by describing what estimates are available, "
            "then help me investigate trends and comparisons."
        )

第二步——把它连接起来 prompts/__init__.py:

from .census import register_census_prompts

def register_prompts(mcp: FastMCP) -> None:
    register_example_prompts(mcp)
    register_census_prompts(mcp)

添加资源

资源公开静态或半静态数据(引用表、数据字典、模式),Claude可以直接读取这些数据,而无需调用工具。

步骤1——创建资源文件:

# src/fed_gov_mcp/resources/census.py
from fastmcp import FastMCP


def register_census_resources(mcp: FastMCP) -> None:
    @mcp.resource("census://reference/state-fips")
    def state_fips_codes() -> str:
        """FIPS code reference table for all US states and territories.

        Use these codes as the state_fips argument when calling Census tools.
        """
        return (
            "State FIPS Code Reference\n\n"
            "01 Alabama    02 Alaska     04 Arizona    05 Arkansas\n"
            "06 California 08 Colorado   09 Connecticut ...\n"
            "(replace with full table or load from a bundled CSV)"
        )

对于参数化资源,在URI中包含一个路径变量:

    @mcp.resource("census://docs/{topic}")
    def census_docs(topic: str) -> str:
        """API documentation for a Census Bureau topic."""
        docs = {
            "acs1": "ACS 1-Year: annual, areas ≥65k population ...",
            "acs5": "ACS 5-Year: rolling average, all geographies ...",
        }
        return docs.get(topic, f"No documentation found for topic '{topic}'.")

第二步——把它连接起来 resources/__init__.py:

from .census import register_census_resources

def register_resources(mcp: FastMCP) -> None:
    register_example_resources(mcp)
    register_census_resources(mcp)

添加自定义HTTP路由

自定义路线仅在以下情况下处于活动状态 MCP_TRANSPORT=streamable-http.在中添加基础设施端点(就绪性探测、版本信息、指标) routes.py 而不是 server.py.

# src/fed_gov_mcp/routes.py
from fastmcp import FastMCP
from starlette.requests import Request
from starlette.responses import JSONResponse


def register_routes(mcp: FastMCP) -> None:
    @mcp.custom_route("/health", methods=["GET"])
    async def health_check(request: Request) -> JSONResponse:
        return JSONResponse({"status": "healthy", "service": "mcp-server"})

    @mcp.custom_route("/version", methods=["GET"])
    async def version(request: Request) -> JSONResponse:
        return JSONResponse({"version": "1.0.0"})

配置

所有设置都是从环境变量加载的(或 .env).

变量 默认值 描述
MCP_TRANSPORT stdio stdio 对于本地, streamable-http 用于远程
MCP_HOST 0.0.0.0 绑定地址(仅限HTTP模式)
MCP_PORT 8000 端口(仅限HTTP模式)

在中添加特定于数据集的键作为键入字段 src/fed_gov_mcp/config.py.


连接到克劳德

克劳德代码(本地标准)

添加到您的项目 .claude/settings.json 或用户MCP设置:

{
  "mcpServers": {
    "fed-gov-mcp": {
      "command": "uv",
      "args": ["run", "fed-gov-mcp"],
      "cwd": "/absolute/path/to/fed-gov-mcp-template"
    }
  }
}

克劳德桌面(本地stdio)

添加 ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)或 %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "fed-gov-mcp": {
      "command": "uv",
      "args": ["run", "fed-gov-mcp"],
      "cwd": "/absolute/path/to/fed-gov-mcp-template"
    }
  }
}

远程HTTP

看 部署.md 了解云部署说明。部署后,连接到:

{
  "mcpServers": {
    "fed-gov-mcp": {
      "type": "http",
      "url": "https://your-server.example.com/mcp"
    }
  }
}

发展

# Install dev dependencies
uv sync --group dev

# Run tests
uv run pytest tests/ -v

# Lint
uv run ruff check .

# Format
uv run ruff format .

设计说明

每个数据集一个文件

每个联邦API都有自己的文件 tools/。这使工具列表可扫描,并允许您通过触摸中的两行来添加或删除整个集成 tools/__init__.py.

返回结构化数据,而不是散文

返回 dict/list 使用一致的密钥。让Claude叙述和解释数据,而不是在工具实现中构建叙述。

明确记录新鲜度

联邦数据集往往存在发布滞后。在工具文档字符串中说明更新频率和“截至”日期。克劳德将在相关时向用户展示这一点。

显示分页参数

大多数联邦API都会分页。要么暴露 offset/limit 对于调用者,或者在内部处理多页获取——但要记录您选择的文档以及最大合理值 limit 岛

使用显式超时

联邦API可能很慢或间歇性无响应。总是通过 timeout=30.0 (对于大型出口,则更高) httpx.Client.

永远不要在没有时间戳的情况下缓存

可以缓存参考数据(州FIPS代码、机构列表)。不应缓存时间敏感的数据(支出数据、健康统计数据)而不显示 retrieved_at 或 as_of 响应中的字段。


远程部署

看 部署.md.