MCP server (api.exchek.us/mcp)
ExChek runs a hosted Model Context Protocol server at https://api.exchek.us/mcp. Point any MCP-capable agent at it and you get all 20 ExChek skills plus live EAR/ITAR data as tools and resources — no local install, no auth, no API key. The client supplies its own LLM; we supply the content and the data.
https://api.exchek.us/mcp/mcp — free, public, edge-cached. The exceptions: get_classification_pdf_contract and create_classification_pdf are Enterprise tools. Authenticate either by signing in (add /mcp/pro as a connector — claude.ai, Claude Desktop) or with an API key header (Claude Code, Cursor, SDKs). See Enterprise below.This hosted MCP vs. the local plugin
The hosted MCP is the recommended default — no install, always current, and it serves the same 20 skills. The local plugin is still fully supported but will be retired in a future release; prefer the hosted MCP for new setups.
| Situation | Use |
|---|---|
| Most users — any AI client that speaks MCP (Claude, Cursor, Manus, OpenAI Codex, custom agents) | This MCP server (recommended). No install, always current; same skill content over the network |
| Browser-only / no shell access | This MCP server, or call the REST endpoints directly |
| You want offline use, the local DOCX converter, or audit-log signing (Claude Code / Desktop / Cowork / Cursor) | Local plugin install — still available; retiring soon |
| Air-gapped network | Local plugin install (download the release zip) — still available; retiring soon |
Connect your client
Claude Desktop (or any client using the standard MCP config)
Add ExChek to your client config. For Claude Desktop, edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"exchek": {
"url": "https://api.exchek.us/mcp",
"transport": "streamable-http"
}
}
}Restart Claude Desktop. ExChek tools and resources will appear in the tool picker.
Cursor
Open Settings → MCP, add a new server with name exchek, URL https://api.exchek.us/mcp, transport streamable-http.
Codex CLI
codex mcp add exchek --url https://api.exchek.us/mcpMCP Inspector (debug + try it out)
npx @modelcontextprotocol/inspector --uri https://api.exchek.us/mcpOpens a UI where you can list resources, browse tools, and run calls interactively. Best way to verify the connection works before wiring it into a real agent.
Raw curl (for testing or shell scripts)
# initialize
curl -sS -X POST https://api.exchek.us/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
# list available skills
curl -sS -X POST https://api.exchek.us/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_skills","arguments":{}}}'
# fetch one skill's SKILL.md
curl -sS -X POST https://api.exchek.us/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get_skill","arguments":{"name":"exchek-csl"}}}'Discovery
api.exchek.us/.well-known/mcp returns the canonical discovery document: protocol version, server info, tool/resource counts, and the endpoint URL. Use it to check capabilities without a full initialize handshake.
Tools
The server exposes 43 tools — 18 free (skill + eCFR lookups — including full section & ECCN control text — the enforcement feed, free denied-party screening against the Consolidated Screening List, plus six legal & regulatory research tools) and 25 Enterprise (disclosed only to authenticated callers). The 14 document tools are listed parametrically (one get_<doc>_pdf_contract + one create_<doc>_pdf per document type):
| Tool | What it does | Required args |
|---|---|---|
list_skills | Returns all 20 skills with name + description + upstream link. | — |
get_skill | Fetches the SKILL.md (markdown) for one skill. Load this into your LLM’s context to run the skill. | name (string) |
get_skill_bundle | SKILL.md plus every template, reference, and prompt file for one skill in a single JSON payload. Use for skills you’ll fully execute (csl, license, classify) to skip N round-trips. | name (string) |
get_ecfr_part | Full hierarchical structure of a CFR part. Sourced live from eCFR, edge-cached 1h. | part (integer) |
get_ecfr_sections | Flat list of sections within a CFR part — section numbers + titles only, useful for indexes/pickers. Read a section’s full text with get_ecfr_text. | part (integer) |
get_ecfr_text | Full text of one CFR section (e.g. 740.17) as clean readable text — the actual control text, not just structure, headings, or search excerpts. Sourced live from eCFR, edge-cached 1h. | part, section |
get_eccn | Full control entry for one ECCN (e.g. 5A002) from the Commerce Control List (Supplement No. 1 to Part 774) — License Requirements, Reason for Control, License Exceptions, and List of Items Controlled — as clean readable text. Edge-cached 1h. | eccn |
search_ecfr_part | Full-text search scoped to one CFR part. Returns ranked hits with section refs and highlighted excerpts. | part, query |
search_ecfr_title | Full-text search across an entire CFR title (15 EAR or 22 ITAR). | title, query |
get_rule_changes | Recent export-control rulemaking from the Federal Register — final and proposed rules from BIS (EAR), DDTC/State (ITAR), and OFAC (sanctions), newest first. | — |
get_enforcement_actions | Recent U.S. export-control enforcement actions from public sources — BIS denial/settlement orders, DDTC ITAR notices, DOJ National Security Division criminal cases, BIS charging letters, and DDTC consent agreements — newest first, with cited statutes. See Enforcement actions. | — (all optional: agency BIS|DDTC|DOJ, action_type, party, statute, since, limit) |
search_csl | Denied-party screening — screen a buyer, consignee, end-user, bank, or intermediary against the U.S. Consolidated Screening List (Trade.gov: BIS Entity/Denied/Unverified, OFAC SDN + consolidated, State DTC debarred, and more). Fuzzy matching on by default; returns scored matches with source list, programs, countries, and remarks. A name match is not a determination — surface hits for human adjudication. | name (optional: fuzzy, sources) |
search_federal_register | Full-text search of the Federal Register — every published rule, proposed rule, notice, and presidential document (the general FR search, distinct from the curated feeds). Filter by agency slug, doc_type, and limit. | query |
get_federal_register_document | Fetch one FR document by number — full metadata plus its plain-text body (~40k chars). Read the actual text of a rule or notice. | document_number |
search_sec_edgar | SEC EDGAR full-text search across public-company filings — surfaces companies self-disclosing export/sanctions issues. Filter by forms and date range. | query |
search_ecfr | Global cross-title full-text search of the eCFR — the discovery search across the entire CFR (distinct from the scoped search_ecfr_part / search_ecfr_title). Optionally narrow to one title. | query |
search_govinfo | GovInfo full text across the Federal Register, CFR, US Code, federal court opinions (USCOURTS), bills, and public laws. Optionally scope to one collection. | query |
search_regulations | Search Regulations.gov rulemaking dockets and public comments — find open comment periods and docket documents for a proposed rule. | query |
check_party_enforcement (Enterprise) | Check whether a named counterparty appears in U.S. export-control enforcement — every source above plus the trade.gov Denied Persons List — and return matching actions grouped by source with a short summary. | name |
search_court_records (Enterprise) | Search CourtListener across federal + state opinions, RECAP dockets, oral arguments, and judges. result_type selects the corpus (default RECAP dockets); court narrows to a court id. Runs under your own CourtListener token (BYOK, per-user rate limits) — add it in app.exchek.us settings. | query |
find_court_case (Enterprise) | Does a matter have a criminal court case? Combines a DOJ press-release title search with a CourtListener RECAP-docket search. The DOJ half always runs; the RECAP half uses your own CourtListener token (BYOK) from app.exchek.us settings. Empty ⇒ likely an administrative-only action with no PACER docket. | name |
get_court_case_documents (Enterprise) | List the docket documents for a CourtListener docket_id — flattens docket entries into a document list, with a download URL for documents already available in RECAP. Runs under your own CourtListener token (BYOK) from app.exchek.us settings. | docket_id |
record_compliance_event (Enterprise) | Record a pipeline stage (classify/screen/license/…) so the user’s app.exchek.us Transactions page tracks the workflow. Metadata only — stage, status, short refs. | transaction_id, event_type, status |
list_compliance_transactions (Enterprise) | The account’s recorded transactions with stages and statuses — answers “what’s still open?”. | — |
record_screening (Enterprise) | Register a screened party into the Screening Center for continuous re-screening + alerts. Stores the party name — only call at the user’s direction. | name, result |
get_party_status (Enterprise) | Look up a party’s screening status (clear/flagged, last screened, monitoring) before transacting. | name |
get_regulatory_notes (Enterprise) | The account’s eCFR Workbench notes — institutional guidance pinned to citations/ECCNs at app.exchek.us. Call before classifying; cite applicable notes as organizational guidance. | eccn?, part?, section? |
record_product_classification (Enterprise) | Save a classification determination into the user’s Products registry at app.exchek.us so future sessions reuse it instead of re-classifying. Metadata only. | label, eccn |
get_prior_classification (Enterprise) | Look up the Products registry for a prior classification of an item before classifying from scratch — returns label, ECCN, jurisdiction, and when it was determined. | label |
get_<doc>_pdf_contract (Enterprise) | The payload contract + authoring rules for a document renderer — one per document type (e.g. get_classification_pdf_contract). Requires the bearer-key header; fetch before building a payload. | — |
create_<doc>_pdf (Enterprise) | Render a completed analysis into the branded, audit-ready PDF for that document, delivered as a 1-hour download link. Seven documents: classification, license-determination, restricted-party-screening (renders free), transaction-compliance-file, emcp-manual, tcp, encryption-report — 14 tools in total. | variables |
Enterprise: PDF memoranda
The classify → memo flow, end to end: run the exchek-classify skill (free), then — with your Enterprise account — fetch get_classification_pdf_contract, fill it from your analysis, call create_classification_pdf — and hand your user a branded, audit-ready PDF in the same conversation. The same get_<doc>_pdf_contract / create_<doc>_pdf pair renders the rest of the seven-document suite (the Restricted-Party Screening Certificate renders free). Two ways to authenticate, by client type:
Option A — Sign in (claude.ai, Claude Desktop, any OAuth-capable client)
Add https://api.exchek.us/mcp/pro as a connector. The client opens a sign-in window at app.exchek.us (one-time email link, no password), you approve access, and the paid tools just work — no API key ever touches the conversation or the client config. Manage and revoke connected apps anytime at app.exchek.us.
Option B — API key header (Claude Code, Cursor, agent SDKs)
Add your Enterprise key as a connection header (keys never appear in tool arguments, where clients would log them). In the ExChek plugin this is the enterprise_api_key setting; raw config:
{
"mcpServers": {
"exchek": {
"url": "https://api.exchek.us/mcp",
"transport": "streamable-http",
"headers": { "Authorization": "Bearer exk_live_…" }
}
}
}Without credentials the paid tools return purchase information instead of failing the protocol — your agent will relay it. Rendering is stateless: payloads are processed in memory and discarded, never stored or logged. Payloads must not contain CUI or classified information. Plans and key management: app.exchek.us — subscribe for unlimited documents, or pay-per-document at $1 on the free tier (the Screening Certificate is free). See Pricing. REST equivalent: POST /pdf/classification (see the API reference).
Resources
The server enumerates 147 resources under the exchek:// scheme — one per SKILL.md plus every template, reference, and prompt file across all 20 skills. (The PDF payload contract is not a resource — it is part of the Enterprise product, available via the get_classification_pdf_contract tool with a key.) Clients that prefer the resource-based pattern (MCP’s read-only, URI-addressed surface) can use these instead of tools.
| URI template | What you get |
|---|---|
exchek://skills/{name} | Full SKILL.md |
exchek://skills/{name}/templates/{filename} | Report or memo template (with {{PLACEHOLDER}} fields) |
exchek://skills/{name}/references/{filename} | Regulatory / best-practice reference |
exchek://skills/{name}/prompts/{filename} | System or user prompt (where applicable) |
Use resources/list to enumerate, resources/read with a URI to fetch content, and resources/templates/list to discover the URI templates.
End-to-end example: classify an item
An agent walking through ECCN classification will typically:
- Call
list_skillsto discover what’s available. - Call
get_skillwithname: "exchek-classify"; load the SKILL.md into its system prompt. - Follow the flow in SKILL.md — including the mandatory CUI/Classified gate at step 0.
- Call
get_ecfr_partwithpart: 774to load the Commerce Control List structure. - Optionally call
search_ecfr_partwith the item description to narrow ECCN candidates. - Call
get_eccn(e.g.eccn: "5A002") to read the candidate’s full control entry, andget_ecfr_textfor any License-Exception section (e.g.part: 740, section: "740.17"). - Fill out the classification memo template (also fetchable via
get_skill_bundleor theexchek://skills/exchek-classify/templates/Classification%20Report.mdresource). - Return the completed memo to the user for review and approval.
CUI and Classified information
Every SKILL.md begins with a CUI/Classified gate that asks the user upfront whether the information involves Controlled Unclassified Information (CUI), § 126.18 ITAR technical data, or classified material. The gate does not auto-refuse: for CUI or ITAR it proceeds only if the user explicitly confirms a compliant secure enclave or on-prem setup (accredited boundary, no training/retention/logging, controlled content kept in-boundary); for classified it proceeds only on an accredited classified system, otherwise it stops. Controlled content is never sent to the public ExChek API, and this MCP server enforces the same gate as the local plugin — because the gate lives in the SKILL.md content itself, any compliant client running the flow will see and apply it.
Caching and freshness
Skill content is mirrored from exchekinc/exchekskills with a 6h edge cache. eCFR data has a 1h edge cache. A daily Worker cron warms the eCFR cache so the first request after midnight UTC is already hot. Push to the skills repo → cache expires within 6h → all MCP clients see the new content automatically.
What this MCP does not do (yet)
- No server-side LLM execution. The MCP serves content and data; your client’s LLM does the reasoning. We’re intentionally Tier 1 — fast, free, zero session state.
- No CSL search. Trade.gov’s Consolidated Screening List API requires a free per-user key. Get one at developer.trade.gov and call the CSL endpoints directly; see the CSL skill for the call pattern.
- No DOCX rendering. The local plugin includes a Node-based markdown→docx converter. Over MCP you get markdown — or, for Enterprise customers, the branded PDF memorandum via
create_classification_pdf(see above). - No persistent state. The MCP doesn’t remember past determinations. If you need that, install the local plugin (audit log + state files) or wire up your own storage.