Metadata-Version: 2.5
Name: gsa-perdiem-mcp
Version: 1.1.1
Summary: MCP server for GSA Per Diem Rates API. Federal travel lodging and M&IE rates for IGCEs and travel cost estimation.
Project-URL: Homepage, https://1102tools.com
Project-URL: Repository, https://github.com/1102tools-dev/federal-contracting-mcps
Project-URL: Issues, https://github.com/1102tools-dev/federal-contracting-mcps/issues
Author: James Jenrette / 1102tools
License: MIT
Keywords: 1102,federal-contracts,gsa,lodging,mcp,mie,model-context-protocol,per-diem,travel
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: filelock>=3.13
Requires-Dist: httpx>=0.27.0
Requires-Dist: mcp<3,>=2.0.0
Requires-Dist: platformdirs>=4.0
Description-Content-Type: text/markdown

# gsa-perdiem-mcp

[![price: free](https://img.shields.io/badge/price-free-007a59)](https://1102tools.com/#why) [![license: MIT](https://img.shields.io/badge/license-MIT-007a59)](license) [![tools: 7](https://img.shields.io/badge/tools-7-007a59)](#what-it-does) [![regression tests: 542](https://img.shields.io/badge/regression%20tests-542-007a59)](testing.md) [![hosted edition: coming soon](https://img.shields.io/badge/hosted%20edition-coming%20soon-b0770f)](#available-in-claude-and-chatgpt)


<!-- mcp-name: com.1102tools/gsa-perdiem-mcp -->

Free, open-source MCP server for the GSA Per Diem Rates API. Federal travel lodging and M&IE rates for IGCEs and travel cost estimation.

ZIP, state, and M&IE lookups for FY2021 onward work with no key and no network call: they are answered from GSA's published rate, ZIP, and M&IE files bundled in the package. City lookups use the GSA Per Diem API, which resolves city names to rate areas; they work with the shared DEMO_KEY, and a free API key raises the limit. Use the installation and configuration instructions below to connect this MCP directly.

*Tested and hardened through seven rounds of integration testing against the live GSA Per Diem API, including a round-7 independent re-audit with live verification. 542 collected regression tests (275 offline, 267 live-gated) covering 1 P0 path-traversal bug, 23 P1 silent-wrong-data bugs, 21 P2 validation gaps, 14 round-7 findings, and the 1.1.0 rate-area ambiguity fixes. See [testing.md](testing.md) for the full testing record.*

## Available in Claude and ChatGPT

| MCP | Claude | ChatGPT |
|---|---|---|
| GSA Per Diem | Coming soon | Coming soon |

A hosted edition is running at `https://gsa-perdiem.1102tools.com/mcp` and is planned for the Claude and ChatGPT directories. It needs no user API key and no local setup. Locally, a free personal key is recommended; a shared fallback works at low volume. Until the listings are live, use the installation and configuration instructions below, then try a [matching prompt](https://1102tools.com/#gsa-per-diem).

## What it does

Exposes GSA per diem rates as 7 MCP tools:

**Core lookups**
- `lookup_city_perdiem` - Rates by city/state, resolved through the GSA API (optional `county` answers from GSA's county definitions without an API call)
- `lookup_zip_perdiem` - Rates by ZIP code from GSA's ZIP file (optional `county`)
- `lookup_state_rates` - All NSA rates and the standard rate for a state
- `get_mie_breakdown` - M&IE tier table (meal components)
- `get_data_status` - Bundled fiscal years, their GSA source files, and which tools call the API

**Workflow**
- `estimate_travel_cost` - Calculate trip per diem (lodging + M&IE with first/last day at 75%)
- `compare_locations` - Compare rates across multiple cities

**Rate areas are never guessed.** GSA sets rates by county or locality. When a ZIP or city spans more than one rate area with different rates, results have `status: "ambiguous"` and list every candidate; supplying `county` selects one. A city GSA does not recognize is `unresolved` rather than defaulting to the standard rate. When GSA lists several rate areas for a city, Census 2020 place-to-county records break the tie only if they place the city in exactly one of them. Every result names its `source`: the bundled GSA file (with SHA-256) or the API endpoint.

**Bundled data.** `src/gsa_perdiem_mcp/data/` holds FY2021 onward, generated by `scripts/build_snapshot.py` from GSA's per diem files page and Census 2020 place/county code files. `data/manifest.json` records each source URL and SHA-256. The builder fails on schema drift, on any disagreement between GSA's rate and ZIP files, and on locality wording it has not been taught. FY2020 and fiscal years not yet bundled use the API.

## Get your own API key (strongly recommended)

City lookups hit `api.gsa.gov`, which uses api.data.gov for rate limiting.
ZIP, state, and M&IE lookups for bundled fiscal years need no key.

- **Without a key**: city lookups fall back to the shared `DEMO_KEY`, which is
  capped at **~10 requests per hour across everyone using it**. City-heavy
  prompts can exhaust that limit and return 429 errors.
- **With a personal key**: 1,000 requests per hour, yours alone.

**Get a free key (takes 30 seconds):**

1. Go to [api.data.gov/signup](https://api.data.gov/signup/)
2. Enter your name and email: no approval, no wait
3. Copy the key from the confirmation page
4. Paste it into your client config as `PERDIEM_API_KEY` (see below)

The same key works for every api.data.gov-backed API (GSA Per Diem, NASA,
FEC, FCC, etc.).

## Installation

```bash
uvx gsa-perdiem-mcp
```

## Configuration

Use the configuration below as the server definition and adapt its placement to your compatible MCP client. For practical requests using this source, see the [prompt library](https://github.com/1102tools-dev/federal-contracting-prompts).

**Recommended (with your own key):**
```json
{
  "mcpServers": {
    "gsa-perdiem": {
      "command": "uvx",
      "args": ["--refresh-package", "gsa-perdiem-mcp", "--from", "gsa-perdiem-mcp", "gsa-perdiem-mcp"],
      "env": {
        "PERDIEM_API_KEY": "paste-your-api-data-gov-key-here",
        "FEDERAL_API_MIN_INTERVAL_SECONDS": "4"
      }
    }
  }
}
```

The server defaults `FEDERAL_API_MIN_INTERVAL_SECONDS` to `4` for personal-key
and DEMO_KEY requests. The explicit value above documents the intended policy
and can be changed when you have a documented reason. Per Diem and
Regulations.gov processes using the same `api.data.gov` key share the gate.

**Without a key** (works for a handful of calls per hour, then 429s until the hour rolls over):
```json
{
  "mcpServers": {
    "gsa-perdiem": {
      "command": "uvx",
      "args": ["--refresh-package", "gsa-perdiem-mcp", "--from", "gsa-perdiem-mcp", "gsa-perdiem-mcp"]
    }
  }
}
```

The `--refresh-package` flag tells uv to check PyPI for a newer release each time your client launches the server, so fixes arrive automatically; without it, uv keeps serving whatever version it first cached. It adds a moment of network time at startup, so raise your platform's MCP startup timeout if it enforces a short one.

Restart the client and the tools appear.

## Example prompts

- "What's the per diem rate for Washington DC in FY2026?"
- "Estimate travel costs for 4 nights in Boston in March."
- "Compare per diem rates for DC, New York, and San Francisco."
- "What are all the NSA per diem locations in Virginia?"
- "Show me the M&IE meal breakdown for the $92 tier."
- "Build a travel estimate: 3 trips to Seattle (4 nights each) and 2 trips to DC (3 nights each)."

## Important: maximum reimbursement, not actual prices

Per diem rates are federal reimbursement ceilings per 41 CFR 301-11. They are not actual hotel prices. CONUS only. Non-foreign OCONUS rates (Alaska, Hawaii, territories) are set by DoD (DTMO); foreign rates by the State Department. Lodging taxes generally not included. First/last travel day M&IE at 75%.

## Companion tools

Use alongside `bls-oews-mcp` (wage data) and `gsa-calc-mcp` (ceiling rates) for complete IGCE development. Per diem covers the travel component; BLS and CALC+ cover labor.

## Request pacing

| Default setting | Value |
| --- | --- |
| Wait after each upstream request completes | **4 seconds** |
| Maximum upstream requests in flight per pacing identity | **1** |
| Rolling attempt counter in this pacer | **None**; provider quotas still apply |

The next request starts after the previous request's duration **plus 4 seconds**. This is a completion delay, not a 4-second start interval. Local processes sharing the same pacing directory and identity share this gate; a separate local counter does not create additional provider quota.

See the [complete pacing reference](../../docs/pacing.md) for all nine servers, shared credentials/IPs, configuration and hosting differences.

Every request, including DEMO_KEY traffic, uses a provisional 4-second
cross-process anti-burst interval by default. Per Diem and Regulations.gov
share a local `api.data.gov` bucket when they use the same key. This does not
increase provider quota or coordinate the key on another computer. Override
with `FEDERAL_API_MIN_INTERVAL_SECONDS`, use `0` to deliberately disable it,
and use `FEDERAL_API_PACING_DIR` to relocate local pacing state.

## License

MIT
