developerUpdated 2026-05-24

MCP Server (Model Context Protocol)

The Tessallite MCP server lets AI assistants — Claude Desktop, Cursor, Claude Code, and any MCP-compatible client — query your semantic layer directly. The assistant can list models, inspect structure, run governed queries, view history, and trigger refreshes without custom REST integration.

What the MCP server can do

ToolDescription
list_modelsList projects, or list models within a project
describe_modelFull model structure: dimensions, measures, hierarchies, joins
execute_queryRun SQL through the semantic layer with aggregate routing
get_query_historyRecent queries with execution times and routing decisions
list_aggregatesMaterialised aggregates with status, grain, and size
trigger_refreshTrigger an aggregate refresh for a specific model (needs a tenant-admin account)

All queries go through Tessallite's query router. Aggregate routing, persona-based security, and row-level filters are enforced exactly as they are for BI tool queries.

trigger_refresh is an administrative action: the scheduler requires a tenant-admin credential. If you configure the MCP server with a viewer or modeler account, every other tool works but trigger_refresh returns a per-aggregate "FAILED (403 ...)" line. Use a tenant-admin (or a service account granted the tenant-admin role) if you need refresh.

How it runs (transport)

The MCP server speaks the MCP stdio transport — the assistant launches it as a child process and talks to it over standard input/output. It is not an HTTP service and has no SSE/HTTP listener, so it cannot be deployed as a long-running Cloud Run service; run it locally next to the assistant (the command/args config below) or via docker run with stdio attached.

Reaching the backend. TESSALLITE_URL must point at the model service and TESSALLITE_QUERY_URL at the query router. In a standard local Docker deployment the backend container ports may not be published on the host (nginx fronts them), so http://localhost:8001 will not resolve — point the variables at the nginx-proxied address your browser uses (for example the app domain, with the service path the reverse proxy exposes) or publish the backend ports for local development. The Endpoints panel in the app pre-fills these values for your deployment.

Prerequisites

Installation

From the monorepo:

cd tessallite/mcp-server
pip install .

Standalone:

pip install tessallite-mcp

Configuration

The server reads configuration from environment variables:

VariableRequiredDefaultDescription
TESSALLITE_URLYeshttp://localhost:8001Model service base URL
TESSALLITE_QUERY_URLNohttp://localhost:8002Query router base URL
TESSALLITE_SCHEDULER_URLNohttp://localhost:8004Scheduler base URL
TESSALLITE_TENANT_IDYesTenant slug to authenticate against
TESSALLITE_EMAILYesUser email for JWT login
TESSALLITE_PASSWORDYesUser password
TESSALLITE_ROW_LIMITNo1000Maximum rows returned per query

Claude Desktop setup

Add to your Claude Desktop configuration (claude_desktop_config.json):

{
  "mcpServers": {
    "tessallite": {
      "command": "tessallite-mcp",
      "env": {
        "TESSALLITE_URL": "http://localhost:8001",
        "TESSALLITE_QUERY_URL": "http://localhost:8002",
        "TESSALLITE_SCHEDULER_URL": "http://localhost:8004",
        "TESSALLITE_TENANT_ID": "acme-demo",
        "TESSALLITE_EMAIL": "admin@acme-demo.com",
        "TESSALLITE_PASSWORD": "acme-demo"
      }
    }
  }
}

If installed from source:

{
  "mcpServers": {
    "tessallite": {
      "command": "python",
      "args": ["-m", "src.server"],
      "cwd": "/path/to/tessallite/mcp-server",
      "env": {
        "TESSALLITE_URL": "http://localhost:8001",
        "TESSALLITE_TENANT_ID": "acme-demo",
        "TESSALLITE_EMAIL": "admin@acme-demo.com",
        "TESSALLITE_PASSWORD": "acme-demo"
      }
    }
  }
}

Cursor setup

Add to .cursor/mcp.json in your project or global settings:

{
  "mcpServers": {
    "tessallite": {
      "command": "tessallite-mcp",
      "env": {
        "TESSALLITE_URL": "http://localhost:8001",
        "TESSALLITE_TENANT_ID": "acme-demo",
        "TESSALLITE_EMAIL": "admin@acme-demo.com",
        "TESSALLITE_PASSWORD": "acme-demo"
      }
    }
  }
}

Claude Code setup

Add to .claude/settings.json:

{
  "mcpServers": {
    "tessallite": {
      "command": "tessallite-mcp",
      "env": {
        "TESSALLITE_URL": "http://localhost:8001",
        "TESSALLITE_TENANT_ID": "acme-demo",
        "TESSALLITE_EMAIL": "admin@acme-demo.com",
        "TESSALLITE_PASSWORD": "acme-demo"
      }
    }
  }
}

Docker

docker build -t tessallite-mcp tessallite/mcp-server/

docker run --rm \
  -e TESSALLITE_URL=http://host.docker.internal:8001 \
  -e TESSALLITE_QUERY_URL=http://host.docker.internal:8002 \
  -e TESSALLITE_SCHEDULER_URL=http://host.docker.internal:8004 \
  -e TESSALLITE_TENANT_ID=acme-demo \
  -e TESSALLITE_EMAIL=admin@acme-demo.com \
  -e TESSALLITE_PASSWORD=acme-demo \
  tessallite-mcp

Security

Use a service account with appropriate permissions rather than a personal admin account in production.

Troubleshooting

Related