MCP Tools REST API

A thin REST wrapper over the same MCP tool registry described in the MCP integration guide. Same tool names, same request arguments, same scope enforcement, same clarification and continuation behavior, and the same result envelope as MCP tools/call - for clients that would rather send one HTTP request than speak JSON-RPC.

Endpoint

POST /api/mcp/tools/{toolName}
Content-Type: application/json
Authorization: Bearer <mcp-access-token>
POST /api/mcp/tools/ask_data

{
  "datasourceId": "238b1c06-a155-4fc3-b229-2cc657500891",
  "schema": "public",
  "question": "Which is our best product",
  "execute": true,
  "maxRows": 10
}

Authentication

Use the same MCP OAuth access token described in the MCP integration guide:

Authorization: Bearer cr_mcp_at_...

Access tokens expire after 15 minutes. Refresh with grant_type=refresh_token against the Colrows OAuth authorization server instead of forcing the user through the browser flow again.

Tool catalog

ToolPurposeScope
list_datasourcesList datasources accessible to the authenticated user.metadata:read
list_schemasList schemas in one accessible datasource.metadata:read
get_schemaReturn accessible tables and columns.metadata:read
search_metadataSearch tables, columns, metrics, terms, and other semantic entities.metadata:read
ask_metadataAnswer natural-language questions about metadata, relationships, lineage, and governance.metadata:read
get_column_profileReturn the existing profile for one column.metadata:read
generate_sqlGenerate and validate read-only SQL without executing it.data:query
execute_queryExecute known, validated read-only SQL.data:query
ask_dataAnswer a natural-language analytics question with text, data, or both.data:query

Response envelope

The REST endpoint returns the same tool-call envelope as MCP.

Success:

{
  "structuredContent": { "data": { /* tool-specific result */ } },
  "content": [{ "type": "text", "text": "{\"data\":{...}}" }],
  "isError": false
}

Tool error:

{
  "content": [{ "type": "text", "text": "datasourceId must be a string" }],
  "isError": true
}

HTTP status is normally 200 for both tool-level success and tool-level error - check isError, not just the status code. Authentication, authorization, and malformed request bodies use HTTP error statuses instead.

Clarification & continuation

Tools that delegate natural-language interpretation - generate_sql and ask_data - may require clarification before Colrows can compile a proven query.

Initial request:

POST /api/mcp/tools/ask_data

{
  "datasourceId": "238b1c06-a155-4fc3-b229-2cc657500891",
  "schema": "public",
  "question": "Which is our best product",
  "execute": true,
  "maxRows": 10
}

Clarification response:

{
  "structuredContent": {
    "data": {
      "status": "clarification_required",
      "continuationToken": "cr_mcp_cont_...",
      "expiresAt": 1782200000000,
      "clarification": {
        "id": "generated-or-synonymous-id",
        "question": "Define what metric “best product” should mean for this query."
      }
    }
  },
  "isError": false
}

Resume request:

POST /api/mcp/tools/ask_data

{
  "continuationToken": "cr_mcp_cont_...",
  "clarificationResponse": {
    "metric": "order volume",
    "answer": "Best product means highest order volume."
  }
}

If clarificationResponse is not an object, Colrows normalizes it to { "answer": "<provided value>" }. REST clients may include execution controls such as execute and maxRows in continuation calls - the original datasource, schema, and question stay bound to the token and are replayed automatically. Full continuation-token semantics (expiry, node affinity, replay rejection) are covered in the MCP integration guide.

Examples

List datasources

POST /api/mcp/tools/list_datasources

{}

Ask metadata

POST /api/mcp/tools/ask_metadata

{
  "question": "Where can I find revenue and which tables contain it?",
  "datasourceIds": ["238b1c06-a155-4fc3-b229-2cc657500891"]
}

Generate SQL

POST /api/mcp/tools/generate_sql

{
  "datasourceId": "238b1c06-a155-4fc3-b229-2cc657500891",
  "schema": "public",
  "question": "Show monthly net revenue for this year"
}

Execute query

POST /api/mcp/tools/execute_query

{
  "datasourceId": "238b1c06-a155-4fc3-b229-2cc657500891",
  "sql": "SELECT 1",
  "maxRows": 10
}

Ask data

POST /api/mcp/tools/ask_data

{
  "datasourceId": "238b1c06-a155-4fc3-b229-2cc657500891",
  "schema": "public",
  "question": "Which is our best product by order volume?",
  "execute": true,
  "maxRows": 10
}

Error handling

ConditionHTTP statusBody
Invalid JSON body400Tool-style error envelope
Missing / expired access token401Auth challenge from the auth layer
Missing required scope403WWW-Authenticate includes the required scope
Unknown tool200Tool-style isError: true
Invalid tool arguments200Tool-style isError: true
This is a wrapper, not a second API.

The REST endpoint delegates directly to the same tool registry MCP tools/call uses. Behavior, validation, and governance are identical between the two - pick whichever transport fits your client.