Open District Get started free
General tools · worked recipes

Examples

Open District stays general-purpose: the same MCP tools for every workflow. These are composition patterns — catalog, run_sql, unified_search, list_sources, and entity_path — over the public catalog and data you bring into your tenant. Endpoint: api.opendistrict.org/mcp. A free API key is required (Authorization: Bearer $OD_API_KEY).

Mint a key after signup with scopes data:read, query:run, and vectors:search for MCP reads. To load private rows over REST, add events:write. See the MCP quickstart.

Walkthrough: join your vendor list to public records

You keep a small CSV of third-party vendors in your private workspace. You want each name matched to GLEIF LEI records, SEC EDGAR filings, and CISA KEV / NVD CVE rows from the shared public catalog — using the same ten MCP tools as every other example, not a separate product surface.

In federated SQL, public catalog rows are available as public_ch_events and public_events alongside your tenant’s private events table (see run_sql in agents.md).

1 — Load private vendor rows (REST)

MCP tools are read-only. Ingest each CSV row with POST https://api.opendistrict.org/webhook/events and an API key that includes the events:write scope. Repeat for every vendor, or send one request per row from your script.

curl -sS -X POST 'https://api.opendistrict.org/webhook/events' \
  -H "Authorization: Bearer $OD_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "event_type": "workspace.vendor",
    "payload": { "vendor_name": "Acme Robotics LLC" }
  }'

A hosted CSV upload control in the web app is not exposed on the public API yet. You can also create private connectors with POST /sources (session auth) — for example the rest template for your own HTTP API, or the file template when a folder is mounted for the gateway — then call POST /sources/{id}/sync. The steps below use only generic MCP tools after ingest.

2 — Open an MCP session

curl -sS -X POST 'https://api.opendistrict.org/mcp' \
  -H "Authorization: Bearer $OD_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-06-18",
      "capabilities": {},
      "clientInfo": { "name": "examples", "version": "1" }
    }
  }'

3 — list_sources

Confirm your tenant’s private sources and which public catalog slugs are installed (for example gleif, sec-edgar-filings, cisa-kev, nvd-cves).

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "list_sources",
    "arguments": {}
  }
}

4 — get_schema (optional)

Inspect allowlisted tables before writing SQL. Federated joins can use events (your tenant) and public_ch_events (read-only public corpus).

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "get_schema",
    "arguments": {}
  }
}

5 — run_sql: join private vendors to public GLEIF + risk signals

Match on legal name (GLEIF payloads store the name at attributes.entity.legalName.name). Use payload ILIKE for fuzzy hits on SEC, KEV, and NVD rows. Event types: gleif.lei-record, gov.filing, security.kev, sec.nvd-cve.

{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {
    "name": "run_sql",
    "arguments": {
      "sql": "SELECT jsonExtractString(v.payload, 'vendor_name') AS vendor, p.event_type, p.id AS public_event_id FROM events v JOIN public_ch_events p ON (p.event_type = 'gleif.lei-record' AND lower(jsonExtractString(p.payload, 'attributes', 'entity', 'legalName', 'name')) = lower(jsonExtractString(v.payload, 'vendor_name'))) OR (p.event_type IN ('gov.filing', 'security.kev', 'sec.nvd-cve') AND p.payload ILIKE concat('%', jsonExtractString(v.payload, 'vendor_name'), '%')) WHERE v.event_type = 'workspace.vendor' LIMIT 25"
    }
  }
}

6 — unified_search and entity_path (optional)

Ask natural-language questions per vendor, or trace graph hops between a company name and a CVE id when entity edges exist.

{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "tools/call",
  "params": {
    "name": "unified_search",
    "arguments": {
      "query": "Acme Robotics SEC 8-K filing",
      "event_type": "gov.filing",
      "limit": 10
    }
  }
}

unified_search accepts query plus optional event_type, source_id, time_range, score_threshold, and limit (see agents.md). entity_path takes from and to strings.

Example output (illustrative)

Fictitious sample only — not live query results. Shape matches what a successful run_sql join might return; every real row carries citation fields in the result envelope.

vendor | public_event_type | public_event_id --------------------|-------------------|---------------------------------- Acme Robotics LLC | gleif.lei-record | 7c9e…-gleif Acme Robotics LLC | gov.filing | 3a1f…-8k Acme Robotics LLC | security.kev | 9b02…-kev (citations on real rows include source_url, record_id, retrieved_at — from run_sql result envelope)

Patterns

Counterparty screening

Does this legal entity have recent public filings that change our risk read?

Public sources
gleif (gleif.lei-record) · sec-edgar-filings (gov.filing)
Tools
catalog() run_sql(sql) unified_search(query) entity_path(from, to)
How an agent composes it
  1. Call catalog or get_schema to confirm column shapes.
  2. Resolve the counterparty with unified_search or run_sql over gleif.lei-record rows.
  3. Join to gov.filing events on shared identifiers (legal name, CIK, or LEI fields in payload via jsonExtractString).
  4. Optional: entity_path between the LEI entity and a filing entity when names differ.

Dataset pages: GLEIF · company filings (slug sec-edgar-filings).

Vulnerability exposure

Which CVEs on the CISA KEV catalog match software on our asset list?

Public sources
nvd-cves (sec.nvd-cve) · cisa-kev (security.kev)
Your data (BYOD)
Ingest an asset inventory with POST /webhook/events or a private POST /sources connector — then join in SQL. See the vendor-list walkthrough for the ingest + run_sql pattern.
Tools
list_sources() run_sql(sql) unified_search(query, event_type?) entity_path(from, to)
How an agent composes it
  1. list_sources to find your asset table and the public nvd-cves / cisa-kev sources.
  2. run_sql to intersect KEV CVE IDs with NVD detail rows (event_type = 'security.kev' and sec.nvd-cve).
  3. Filter to CVEs that mention products in your BYOD asset list (same SQL session, federated ch_events / events).
  4. entity_path from a product name to a CVE id when graph edges exist.

Related join recipe: NVD × KEV (public catalog only).

Regulatory tracking

What final rules and related bills mention our industry keywords this month?

Public sources
federal-register (gov.document) · congress-bills (gov.bill)
Tools
unified_search(query, event_type?, time_range?) run_sql(sql) catalog()
How an agent composes it
  1. unified_search with event_type: "gov.document" for Federal Register hits on your keywords.
  2. unified_search or run_sql on gov.bill rows from congress-bills (Congress.gov) for legislation in the same topic.
  3. Use run_sql to correlate bill titles or sponsors with rule citations in payload text fields.

Bill data is served from Congress.gov via the congress-bills source (replacing the older govtrack-bills connector). Pages: Federal Register.

Weather alert impact

Which of our sites are under an active NWS warning right now?

Public sources
nws-active-alerts (weather.alert)
Your data (BYOD)
Facility or site list uploaded to your tenant (coordinates or counties).
Tools
list_sources() run_sql(sql) unified_search(query, event_type?)
How an agent composes it
  1. run_sql on active weather.alert rows from the public catalog.
  2. Join or filter against your BYOD site table in the same federated query.
  3. unified_search for plain-language questions (“severe thunderstorm warning near Chicago”).

Step-by-step join: NWS alerts × your sites · NWS dataset.

Landing-page scenario cards on the home page use narrative shorthand in examples.yaml; integrate using the ten tools in agents.md only.