This article covers security, configuration, observability, runtime behavior, and error handling for K2view Fabric MCP servers.
MCP server security follows the same RBAC (Role-Based Access Control) model as Fabric APIs.
Clients authenticate using one of:
Note: Fabric OAuth support is currently not RFC 9728 compliant.
Requests without authentication or with invalid/expired tokens receive a 401 Unauthorized response.
Permissions are controlled at two levels:
Tool-level permissions are currently not supported.
Users with no permissions on a data product receive 403 Forbidden. Users with READ-only permissions can perform read operations only. IID-specific permissions restrict access to only the authorized entity instances.
Security profiles can also be applied to mask or anonymize sensitive data in MCP responses, supporting compliance with GDPR, CCPA, and other regulations.
Because each MCP session is scoped to a specific LU and IID, data isolation is enforced at the architecture level. The MicroDB contains only data for the attached entity instance. For example, a session connected to customer/1 cannot access data from customer/2, preventing cross-entity data leakage.
MCP server behavior can be controlled via config.ini settings:
Changes to these settings require a Fabric restart to take effect.
Fabric provides observability for MCP server activity.
MCP activity is tracked via JMX statistics:
Fabric's MCP server sends standard MCP protocol notifications to connected clients when server state changes. Clients will receive these automatically and react accordingly (e.g., refreshing the tool list).
| Notification | When sent | Client behavior |
|---|---|---|
notifications/tools/list_changed |
When Broadway tools are added or removed during LU redeployment | Client should re-fetch tools/list |
Notifications are only sent for tools. Prompt and resource change notifications are intentionally disabled, so that prompt changes on redeployment are not broadcast to connected clients.
The tools/list_changed capability is declared in the server's MCP capabilities on initialization, so compliant clients know to expect it. When an LU is redeployed and tagged Broadway flows change, every addTool or removeTool operation on an active session triggers this notification to all connected clients.
MCP separates errors into two layers: transport-level errors (HTTP status codes) and application-level errors (JSON-RPC responses with isError: true). Understanding this distinction is important for building robust client integrations.
Transport-level errors indicate that the request did not reach the MCP tool logic. These are returned as standard HTTP error codes with no JSON-RPC body.
Application-level errors occur when the HTTP request is valid and the MCP server successfully processes it, but the tool execution itself fails. These always return HTTP 200 OK with a JSON-RPC response containing isError: true.
Example: Application-Level Error Response (HTTP 200 OK):
{
"content": [
{
"type": "text",
"text": "Error reading table: [SQLITE_ERROR] SQL error or missing database (no such table: AAA)"
}
],
"isError": true
}
This article covers security, configuration, observability, runtime behavior, and error handling for K2view Fabric MCP servers.
MCP server security follows the same RBAC (Role-Based Access Control) model as Fabric APIs.
Clients authenticate using one of:
Note: Fabric OAuth support is currently not RFC 9728 compliant.
Requests without authentication or with invalid/expired tokens receive a 401 Unauthorized response.
Permissions are controlled at two levels:
Tool-level permissions are currently not supported.
Users with no permissions on a data product receive 403 Forbidden. Users with READ-only permissions can perform read operations only. IID-specific permissions restrict access to only the authorized entity instances.
Security profiles can also be applied to mask or anonymize sensitive data in MCP responses, supporting compliance with GDPR, CCPA, and other regulations.
Because each MCP session is scoped to a specific LU and IID, data isolation is enforced at the architecture level. The MicroDB contains only data for the attached entity instance. For example, a session connected to customer/1 cannot access data from customer/2, preventing cross-entity data leakage.
MCP server behavior can be controlled via config.ini settings:
Changes to these settings require a Fabric restart to take effect.
Fabric provides observability for MCP server activity.
MCP activity is tracked via JMX statistics:
Fabric's MCP server sends standard MCP protocol notifications to connected clients when server state changes. Clients will receive these automatically and react accordingly (e.g., refreshing the tool list).
| Notification | When sent | Client behavior |
|---|---|---|
notifications/tools/list_changed |
When Broadway tools are added or removed during LU redeployment | Client should re-fetch tools/list |
Notifications are only sent for tools. Prompt and resource change notifications are intentionally disabled, so that prompt changes on redeployment are not broadcast to connected clients.
The tools/list_changed capability is declared in the server's MCP capabilities on initialization, so compliant clients know to expect it. When an LU is redeployed and tagged Broadway flows change, every addTool or removeTool operation on an active session triggers this notification to all connected clients.
MCP separates errors into two layers: transport-level errors (HTTP status codes) and application-level errors (JSON-RPC responses with isError: true). Understanding this distinction is important for building robust client integrations.
Transport-level errors indicate that the request did not reach the MCP tool logic. These are returned as standard HTTP error codes with no JSON-RPC body.
Application-level errors occur when the HTTP request is valid and the MCP server successfully processes it, but the tool execution itself fails. These always return HTTP 200 OK with a JSON-RPC response containing isError: true.
Example: Application-Level Error Response (HTTP 200 OK):
{
"content": [
{
"type": "text",
"text": "Error reading table: [SQLITE_ERROR] SQL error or missing database (no such table: AAA)"
}
],
"isError": true
}