Reference
MCP server docs
Everything an agent or a developer needs: the wire protocol, both tiers, and every tool with typed parameters and response fields. Run anything for real in the playground. Agents can read this site as markdown via /llms.txt or fetch this page as markdown at /mcp/docs.md.
Get started
- Add the server to your client below. The free tier needs no account.
- Ask a question: "What changed in California healthcare regulations this month? Cite every source."
- Optional: add an API key, bought with credits or included with the Professional plan, for full history and higher limits.
claude mcp add --transport http bizmoon https://bizmoon.ai/api/mcp
With an API key, for full history and your organization's tools:
claude mcp add --transport http bizmoon https://bizmoon.ai/api/mcp \ --header "Authorization: Bearer bm_sk_..."
In Claude.ai or Claude Desktop, open Settings, then Connectors, then Add custom connector, and paste https://bizmoon.ai/api/mcp. For a key, add a request header named Authorization with the value Bearer bm_sk_....
Protocol
The server speaks Model Context Protocol over stateless Streamable HTTP at one endpoint:
https://bizmoon.ai/api/mcp
Send JSON-RPC 2.0 by POST with content-type: application/json and accept: application/json, text/event-stream. Responses arrive as server-sent events; the JSON-RPC message is on the last data: line. No session is required: initialize is optional and every request stands alone, so scheduled jobs can call a tool directly.
List the tools available to your credentials:
curl -s -X POST https://bizmoon.ai/api/mcp \
-H "content-type: application/json" \
-H "accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'Tool results wrap their payload as JSON text in result.content[0].text, with result.isError set on failures. All tools are read-only and annotated as such.
A complete call, in JavaScript:
const res = await fetch("https://bizmoon.ai/api/mcp", {
method: "POST",
headers: {
"content-type": "application/json",
accept: "application/json, text/event-stream",
// With an API key: authorization: "Bearer bm_sk_..."
},
body: JSON.stringify({
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_regulatory_changes",
"arguments": {
"jurisdiction": "CA",
"keyword": "health",
"limit": 5
}
}
}),
});
const text = await res.text();
const line = text.split("
").filter((l) => l.startsWith("data: ")).pop();
const msg = JSON.parse(line ? line.slice(6) : text);
const payload = JSON.parse(msg.result.content[0].text);
console.log(payload);Auth and limits
No authentication is required for the free tier. An API key is sent as a bearer header and unlocks full history and higher limits. Buy one with prepaid credits at /mcp/start, or get it with the Professional plan, which also adds the organization tools:
Authorization: Bearer bm_sk_...
| Free | API key | |
|---|---|---|
| History | Last 90 days | Everything |
| Results per call | 10 | 50 |
| Rate limit | 30 per min, 300 per day per visitor | 60 per min per key, 1,000 per day per organization |
| Tools | 5 public | 5 public + 5 organization |
Where the key goes, per client. The header is the same everywhere:
| Claude Code | claude mcp add ... --header "Authorization: Bearer bm_sk_..." |
| Claude.ai and Claude Desktop | Settings, Connectors, Add custom connector: an org admin adds a request header named Authorization |
| OpenAI and xAI APIs | "authorization": "bm_sk_..." beside server_url on the mcp tool |
| Gemini CLI | headers: { "Authorization": "Bearer bm_sk_..." } beside httpUrl |
| OpenClaw | headers: { "Authorization": "Bearer bm_sk_..." } on the server entry |
| Cursor, VS Code, Windsurf | headers: { "Authorization": "Bearer bm_sk_..." } in the MCP config |
| cURL or any HTTP client | -H "authorization: Bearer bm_sk_..." |
| REST API (/api/v1) | Same bearer header on every request |
A missing or malformed header simply falls back to the free tier; an invalid bm_sk_ key returns HTTP 401.
Search regulations
search_regulatory_changes
Search rules and notices across every register Bizmoon monitors, newest first, each with an AI summary and the official source URL. Funding opportunities are left out; search_funding_programs covers those.
| Parameter | Type | Required | Description |
|---|---|---|---|
| jurisdiction | string | no | US_FED for federal, or a two-letter state code such as CA (US_STATE_CA also works). Omit for all jurisdictions. Unrecognized values return a tool error instead of silently widening the search.e.g. "CA" |
| agency | string | no | Case-insensitive substring match on the issuing agency name.e.g. "Department of Public Health" |
| category | string | no | Either "regulation" or "funding". Omit to search regulations and uncategorized documents while leaving funding opportunities out. Pass "funding" to search those here instead.e.g. "regulation" |
| keyword | string | no | Case-insensitive substring matched against title, AI summary, and description.e.g. "health" |
| from | string (date) | no | YYYY-MM-DD. Only documents published on or after this date. The free tier floors this at 90 days ago and reports the clamp in lookbackClampedTo.e.g. "2026-08-01" |
| to | string (date) | no | YYYY-MM-DD. Only documents published on or before this date (the whole day is included).e.g. "2026-09-01" |
| limit | integer | no | Max results per call. Default 20. Free tier caps at 25, API key at 50.e.g. 10 |
| offset | integer | no | Pagination offset. Default 0. Ask again with offset advanced by your limit until offset plus the results you have reaches total. A page is a snapshot: documents published between calls shift the window, so a recurring agent should advance its date rather than page far.e.g. 20 |
Responses include total (all matches), the page of results, and lookbackClampedTo when the free-tier window was applied.
Every result carries publishedDate, effectiveDate, agencies, an AI summary, and the canonical url to cite.
Request
Try it in the playground →curl -s -X POST https://bizmoon.ai/api/mcp \
-H "content-type: application/json" \
-H "accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search_regulatory_changes","arguments":{"jurisdiction":"CA","keyword":"health","limit":5}}}'
# key tier: add -H "authorization: Bearer bm_sk_..."Response fields
| Field | Type | Description |
|---|---|---|
| results[].id | string | Document id; pass to get_regulatory_change |
| results[].title | string | null | Document title |
| results[].jurisdiction | string | US_FED or US_STATE_XX |
| results[].source | string | The official register the document came from |
| results[].agencies | string[] | Issuing agencies |
| results[].category | string | null | "regulation", "funding", or null when unclassified |
| results[].docType | string | null | Source-specific document type |
| results[].publishedDate | string | null | YYYY-MM-DD publication date |
| results[].effectiveDate | string | null | YYYY-MM-DD effective date when stated |
| results[].summary | string | null | AI summary of the document |
| results[].url | string | null | Canonical official URL to cite |
| total | integer | All matches, not just this page |
| offset | integer | Offset this page started at |
| limit | integer | Effective limit after tier clamping |
| lookbackClampedTo | string | null | ISO timestamp the window was floored to on the free tier, else null |
Read one document
get_regulatory_change
One document in full: agencies, published and effective dates, summary, description, and the canonical URL to cite.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | yes | The document id returned by search_regulatory_changes, changes_since, or search_funding_programs.e.g. "278724" |
Unknown ids return { "error": "not_found", "id": "..." } as a normal result.
Request
Try it in the playground →curl -s -X POST https://bizmoon.ai/api/mcp \
-H "content-type: application/json" \
-H "accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_regulatory_change","arguments":{"id":"304959"}}}'
# key tier: add -H "authorization: Bearer bm_sk_..."Response fields
| Field | Type | Description |
|---|---|---|
| id | string | Document id |
| title | string | null | Document title |
| jurisdiction | string | US_FED or US_STATE_XX |
| source | string | The official register |
| agencies | string[] | Issuing agencies |
| category | string | null | "regulation", "funding", or null |
| docType | string | null | Source-specific document type |
| publishedDate | string | null | YYYY-MM-DD |
| effectiveDate | string | null | YYYY-MM-DD when stated |
| summary | string | null | AI summary |
| description | string | null | Longer extracted description |
| categories | string[] | Source-provided category labels |
| url | string | null | Canonical official URL to cite |
Show coverage
list_jurisdictions
Coverage and freshness for every source: the latest publication and when the register was last checked.
No parameters.
Call this first in a session to learn what data exists and how fresh it is.
jurisdiction values from this tool are exactly what the other tools accept.
Request
Try it in the playground →curl -s -X POST https://bizmoon.ai/api/mcp \
-H "content-type: application/json" \
-H "accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_jurisdictions","arguments":{}}}'
# key tier: add -H "authorization: Bearer bm_sk_..."Response fields
| Field | Type | Description |
|---|---|---|
| jurisdictions[].jurisdiction | string | US_FED or US_STATE_XX |
| jurisdictions[].source | string | Register name |
| jurisdictions[].slug | string | Stable source identifier |
| jurisdictions[].lastRunAt | string | null | ISO timestamp the register was last checked |
| jurisdictions[].lastRunStatus | string | null | "success", "error", or "empty_clean" |
| jurisdictions[].latestPublished | string | null | YYYY-MM-DD of the newest document |
What changed since a date
changes_since
Everything published since a date, newest first. Built for scheduled agents: store the newest publishedDate you saw and pass it back next run.
| Parameter | Type | Required | Description |
|---|---|---|---|
| since | string (date or ISO timestamp) | yes | Documents published on or after this moment.e.g. "2026-08-25" |
| jurisdiction | string | no | US_FED for federal, or a two-letter state code such as CA (US_STATE_CA also works). Omit for all jurisdictions. Unrecognized values return a tool error instead of silently widening the search.e.g. "CA" |
| limit | integer | no | Max results per call. Default 20. Free tier caps at 25, API key at 50.e.g. 10 |
| offset | integer | no | Pagination offset. Default 0. Ask again with offset advanced by your limit until offset plus the results you have reaches total. A page is a snapshot: documents published between calls shift the window, so a recurring agent should advance its date rather than page far.e.g. 20 |
For a recurring run, advance `since` to the newest publishedDate you stored rather than paging: it stays correct as new documents arrive and never re-reads what you already have.
Request
Try it in the playground →curl -s -X POST https://bizmoon.ai/api/mcp \
-H "content-type: application/json" \
-H "accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"changes_since","arguments":{"since":"2026-09-11","jurisdiction":"US_FED","limit":5}}}'
# key tier: add -H "authorization: Bearer bm_sk_..."Response fields
| Field | Type | Description |
|---|---|---|
| results[].id | string | Document id; pass to get_regulatory_change |
| results[].title | string | null | Document title |
| results[].jurisdiction | string | US_FED or US_STATE_XX |
| results[].source | string | The official register the document came from |
| results[].agencies | string[] | Issuing agencies |
| results[].category | string | null | "regulation", "funding", or null when unclassified |
| results[].docType | string | null | Source-specific document type |
| results[].publishedDate | string | null | YYYY-MM-DD publication date |
| results[].effectiveDate | string | null | YYYY-MM-DD effective date when stated |
| results[].summary | string | null | AI summary of the document |
| results[].url | string | null | Canonical official URL to cite |
| total | integer | All matches, not just this page |
| offset | integer | Offset this page started at |
| limit | integer | Effective limit after tier clamping |
| lookbackClampedTo | string | null | ISO timestamp the window was floored to on the free tier, else null |
Find funding
search_funding_programs
Federal and state grants and incentive programs, with deadlines and the official program page.
| Parameter | Type | Required | Description |
|---|---|---|---|
| jurisdiction | string | no | US_FED for federal, or a two-letter state code such as CA (US_STATE_CA also works). Omit for all jurisdictions. Unrecognized values return a tool error instead of silently widening the search.e.g. "CA" |
| agency | string | no | Case-insensitive substring match on the issuing agency or program office.e.g. "Commerce" |
| keyword | string | no | Case-insensitive substring matched against title, AI summary, and description.e.g. "manufacturing" |
| from | string (date) | no | YYYY-MM-DD lower bound on publication date (free tier floors at 90 days ago). |
| to | string (date) | no | YYYY-MM-DD upper bound on publication date, inclusive. |
| limit | integer | no | Max results per call. Default 20. Free tier caps at 25, API key at 50.e.g. 10 |
| offset | integer | no | Pagination offset. Default 0. Ask again with offset advanced by your limit until offset plus the results you have reaches total. A page is a snapshot: documents published between calls shift the window, so a recurring agent should advance its date rather than page far.e.g. 20 |
Request
Try it in the playground →curl -s -X POST https://bizmoon.ai/api/mcp \
-H "content-type: application/json" \
-H "accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search_funding_programs","arguments":{"jurisdiction":"OH","keyword":"manufactur","limit":5}}}'
# key tier: add -H "authorization: Bearer bm_sk_..."Response fields
| Field | Type | Description |
|---|---|---|
| results[].id | string | Document id; pass to get_regulatory_change |
| results[].title | string | null | Document title |
| results[].jurisdiction | string | US_FED or US_STATE_XX |
| results[].source | string | The official register the document came from |
| results[].agencies | string[] | Issuing agencies |
| results[].category | string | null | "regulation", "funding", or null when unclassified |
| results[].docType | string | null | Source-specific document type |
| results[].publishedDate | string | null | YYYY-MM-DD publication date |
| results[].effectiveDate | string | null | YYYY-MM-DD effective date when stated |
| results[].summary | string | null | AI summary of the document |
| results[].url | string | null | Canonical official URL to cite |
| total | integer | All matches, not just this page |
| offset | integer | Offset this page started at |
| limit | integer | Effective limit after tier clamping |
| lookbackClampedTo | string | null | ISO timestamp the window was floored to on the free tier, else null |
Organization tools
With an API key, five more tools return data scoped to your own organization. Same wire format; nothing here is visible to other organizations or to the free tier.
Search your analyses
search_analyses
The AI relevance analyses Bizmoon produced for your organization: severity, urgency, affected areas, recommended actions.
severityurgencyareacategorykeyworddays
Read one analysis
get_document_details
Full analysis by analysisId: key provisions, compliance deadlines, funding details, and the underlying document.
analysisId
Upcoming deadlines
get_compliance_deadlines
Compliance deadlines extracted from your analyses, with days remaining and overdue flags.
days
Watchlist matches
get_watchlist_matches
Documents that matched your organization's watchlists recently.
days
Funding for you
get_funding_opportunities
Grant and funding analyses relevant to your organization, with deadlines and funding details.
days
REST API
Two doors to the same data. The MCP server is built for AI agents: tools, natural-language friendly, free tier included. The REST API is plain HTTP for your own code: the organization tools as JSON endpoints, always key-authenticated. One bm_sk_ key opens both.
| Method | Path | Returns |
|---|---|---|
| POST | /analyses/search | Search your organization's policy analyses |
| GET | /analyses/{id} | One analysis in full, with the underlying document |
| GET | /deadlines | Upcoming compliance deadlines |
| GET | /funding | Funding opportunities for your organization |
| GET | /watchlist/matches | Recent watchlist matches |
| GET | /reports | Generated compliance reports |
curl -s https://bizmoon.ai/api/v1/deadlines \ -H "authorization: Bearer bm_sk_..."
Base URL https://bizmoon.ai/api/v1, machine-readable spec at /api/v1/openapi.json. Limits: 60 requests per minute per key, 1,000 per day per organization. Public regulatory search is MCP-only; use the MCP server (or a scheduled agent) for that.
Errors
Failures come back as normal tool results with isError: true and a JSON payload your agent can read and act on. The three shapes:
Rate limited
{
"error": "rate_limited",
"retryAfterSeconds": 42,
"tier": "anon",
"upgrade": "https://bizmoon.ai/pricing"
}Tool failed
{
"error": "tool_failed",
"message": "Unknown jurisdiction \"California\". Use US_FED or a two-letter state code such as CA."
}Not found
{
"error": "not_found",
"id": "999999999"
}An invalid API key is the one HTTP-level failure: status 401 (or 403 for a plan without MCP access) with a JSON body { "error": "..." }.