@fedpulse/mcp
v1.0.2
Published
Model Context Protocol server for FedPulse — federal contract, exclusion, entity, grant, and wage data for AI agents
Maintainers
Readme
@fedpulse/mcp — FedPulse MCP Server
A Model Context Protocol (MCP) server that exposes the entire FedPulse API surface to AI assistants such as Claude Desktop, Copilot, and any MCP-compatible agent.
Two transports are supported:
| Transport | Use case |
|-----------|----------|
| Stdio (npx @fedpulse/mcp) | Local Claude Desktop / Cursor integration |
| HTTP+SSE (node src/http-server.js) | Hosted cloud service at https://mcp.fedpulse.dev |
Quick Start — Claude Desktop (stdio)
Get your FedPulse API key from app.fedpulse.dev.
Open
~/Library/Application Support/Claude/claude_desktop_config.json(macOS) or%APPDATA%\Claude\claude_desktop_config.json(Windows) and add:
{
"mcpServers": {
"fedpulse": {
"command": "npx",
"args": ["@fedpulse/mcp"],
"env": {
"FEDPULSE_API_KEY": "fp_live_your_key_here"
}
}
}
}- Restart Claude Desktop. You will see 14 new tools prefixed
fedpulse.
Quick Start — HTTP Server (self-hosted or https://mcp.fedpulse.dev)
# Environment variables
export FEDPULSE_API_KEY=fp_live_your_key_here # passed to the API for each caller
export PORT=3100 # default: 3100
export ALLOWED_ORIGINS=https://your-app.com # optional CORS allowlist (comma-separated)
node src/http-server.jsConnect any MCP HTTP client to http://localhost:3100/mcp using Bearer <api_key> or X-Api-Key: <api_key> authentication.
Environment Variables
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| FEDPULSE_API_KEY | Yes | — | Your FedPulse API key. Passed as the API credential for every request. |
| FEDPULSE_BASE_URL | No | https://api.fedpulse.dev | Override API base URL (staging, local dev). |
| FEDPULSE_TIMEOUT_MS | No | 15000 | Per-request timeout in milliseconds. |
| PORT | No | 3100 | HTTP server port (HTTP transport only). |
| HOST | No | 0.0.0.0 | HTTP server bind address. |
| ALLOWED_ORIGINS | No | * | Comma-separated CORS origins for the HTTP server. |
Tools (14 total)
Opportunities
| Tool | Description |
|------|-------------|
| search_opportunities | Full-text + structured search across all federal contract opportunities. Supports NAICS codes, agency, set-aside type, notice type, date ranges, award amounts, and AI-powered fields like categories and keywords. |
| get_opportunity | Fetch complete details for a single opportunity by noticeId. |
| get_similar_opportunities | Find opportunities similar to a given one, matched by NAICS code. |
Exclusions & Compliance
| Tool | Description |
|------|-------------|
| check_exclusion | Check whether a single entity (by UEI, CAGE, or name) appears on the SAM.gov exclusions list. Returns a clear EXCLUDED / NOT EXCLUDED verdict with details. |
| bulk_compliance_check | Submit up to 100 entities for exclusion screening in a single call. Returns a per-entity verdict table plus a summary count. |
Entities
| Tool | Description |
|------|-------------|
| get_entity_profile | Full SAM.gov entity profile including registration status, NAICS codes, certifications (8(a), WOSB, SDVOSB, etc.), and contact info. |
| search_entities | Search the SAM.gov entity registry by business name, NAICS code, state, certifications, or registration status. |
| get_entity_contracts | Award history for a registered entity (by UEI). |
Intelligence
| Tool | Description |
|------|-------------|
| get_entity_360 | Cross-dataset 360° profile for an entity: entity record + exclusion status + recent opportunities + market position. |
| get_market_analysis | Market intelligence for a NAICS code: award trends, top agencies, top awardees, opportunity pipeline, and competition metrics. |
| get_agency_profile | Aggregated contracting profile for a federal agency: NAICS distribution, award count, recent activity, and top categories. |
Assistance / Grants
| Tool | Description |
|------|-------------|
| search_grants | Search federal grant opportunities (Assistance Listings). Supports full-text, agency, assistance type, eligibility, and status filters. |
| get_grant | Fetch a grant program by its CFDA program number (e.g., "10.001"). |
Wages
| Tool | Description |
|------|-------------|
| get_wage_determination | Look up Service Contract Act (SCA) or Davis-Bacon Act (DBA) wage determinations by state, county, and type. Returns the most recent revision plus all historical revisions. |
Resources (6 URI templates)
Resources can be fetched by MCP-compatible clients using the fedpulse:// scheme:
| URI Template | Description |
|-------------|-------------|
| fedpulse://opportunities/{noticeId} | Single opportunity record (JSON) |
| fedpulse://entities/{uei} | Entity registration record (JSON) |
| fedpulse://exclusions/{exclusionId} | Exclusion record (JSON) |
| fedpulse://grants/{programNumber} | Grant/assistance listing (JSON) |
| fedpulse://markets/{naics} | Market analysis for a NAICS code (JSON) |
| fedpulse://agencies/{departmentSlug} | Agency contracting profile (JSON), slug is hyphenated department name |
Prompts (3 workflow templates)
Built-in, multi-step LLM workflow prompts that chain multiple tools automatically:
| Prompt | Arguments | Description |
|--------|-----------|-------------|
| find_opportunities_for_vendor | uei, limit? | Full 5-step vendor opportunity discovery: profile check → exclusion check → NAICS-matched search → dedup → ranked shortlist. |
| compliance_check_before_award | uei | Pre-award due-diligence workflow: SAM status + exclusion active record check + 360° intelligence + structured red-flag report. |
| market_brief | naics, context? | Full market brief generation: market analysis + active opportunity search + optional agency profiles → formatted narrative brief. |
Architecture
mcp/
├── bin/
│ └── cli.js # Stdio entry point (npx @fedpulse/mcp)
├── src/
│ ├── server.js # buildMcpServer(client) — wires all tools, resources, prompts
│ ├── http-server.js # HTTP+SSE transport server
│ ├── client.js # FedPulseClient — retry, cache-aside, circuit-breaker
│ ├── cache.js # Zero-dependency LRU cache with TTL
│ ├── errors.js # Error classes + formatToolError()
│ ├── tools/
│ │ ├── opportunities.js # search_opportunities, get_opportunity, get_similar_opportunities
│ │ ├── exclusions.js # check_exclusion, bulk_compliance_check
│ │ ├── entities.js # get_entity_profile, search_entities, get_entity_contracts
│ │ ├── intelligence.js # get_entity_360, get_market_analysis, get_agency_profile
│ │ ├── assistance.js # search_grants, get_grant
│ │ └── wages.js # get_wage_determination
│ ├── resources/
│ │ └── index.js # 6 ResourceTemplate registrations
│ └── prompts/
│ └── index.js # 3 multi-step workflow prompts
└── package.jsonDesign Decisions
LRU Cache with domain-aware TTLs: Results are cached in-process using an O(1) doubly-linked-list LRU to prevent redundant API calls during a session. TTLs are tuned by data volatility (wages: 6h; market analysis: 1h; exclusion checks: 2min; opportunity search: 60s).
Circuit-breaker on auth failures: A single confirmed 401 sets _authFailed = true on the client, short-circuiting all subsequent calls with an immediate FedPulseAuthError — no wasted retries.
Retry with full-jitter exponential backoff: Transient 502/503/504 errors and network failures trigger up to 3 retries with sleep = rand(0, min(cap, base * 2^attempt)) where base=100ms, cap=10s. Rate-limit 429 retries respect the Retry-After response header.
Per-session server instances (HTTP transport): Each HTTP client connection gets its own FedPulseClient + McpServer pair keyed by Mcp-Session-Id. Sessions idle for more than 30 minutes are garbage-collected by a background sweep.
Stdio isolation: All diagnostic output (startup messages, errors) goes to stderr. stdout is reserved exclusively for MCP protocol frames.
Development
cd mcp
npm install
# Run tests
npm test
# Run stdio server locally
FEDPULSE_API_KEY=fp_test node bin/cli.js
# Run HTTP server locally
FEDPULSE_API_KEY=fp_test node src/http-server.jsSecurity
- API keys are never logged. The
FedPulseClientredacts the key from all error messages. - HTTP server enforces per-IP sliding-window rate limiting (120 req/min) backed entirely in-process (no Redis dependency at the MCP layer).
- Request bodies are capped at 512 KB.
- CORS origins are restricted to
ALLOWED_ORIGINSwhen set. - The server runs auth validation before any MCP frame is parsed.
Community
- 💬 Discord — Ask questions, share what you build with AI agents, get help in
#mcp-ai-agents - 🔧 Dashboard — Manage API keys
- 📖 MCP Docs — Full MCP documentation
- 🐛 Bug reports — GitHub Issues for the API
License
MIT — See LICENSE.
