{"openapi":"3.1.0","info":{"title":"911CPB-MCP","version":"1.0.0","description":"Read-only access to the CRM Postgres database. Table names are PascalCase, so quote them in SQL (\"Device\"). Only one SELECT/WITH/EXPLAIN/SHOW statement per query; max 500 rows; 15 s timeout."},"servers":[{"url":"https://mcp.911cpb.org"}],"security":[{"bearerAuth":[]},{"apiKey":[]}],"paths":{"/api/list_tables":{"post":{"operationId":"list_tables","summary":"List tables and views","responses":{"200":{"description":"Tables","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Table"}}}}},"401":{"description":"Missing or wrong token"},"422":{"description":"Query rejected or failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/describe_table":{"post":{"operationId":"describe_table","summary":"Show columns and types for a table","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["table"],"properties":{"table":{"type":"string","description":"Exact, case-sensitive table name, e.g. Device"},"schema":{"type":"string","default":"public"}}}}}},"responses":{"200":{"description":"Columns (empty if the table does not exist)","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Column"}}}}},"401":{"description":"Missing or wrong token"},"422":{"description":"Query rejected or failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/query":{"post":{"operationId":"query","summary":"Run one read-only SQL statement","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["sql"],"properties":{"sql":{"type":"string","description":"e.g. select count(*) from \"Device\""}}}}}},"responses":{"200":{"description":"Result rows","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueryResult"}}}},"401":{"description":"Missing or wrong token"},"422":{"description":"Query rejected or failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"},"apiKey":{"type":"apiKey","in":"header","name":"X-API-Key"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string"}}},"Table":{"type":"object","properties":{"table_schema":{"type":"string"},"table_name":{"type":"string"},"table_type":{"type":"string"}}},"Column":{"type":"object","properties":{"column_name":{"type":"string"},"data_type":{"type":"string"},"is_nullable":{"type":"string"},"column_default":{"type":["string","null"]}}},"QueryResult":{"type":"object","properties":{"rowCount":{"type":"integer","description":"Total rows the database returned"},"rows":{"type":"array","items":{"type":"object"},"description":"Up to 500 rows"},"truncated":{"type":"boolean"}}}}}}