Knowi exposes a Model Context Protocol (MCP) server that lets external AI tools - Claude, Cursor, Copilot, or any MCP-compatible client - operate Knowi programmatically. Instead of navigating the UI, your AI assistant creates dashboards, queries data, exports results, and manages reports through natural language.
The MCP server runs within Knowi's application server. No additional services to deploy.
For connecting AI tools, see the setup guides: Claude Code | Cursor | VS Code | ChatGPT | Codex CLI
Authentication
The MCP server supports three authentication methods.
Option 1: OAuth Browser Auth (Recommended)
MCP clients that support OAuth 2.1 (Claude Code, Cursor, VS Code, Codex CLI) can connect with a one-click browser flow - no manual token copy/paste needed.
- Add Knowi as an MCP server in your AI tool using just the URL (no token required).
- When you first use the connection, the AI tool opens your browser to Knowi's login page.
- Log in (if not already signed in) and click Allow on the consent page.
- Done. The AI tool receives a long-lived token automatically and stores it - no repeated auth until the token expires (1 year).
Under the hood, this uses OAuth 2.1 with PKCE:
- The AI tool discovers Knowi's OAuth endpoints via
GET /.well-known/oauth-authorization-server - Authorization uses
response_type=codewithcode_challenge_method=S256 - The token endpoint exchanges the code + PKCE verifier for a 1-year MCP bearer token
- No client secret needed - security comes from PKCE
See each client's setup guide for the exact configuration.
Option 2: MCP Token (Manual)
If your MCP client doesn't support OAuth, or you prefer manual token management, generate a long-lived MCP token from the Knowi UI.
- Log into Knowi.
- Navigate to Settings > AI Settings.
- Under MCP Token, select an expiry period and click Generate Token.
- Copy the token and paste it into your AI tool's configuration.
Use the token as a Bearer token in all MCP requests:
Authorization: Bearer YOUR_MCP_TOKEN
Security: The MCP token is a separate, revocable credential scoped to MCP endpoints only - it cannot access the broader Management API. Generating a new token automatically revokes any previous one. Revoke at any time from AI Settings.
Option 3: Standard Bearer Token
For short-lived programmatic access, use the standard Management API login:
POST /api/2.0/login
curl -X POST https://www.knowi.com/api/2.0/login \
-H "Content-Type: application/json" \
-d '{"clientId":"YOUR_CLIENT_ID","clientSecret":"YOUR_CLIENT_SECRET"}'
This returns a bearer token that expires after 1 hour. Request a new token when you receive a 401 response.
Instance URL: While the examples here use https://www.knowi.com, use the URL that matches your Knowi deployment:
-
Knowi Cloud (default):
https://www.knowi.com -
EU Cloud:
https://eu.knowi.com -
On-Premise: Your on-premise Knowi URL (e.g.
https://knowi.yourcompany.com)
Endpoints
All MCP endpoints are at /api/2.0/mcp/.
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /api/2.0/mcp/health | Health check | No |
| POST | /api/2.0/mcp | Streamable HTTP - all JSON-RPC methods (initialize, tools/list, tools/call) | Yes |
| DELETE | /api/2.0/mcp | Terminate a Streamable HTTP session | Yes |
| GET | /api/2.0/mcp/tools | List all available tools (REST) | Yes |
| GET | /api/2.0/mcp/tools/{toolName} | Get schema for a specific tool (REST) | Yes |
| POST | /api/2.0/mcp/tools/call | Execute a tool (REST) | Yes |
Health Check
curl https://www.knowi.com/api/2.0/mcp/health
Response:
{
"status": "healthy",
"toolCount": 31,
"tools": ["knowi_do", "knowi_ask", "knowi_search", ...],
"activeSessions": 0
}
List Tools
curl -H "Authorization: Bearer YOUR_TOKEN" \ https://www.knowi.com/api/2.0/mcp/tools
Returns an array of tool definitions with name, description, and input schema for each tool.
Call a Tool
Request
POST /api/2.0/mcp/tools/call
curl -X POST https://www.knowi.com/api/2.0/mcp/tools/call \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "knowi_list_dashboards",
"arguments": {}
}'
Response
{
"content": [
{"type": "text", "text": "Found 3 dashboards"}
],
"isError": false,
"_meta": {
"executionTimeMs": 245
}
}
Available Tools
The MCP server exposes 31 tools: 3 AI-powered tools and 28 deterministic tools.
AI-Powered Tools
These tools use the AI orchestrator to interpret natural language and chain multiple operations together.
knowi_do
Execute any Knowi operation using natural language. The orchestrator routes the instruction to the appropriate internal agent(s).
| Parameter | Type | Required | Description |
|---|---|---|---|
| instruction | string | Yes | Natural language instruction describing what to do |
| dashboardId | integer | No | Target dashboard ID for dashboard-level operations |
| widgetId | integer | No | Target widget ID for widget-level operations |
Example:
{
"name": "knowi_do",
"arguments": {
"instruction": "Create a sales dashboard with revenue trends and top products"
}
}
Note: knowi_do blocks destructive operations (delete, remove, drop). Use knowi_delete for those.
knowi_ask
Ask a data question in natural language. The AI finds the relevant dataset, generates a query, executes it, and returns results.
| Parameter | Type | Required | Description |
|---|---|---|---|
| question | string | Yes | Natural language question about your data |
| datasetIds | array of integers | No | Specific dataset IDs to query. If omitted, the AI searches all accessible datasets. |
Example:
{
"name": "knowi_ask",
"arguments": {
"question": "What were total sales last quarter?",
"datasetIds": [456]
}
}
Response includes the executed query, result fields, data rows, and the datasets that were searched.
knowi_search
Search across all Knowi assets using keyword or semantic search.
| Parameter | Type | Required | Description |
|---|---|---|---|
| query | string | Yes | Search query |
| assetType | string | No | Filter by type: dashboard, widget, dataset, query, report, alert |
| limit | integer | No | Maximum number of results to return |
Example:
{
"name": "knowi_search",
"arguments": {
"query": "customer retention",
"assetType": "dashboard"
}
}
Deterministic Tools
These tools execute specific operations directly without AI interpretation. They are fast and predictable.
knowi_list_dashboards
List all dashboards accessible to the authenticated user. No required parameters.
{
"name": "knowi_list_dashboards",
"arguments": {}
}
Returns dashboard IDs, names, and widget counts.
knowi_get_data
Retrieve data from a widget or dataset.
| Parameter | Type | Required | Description |
|---|---|---|---|
| widgetId | integer | No* | Widget ID to get data from |
| datasetId | integer | No* | Dataset ID to get data from |
| limit | integer | No | Maximum number of rows to return (default 100) |
*One of widgetId or datasetId is required.
knowi_get_details
Get full details for any asset.
| Parameter | Type | Required | Description |
|---|---|---|---|
| assetType | string | Yes | Type of asset: dashboard, widget, dataset, query, report, alert, datasource |
| assetId | integer | Yes | ID of the asset |
Returns full metadata including schema (for datasets), widget counts (for dashboards), and configuration details.
knowi_find_widget
Find widgets by name, optionally scoped to a dashboard.
| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Widget name to search for (substring match) |
| dashboardId | integer | No | Limit search to a specific dashboard |
Returns matching widget IDs, names, chart types, and dataset information.
knowi_push_data
Push data rows to a dataset. Creates the dataset if it does not exist.
| Parameter | Type | Required | Description |
|---|---|---|---|
| datasetName | string | Yes | Name of the dataset to push data to |
| rows | array of objects | Yes | Data rows to push |
knowi_import_file
Import file data (CSV, JSON, XML, or Excel) into a Knowi dataset. Pass inline text for CSV/JSON/XML, or base64-encoded content for Excel. Creates or updates a dataset.
| Parameter | Type | Required | Description |
|---|---|---|---|
| datasetName | string | Yes | Name for the dataset to create or update |
| content | string | No* | Inline file content. Raw text for CSV/JSON/XML; base64-encoded binary for Excel. |
| fileUrl | string | No* | URL to download file from (http/https). Prefer for large files. |
| fileType | string | No | File format: csv, json, xml, or excel. Auto-detected if omitted. |
*One of content or fileUrl is required.
knowi_export_pdf
Export a dashboard or widget as a PDF. Returns base64-encoded PDF content.
| Parameter | Type | Required | Description |
|---|---|---|---|
| dashboardId | integer | No* | Dashboard to export |
| widgetId | integer | No* | Widget to export |
*One of dashboardId or widgetId is required.
knowi_export_csv
Export a dashboard or widget as CSV. For dashboards, exports all widgets as separate CSV files. Returns base64-encoded content.
| Parameter | Type | Required | Description |
|---|---|---|---|
| dashboardId | integer | No* | Dashboard to export - each widget becomes a separate CSV |
| widgetId | integer | No* | Single widget to export as CSV |
| limit | integer | No | Max rows per widget (default 10000, max 200000) |
*One of dashboardId or widgetId is required.
knowi_get_embed_url
Generate an embeddable share URL for a dashboard or widget.
| Parameter | Type | Required | Description |
|---|---|---|---|
| dashboardId | integer | No* | Dashboard to share |
| widgetId | integer | No* | Widget to share |
*One of dashboardId or widgetId is required.
knowi_create_widget
Create a visualization on a dataset. Use knowi_get_data with a small limit first to inspect field names - the widget will show no data if field names are wrong.
| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Widget name |
| datasetId | integer | Yes | Dataset to visualize |
| chartType | string | No | Chart type: column, line, bar, pie, donut, area, scatter, heatmap, funnel, treemap, gauge, singletext, datagrid2, recommendation. Default: column |
| xAxis | string | No* | Field name for x-axis (exact field name from dataset). Required for chart types. |
| yAxis | string | No* | Field name for y-axis/value (exact field name from dataset). Required for chart types. |
| groupBy | string | No | Field name for grouping/legend (creates multiple series) |
| series | string | No | Comma-separated metric field names for multiple y-axis series |
| dashboardId | integer | No | Dashboard to add the widget to. If omitted, widget is created standalone. |
knowi_update_widget
Update an existing widget's data transformations (filters, aggregations, sorting) and/or display settings (chart type, name). Changes are saved server-side immediately.
| Parameter | Type | Required | Description |
|---|---|---|---|
| widgetId | integer | Yes | ID of the widget to update |
| filters | array of objects | No | Filters to apply. Each: {field, operator (=, !=, >, <, >=, <=, like, in, between), value}. Replaces existing filters. |
| c9ql | string | No | Raw C9QL query to set as data transformation. Replaces the entire transformation if provided. |
| chartType | string | No | New chart type: column, line, bar, pie, donut, area, scatter, heatmap, funnel, treemap, gauge, singletext, datagrid2 |
| widgetName | string | No | New name for the widget |
| xAxis | string | No | New x-axis field (exact field name from dataset) |
| yAxis | string | No | New y-axis field (exact field name from dataset) |
| groupBy | string | No | New group-by/legend field |
knowi_layout_dashboard
Set widget positions and sizes on a dashboard. Grid is 24 columns wide.
| Parameter | Type | Required | Description |
|---|---|---|---|
| dashboardId | integer | Yes | Dashboard ID |
| widgets | array of objects | Yes | Widget positions. Each: {widgetId, col (1-24), row (1+), sizeX (1-24), sizeY (1-16)} |
knowi_create_datasource
Create a new datasource connection.
| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Name for the datasource |
| datasourceType | string | Yes | Type: mysql, postgresql, mongo, restapi, csv, snowflake, bigquery, redshift, elasticsearch, etc. |
| host | string | No | Database host |
| port | integer | No | Database port |
| dbName | string | No | Database name |
| dbUser | string | No | Database username |
| dbPassword | string | No | Database password |
knowi_create_query
Create a query against a datasource.
| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Name for the query |
| datasourceId | integer | Yes | Datasource to query against |
| queryString | string | Yes | The query to execute (SQL, native query, etc.) |
| runNow | boolean | No | Execute the query immediately (default: true) |
knowi_run
Trigger execution of a query or report.
| Parameter | Type | Required | Description |
|---|---|---|---|
| queryId | integer | No* | Query to execute |
| reportId | integer | No* | Report to trigger |
*One of queryId or reportId is required.
knowi_create_report
Create a scheduled report that sends a dashboard or widgets via Email, Slack, or Teams.
| Parameter | Type | Required | Description |
|---|---|---|---|
| dashboardId | integer | No* | Dashboard to include in the report |
| widgetIds | array of integers | No* | Widget IDs to include (for widget-level reports) |
| recipients | string | No | Comma-separated email recipients. At least one delivery channel required. |
| slackName | string | No | Slack channel or config name (e.g. "#general", "sales-team") |
| teamsActionIds | array of integers | No | Teams integration IDs configured in Settings > Notifications |
| frequencyType | string | No | Frequency unit: minutes, hours, days, weeks, months. Default: days |
| frequency | integer | No | Frequency count (default: 1) |
| startTime | string | No | Time of day in HH:mm (24-hour). Default: 08:00 |
| timezone | string | No | IANA timezone. Default: user's timezone |
| dayOfWeek | string | No | Day for weekly reports: MONDAY-SUNDAY. Default: MONDAY |
| dayOfMonth | integer | No | Day of month for monthly reports (1-28). Default: 1 |
| format | string | No | Report format: pdf or image. Default: pdf |
| reportName | string | No | Display name for the report |
| subject | string | No | Email subject line |
| emailBody | string | No | Email body text |
| sendNow | boolean | No | If true, send immediately after creating. Default: false |
| exportCSV | boolean | No | Include CSV data export (widget-level reports only). Default: false |
| includeRecommendations | boolean | No | Include AI recommendations in the report. Default: false |
*One of dashboardId or widgetIds is required.
knowi_update_report
Update an existing scheduled report's configuration. Only specified fields are changed.
| Parameter | Type | Required | Description |
|---|---|---|---|
| reportId | integer | Yes | ID of the report to update |
| frequencyType | string | No | New frequency unit: minutes, hours, days, weeks, months |
| frequency | integer | No | New frequency count |
| startTime | string | No | New time of day in HH:mm (24-hour) |
| timezone | string | No | New timezone (IANA format) |
| recipients | string | No | New comma-separated email recipients (replaces existing) |
| subject | string | No | New email subject line |
| emailBody | string | No | New email body text |
| reportName | string | No | New report name |
| sendNow | boolean | No | Send immediately after updating. Default: false |
knowi_create_alert
Create an alert on a dataset. Supports conditional alerts (trigger when a C9QL condition matches), data-not-updated alerts, and query error alerts.
| Parameter | Type | Required | Description |
|---|---|---|---|
| datasetId | integer | Yes | Dataset to create the alert on |
| alertName | string | Yes | Name for the alert |
| alertType | string | Yes | Type of alert: conditional, data_not_updated, query_error |
| alertCondition | string | No* | Condition that triggers the alert (natural language or C9QL). Required for conditional alerts. |
| recipients | string | No | Comma-separated email addresses for notifications |
| subject | string | No | Email subject for alert notification |
| frequencyType | string | No | Check frequency: minutes, hours, days, months. Default: days |
| startTime | string | No | Time of day to check in HH:mm. Default: 08:00 |
| timezone | string | No | Schedule timezone. Default: user's timezone |
| realtime | boolean | No | If true, evaluates every time the dataset updates. Default: false |
knowi_list_alerts
List alerts accessible to the current user. Optionally filter by dataset or widget.
| Parameter | Type | Required | Description |
|---|---|---|---|
| datasetId | integer | No | Filter alerts for a specific dataset |
| widgetId | integer | No | Filter alerts for a specific widget |
knowi_test_alert
Test an alert by triggering it immediately. Sends notifications if the condition matches. Results are not recorded in the alert's history.
| Parameter | Type | Required | Description |
|---|---|---|---|
| alertId | integer | Yes | ID of the alert to test |
knowi_update_alert
Update an existing alert. Only specified fields are changed.
| Parameter | Type | Required | Description |
|---|---|---|---|
| alertId | integer | Yes | ID of the alert to update |
| alertName | string | No | New name for the alert |
| alertCondition | string | No | New condition (natural language or C9QL) |
| recipients | string | No | New comma-separated email recipients (replaces existing) |
| subject | string | No | New email subject |
| frequencyType | string | No | New check frequency: minutes, hours, days, months |
| startTime | string | No | New time of day in HH:mm |
| timezone | string | No | New timezone (IANA format) |
| realtime | boolean | No | Toggle real-time evaluation on/off |
| paused | boolean | No | true to pause the alert, false to resume |
knowi_ingest_document
Ingest a document (PDF, Word, CSV, Excel, images, or text) into Knowi for Q&A and data extraction. Documents are chunked, embedded, and stored for semantic search.
| Parameter | Type | Required | Description |
|---|---|---|---|
| fileUrl | string | No* | URL to download the document from (http/https) |
| content | string | No* | Inline content. Raw text for text/CSV/Markdown; base64-encoded for binary formats (PDF, DOCX, Excel, images). |
| fileName | string | No | File name with extension (e.g. "report.pdf"). Required when using inline content; auto-detected from URL otherwise. |
*One of fileUrl or content is required.
knowi_ask_document
Ask a natural language question against ingested documents. Returns an AI-generated answer with source citations.
| Parameter | Type | Required | Description |
|---|---|---|---|
| question | string | Yes | Natural language question to ask |
| documentIds | array of strings | No | Specific document IDs to search. If omitted, searches all documents. Use knowi_list_documents to find IDs. |
knowi_extract_document_data
Extract structured data from documents into a Knowi dataset. Define the fields to extract - Knowi parses each document and returns structured rows that can be queried and visualized.
| Parameter | Type | Required | Description |
|---|---|---|---|
| fields | string | Yes | Comma-separated field names to extract (e.g. "company_name, contract_value, start_date") |
| extractionPrompt | string | No | Custom prompt guiding extraction (e.g. "Parse dates as YYYY-MM-DD. Contract value should be numeric.") |
| documentIds | array of strings | No | Specific document IDs to extract from. If omitted, uses all documents. |
| detailsDepth | integer | No | Extraction thoroughness 1-20. Higher values examine more content but take longer. Default: 5 |
| datasetName | string | No | Name for the resulting dataset. Auto-generated if omitted. |
knowi_list_documents
List documents ingested into the document store. Returns document names and IDs for use with ask/extract/delete tools.
| Parameter | Type | Required | Description |
|---|---|---|---|
| datasourceId | integer | No | Filter by document datasource ID. If omitted, lists all documents. |
| query | string | No | Filter documents by name (partial match) |
knowi_delete_document
Delete an ingested document from the vector store. Requires confirmation.
| Parameter | Type | Required | Description |
|---|---|---|---|
| documentId | string | Yes | Document identifier. Use knowi_list_documents to find IDs. |
| confirm | boolean | Yes | Must be true to confirm deletion |
knowi_get_insights
Generate AI-powered insights and recommendations for a widget or dashboard. Returns observations, trends, anomalies, and actionable recommendations.
| Parameter | Type | Required | Description |
|---|---|---|---|
| widgetId | integer | No* | Widget ID to analyze |
| dashboardId | integer | No* | Dashboard ID to analyze (all widgets) |
| context | string | No | Optional guidance for analysis, e.g. "focus on revenue trends" |
*One of widgetId or dashboardId is required.
knowi_delete
Delete a Knowi asset. This is the only tool that performs destructive operations.
| Parameter | Type | Required | Description |
|---|---|---|---|
| assetType | string | Yes | Type of asset: dashboard, widget, dataset, report, alert |
| assetId | integer | Yes | ID of the asset to delete |
| confirm | boolean | Yes | Must be true to confirm deletion |
All three parameters are required. The confirm parameter must be explicitly set to true.
Streamable HTTP Transport
MCP-compatible clients (Claude Code, Claude Desktop, Cursor, etc.) connect using the Streamable HTTP transport. This uses a single POST endpoint for all operations - no persistent connection required.
How It Works
Every MCP operation is a standard HTTP request/response. The client sends a JSON-RPC message via POST, and the server returns the result immediately. If the server restarts (e.g., during an update), the client simply retries the next request - no reconnection needed.
Initialize
curl -X POST https://www.knowi.com/api/2.0/mcp \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {}}'
Response includes a Mcp-Session-Id header. Send this header on subsequent requests.
Mcp-Session-Id: sh-1
{"jsonrpc": "2.0", "id": 1, "result": {
"protocolVersion": "2024-11-05",
"capabilities": {"tools": {}},
"serverInfo": {"name": "knowi-mcp-server", "version": "1.0.0"}
}}
Call a Tool
curl -X POST https://www.knowi.com/api/2.0/mcp \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id: sh-1" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "knowi_list_dashboards",
"arguments": {}
}
}'
JSON-RPC Methods
| Method | Description |
|---|---|
| initialize | Client handshake - returns server capabilities and protocol version |
| notifications/initialized | Client confirms initialization (no response, returns 204) |
| tools/list | List all available tools with schemas |
| tools/call | Execute a tool |
Session Management
- The server returns a
Mcp-Session-Idheader on every response - The client sends this header on subsequent requests for session continuity
- Sessions auto-expire after 30 minutes of inactivity
- The client can explicitly terminate a session with
DELETE /api/2.0/mcp(include theMcp-Session-Idheader) - If the server restarts, old sessions expire - the client automatically gets a new session on the next request
Security
Authentication Flow
MCP Token (recommended for MCP clients):
- The user generates an MCP token from Settings > AI Settings > MCP Token in the Knowi UI.
- Knowi revokes any existing MCP token for the user and creates a new long-lived token (configurable: 30 days to 1 year).
- The user copies the token into their MCP client configuration (e.g., Claude Code, Claude Desktop) as a
Bearertoken. - The ManagementInterceptor validates the token, verifies it is scoped to MCP endpoints, loads the associated user (including roles, permissions, and customer context), and establishes a security session for the request.
- If the token is compromised, the user revokes it from AI Settings and generates a new one. No other credentials are affected.
Standard Bearer Token (for programmatic use):
- The client sends a login request with
clientIdandclientSecrettoPOST /api/2.0/login. - Knowi returns a bearer token valid for 1 hour.
- When the token expires, the client must obtain a new one.
All tokens are tied to a specific user and inherit that user's full permission set. Tokens grant the same access as the user logging in through the UI.
Authorization
Every tool checks that the authenticated user has access to the requested resource before executing:
-
Dashboard and widget access: Validated using
user.isAllowed(resourceId, assetType, write), the same authorization check used throughout Knowi's UI and API. - Dataset access: Validated by matching the dataset's customer ID against the user's customer ID. A user cannot access datasets belonging to a different organization.
- Datasource access: Validated by customer ID ownership. Creating datasources scopes them to the authenticated user's organization.
Access denied errors are logged with user ID and the resource that was requested.
Data Flow and AI Provider Implications
Understanding what data is sent where is critical for security evaluation. When using the MCP server, there are two separate data flows:
Flow 1: Tool responses to the MCP client. Every tool - deterministic and AI-powered - returns results to the calling MCP client (e.g., Claude Code, Claude Desktop, Cursor). These results may contain actual data rows, dashboard metadata, field names, and generated insights. The client's LLM sees this data. For example, if you ask Claude Code to get data from a widget, the data rows are returned to Claude, which runs on Anthropic's infrastructure. This is inherent to MCP - the client must receive the results to act on them.
Flow 2: Knowi's internal AI processing. AI-powered tools (knowi_do, knowi_ask, knowi_search) additionally send data to Knowi's configured AI model for reasoning (SQL generation, chart type selection, etc.). Where this data goes depends on the configured provider:
- Knowi Internal: Data stays within Knowi's infrastructure for AI processing.
- OpenAI / Anthropic: Data is also sent to the external provider's API.
See AI Model Providers to configure which provider Knowi uses internally.
Deterministic tools (knowi_list_dashboards, knowi_get_data, knowi_push_data, etc.) do not invoke any AI model on Knowi's side - they execute directly against Knowi's services. However, their results are still returned to the MCP client.
What the AI model on Knowi's side receives (Flow 2 only):
| Sent to Knowi's AI Model | NOT Sent to Knowi's AI Model |
|---|---|
| Dataset schema (field names and types) | Database credentials or connection strings |
| Sample data rows (truncated to fit context window) | User authentication tokens or passwords |
| The user's natural language instruction | Data from other organizations |
| Widget metadata (chart type, settings) | System configuration or server internals |
Security implication: Even if Knowi is configured with its internal AI provider, using the MCP server means data flows to the MCP client's infrastructure. Evaluate whether the data accessible through your Management API credentials is appropriate for transmission to the client platform you are using. For maximum data isolation, use Knowi's in-product agents (Dashboard and Widget AI Assistants) instead of MCP.
Input Validation and Prompt Injection
All inputs to AI-powered tools are validated before execution:
Tool name whitelisting: Only the 15 registered tool names are accepted. Any other tool name returns a 404 error.
Instruction length limit: Natural language instructions are capped at 2,000 characters.
Prompt injection detection: Instructions are scanned against patterns known to indicate prompt injection attempts, including:
- "ignore previous instructions"
- "system prompt"
- "you are now" / "act as" / "pretend"
- "disregard" / "override" / "forget"
- "reveal the/your/system"
- "jailbreak" / "DAN"
Matching instructions are rejected with an error before reaching the AI model.
Input sanitization: Control characters (ASCII 0x00-0x08, 0x0B, 0x0C, 0x0E-0x1F, 0x7F) are stripped from all string arguments.
Destructive Operation Safeguards
The knowi_do tool scans instructions for destructive intent (delete, remove, drop, destroy, purge, wipe). If detected, the request is blocked and the user is directed to use the explicit knowi_delete tool instead.
The knowi_delete tool requires three explicit parameters - assetType, assetId, and confirm: true - preventing accidental or AI-hallucinated deletions. All three parameters must be provided; omitting any one causes the request to fail.
Session Security
Streamable HTTP sessions are bound to the authenticated user. Each session receives a unique Mcp-Session-Id and validates that subsequent requests come from the same user who created the session. A valid bearer token is required for every request - session IDs alone do not grant access.
Sessions auto-expire after 30 minutes of inactivity and can be explicitly terminated by the client.
Audit Logging
All agent executions are logged with:
- The user's input prompt
- Success or failure status
- Agent response
- Execution time in milliseconds
- Associated resource IDs (dashboard, widget, dataset)
MCP tool calls are logged with the tool name, success status, and execution time. Logs are available to account administrators.
Data Exposure Controls
Data returned by tools is truncated by default:
-
knowi_get_datareturns a maximum of 100 rows by default (configurable via thelimitparameter). -
knowi_askreturns a maximum of 100 rows. - AI-powered recommendations truncate data to fit the AI model's context window, iteratively reducing rows until the prompt fits.
The response includes totalRows and returnedRows counts so the caller knows if data was truncated.
Known Limitations
- No per-user rate limiting: The MCP server does not enforce per-user rate limits on tool calls. Rate limiting should be applied at the network layer (e.g., API gateway, reverse proxy) for production deployments.
- Token scoping: Bearer tokens inherit the user's full permission set. There is no mechanism to create a token scoped to specific tools or read-only access.
- One MCP token per user: Registering a new MCP token revokes the previous one. A user cannot have multiple active MCP tokens simultaneously.
Error Handling
Errors are returned in the MCP response format:
{
"content": [
{"type": "text", "text": "Access denied: you do not have permission to access dashboard 12345"}
],
"isError": true
}
Common error scenarios:
| Error | Cause | Resolution |
|---|---|---|
| 401 Unauthorized | Token expired or invalid | Generate a new MCP token from Settings > AI Settings |
| Access denied | User lacks permission for the requested resource | Check user permissions in Knowi settings |
| Tool not found | Invalid tool name in request | Use /api/2.0/mcp/tools to list valid tool names |
| Validation error | Missing required parameters | Check tool schema for required fields |
| Instruction blocked | Destructive instruction sent to knowi_do | Use knowi_delete for delete operations |
Rate Limits
AI-powered tools (knowi_do, knowi_ask, knowi_search) consume agent calls, which are metered based on your plan. Deterministic tools are unlimited.
See your account settings for current usage and limits.