Getting Started with the Solid MCP Server

Connect your AI tools and agents to your data warehouse through Solid's semantic layer. The Solid MCP Server exposes a text2sql tool that translates plain English questions into accurate SQL — grounded in your organization's business definitions, joins, and metric logic.

What You Can Do

Once connected, you can:

  • Build agentic workflows that query your data automatically as part of a larger AI pipeline
  • Generate SQL from plain English — describe what you want and get the query back instantly
  • Integrate Solid's data layer directly into the AI tools and agents you build
  • Explore your data interactively — tables, columns, metrics, and more through conversation

How It Works

Understanding this flow will save you debugging time:

Your AI tool / agent
        ↓  (MCP protocol)
Solid MCP Server
        ↓  (semantic model lookup)
Your Solid semantic layer
        ↓  (SQL generation)
SQL query returned to your tool
        ↓  (you run this)
Your data warehouse (Snowflake, BigQuery, etc.)
        ↓
Results

Key point: Solid generates SQL. It does not query your warehouse directly, and it does not move or store your data. Your tool or agent runs the returned SQL against your warehouse using your existing credentials and connection.

This means:

  • Solid only needs read access to your semantic layer metadata — not your raw data
  • All warehouse-level permissions and access controls remain in effect
  • You control where and how the SQL executes

Architecture & Security

ConcernHow Solid handles it
Data movementNone. Solid reads metadata, returns SQL. Your data never leaves your warehouse.
AuthenticationOAuth 2.1 (browser, interactive clients) or a Solid management key (automated). For direct MCP, pass the key as the x-solid-management-key header — no token exchange step.
EncryptionAll traffic over HTTPS (TLS 1.2+)
Warehouse accessControlled entirely by your DWH credentials and role — not by Solid
MCP permissionsScoped to read-only semantic layer operations

Before You Start

You will need:

A data warehouse connection configured in Solid. The text2sql tool generates SQL for your specific warehouse schema. Ask your Solid admin to confirm your connection is active.

The Solid MCP Server URL:

https://mcp.production.soliddata.io/mcp

A way to authenticate — browser sign-in (easiest, no credential management) for interactive MCP clients, or a management key from your Solid admin for automated and production use.

Automated clients pass the management key directly — there is no separate auth call and no JWT to refresh.

Which Setup Is Right for You?

I am using...Follow this guide
Cursor, Claude Desktop, or WindsurfOption A — Browser sign-in
CrewAI, scripts, or direct MCP HTTPOption B — Management key
Workato or other REST/OpenAPI toolsOption B — Management key (REST Bridge)
Microsoft Copilot StudioOption C — Copilot Studio

Not sure? If you're a developer building an automated pipeline or agent with native MCP support, use Option B — Management key.

If your platform only supports REST/OpenAPI (no SSE streaming), use Option B — Management key (REST bridge).

If you're trying Solid out interactively in a coding assistant, use Option A.


Option A — Sign in with your browser

Best for: Cursor, Claude Desktop, Windsurf, and any MCP-compatible tool you use interactively.

The client handles auth via browser.

Cursor

  1. Open Settings → MCP, or press Cmd+Shift+P (Mac) / Ctrl+Shift+P (Windows) and search MCP: Add Server.
  2. Click + Add new MCP server and enter:
    • Name: Solid
    • Type: streamable-http
    • URL: https://mcp.production.soliddata.io/mcp
  3. Save. On first use, Cursor opens a browser window — sign in with your Solid credentials. Prefer config-as-code? Add this to .cursor/mcp.json:
{
  "mcpServers": {
    "Solid": {
      "url": "https://mcp.production.soliddata.io/mcp",
      "transport": "streamable-http"
    }
  }
}

Claude Desktop, Windsurf, and other tools

Add a new MCP server with:

  • URL: https://mcp.production.soliddata.io/mcp
  • Transport: streamable-http Sign in when prompted. Token refresh is handled automatically.

Claude Code (CLI)

Add Solid with the following one-liner in your terminal:

claude mcp add --transport http soliddata https://mcp.production.soliddata.io/mcp

Option B — Use a Management Key

Best for: CrewAI, Workato, CI/CD pipelines, scripts, and any non-interactive environment.

Pass your Solid management key directly. There is no auth exchange endpoint, no Bearer token, and no JWT to refresh. Ask your Solutions Engineer or Solid admin for a management key with MCP access.

Direct MCP (CrewAI, scripts, MCP Inspector)

Connect to Solid's MCP URL and send the management key on every request as a header. Tool payloads contain tool arguments only — do not put management_key inside MCP tool call arguments.

CrewAI:

import os
from crewai.tools import MCPServerHTTP

mcp_server = MCPServerHTTP(
    url="https://mcp.production.soliddata.io/mcp",
    headers={"x-solid-management-key": os.environ["SOLID_MANAGEMENT_KEY"]},
    streamable=True,
    cache_tools_list=True,
)

Any HTTP-based MCP client:

SettingValue
URLhttps://mcp.production.soliddata.io/mcp
Transportstreamable-http
Auth headerx-solid-management-key: your-management-key

MCP Inspector (quick connection test):

npx @modelcontextprotocol/inspector@latest

Add a Streamable HTTP server with URL https://mcp.production.soliddata.io/mcp and header x-solid-management-key: <your-management-key>. No prior auth step is required.

REST / OpenAPI bridge (Workato, Power Platform, Postman)

If your platform cannot speak MCP over SSE, use Solid's REST-to-MCP bridge via the OpenAPI spec. Send one POST per tool call with management_key and the tool-specific fields in the JSON body. The bridge forwards your key to Solid as x-solid-management-key. No Bearer token and no separate auth call.

SettingValue
Base URLYour bridge URL (e.g. https://…azurewebsites.net/api/mcp)
AuthInclude management_key in every request body
Host keyInclude the Azure Function code query parameter (pre-filled in the OpenAPI spec - ask your admin)

text2sql example:

{
  "management_key": "<your-solid-management-key>",
  "question": "What were total sales last month?",
  "semantic_layer_ids": ["model-id-1"]
}

POST to {bridge_base}/text2sql?code=<function-host-key>. This is pre-filled in the OpenAPI spec, which will be provided by your Solid Admin.


Option C — Connect via Microsoft Copilot Studio

Best for: Copilot Studio agents running in Teams or other Microsoft channels.

Uses the native MCP onboarding wizard for streamable HTTP clients, or a REST custom connector when your agent cannot consume MCP/SSE directly.

No bridge infrastructure is required on your side for native MCP; the OpenAPI bridge is only for REST-only integrations.

Prerequisites

  • A Solid management key from your admin
  • Your Semantic layer ID(s) — the UUID(s) of your Solid semantic layer(s)
  • Access to Microsoft Copilot Studio

Setup

  1. In Copilot Studio, open your agent and go to Tools.
  2. Select Add a tool → New tool → Model Context Protocol.
  3. Enter:
    • Server name: Solid Text2SQL
    • Server description: Converts natural language questions to SQL using Solid's semantic layer
    • Server URL: https://mcp.production.soliddata.io/mcp
  4. Choose authentication based on how you connect:
    • Native MCP (streamable HTTP): use API key and provide your Solid management key (sent as x-solid-management-key).
    • REST custom connector (OpenAPI): import Solid's OpenAPI spec and map management_key from a connection secret into each action body. No Bearer token or token exchange is required on the bridge.
  5. Select Create, then Add to agent.

Configuring your agent

Once connected:

  • Agent instructions: Tell the agent when to use Solid, e.g.: "For any data or analytics questions, use the Solid Text2SQL action to generate SQL."
  • Web search: Consider disabling or limiting web search for data questions so the agent routes to Solid instead.
  • Testing: Enable "Show activity map when testing" to confirm the tool is being called and SQL is returned.

Available Tools

text2sql

Describe what you want in plain English. The tool returns a SQL query you can run against your warehouse.

Parameters:

  • question (required) — your natural language question
  • source_system (optional) — your warehouse type, e.g. snowflake, big_query. If you have multiple connected sources and omit this, the tool will ask you to choose.
  • semantic_layer_ids (optional) — one or more semantic model UUIDs to target. See Specifying Semantic Model IDs below. Examples:

Single data source:

"What were total sales last month?"
→ Returns SQL. Run it against your warehouse.

Multiple data sources:

"Show me top 10 customers by revenue."
→ If multiple sources are configured, returns a list of options. Reply with your choice (e.g. snowflake), then call again with source_system set.

What a good output looks like:

SELECT
    DATE_TRUNC('month', o.order_date) AS month,
    r.region_name,
    SUM(o.revenue) AS total_revenue
FROM edw.mart.orders o
JOIN edw.mart.regions r ON o.region_id = r.region_id
WHERE o.order_date >= DATEADD('month', -1, DATE_TRUNC('month', CURRENT_DATE))
  AND o.order_date < DATE_TRUNC('month', CURRENT_DATE)
GROUP BY 1, 2
ORDER BY 1, 3 DESC;

Solid uses your semantic layer to resolve the correct table names, join paths, and metric definitions — rather than guessing from column names alone.


Specifying Semantic Model IDs

By default, text2sql uses all semantic layers connected to your account. If you want to target a specific model — or let Solid's router pick the best match across several — pass one or more IDs using the semantic_layer_ids parameter.

Single model

{
  "question": "What were total sales last month?",
  "semantic_layer_ids": ["model-id-1"]
}

Multiple models (router mode)

{
  "question": "Show me top 10 customers by revenue.",
  "semantic_layer_ids": ["model-id-1", "model-id-2", "model-id-3"]
}

When you provide more than one ID, Solid's router evaluates your question against each model's metadata and routes to the best-certified match. Only certified semantic models are eligible — if a model in the list hasn't been certified, it is skipped automatically.

This is useful when you have separate models for different domains (e.g. finance, sales, support) and want the router to pick the right one without you having to know in advance.

With a management key (Option B)


Direct MCP

Pass semantic_layer_ids as MCP tool arguments only. Auth stays on the transport header:

curl --location 'https://mcp.production.soliddata.io/mcp' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json, text/event-stream' \
  --header 'x-solid-management-key: <your-management-key>' \
  --data '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "text2sql",
      "arguments": {
        "question": "What is net revenue by region for Q1 2025?",
        "semantic_layer_ids": ["model-id-1", "model-id-2"]
      }
    }
  }'

REST bridge

Include management_key in the POST body alongside the tool fields:

{
  "management_key": "<your-solid-management-key>",
  "question": "What is net revenue by region for Q1 2025?",
  "semantic_layer_ids": ["model-id-1", "model-id-2", "model-id-3"]
}

In CrewAI

Replace the code block:

mcp_server = MCPServerHTTP(
    url="https://mcp.production.soliddata.io/mcp",
    headers={"x-solid-management-key": os.environ["SOLID_MANAGEMENT_KEY"]},
    streamable=True,
    cache_tools_list=True,
)

# Pass semantic_layer_ids as part of your tool call input
result = mcp_server.run_tool("text2sql", {
    "question": "Show me monthly churn rate by plan type",
    "semantic_layer_ids": ["model-id-1", "model-id-2"]
})

How the router picks a model

When multiple IDs are provided, Solid scores each certified model against your question using its semantic metadata — tables, metrics, join paths, and descriptions. The model with the strongest match is used to generate the SQL.

If no model in the list is certified, or none is a confident match, the tool returns an error. Try making your question more specific, or verify the model IDs with your Solid admin.

Tip: Not sure what your model IDs are? Use the semantic_model_qa tool to explore what a given model covers, or ask your Solid admin for the UUIDs of certified models in your workspace.


glossary_search

Ask for a definition of a glossary term in plain English. The tool returns the glossary definition stored in Solid, and additional context.

Parameters:

  • query (required) — your natural language question about a term meaning Example:
"What does LLS mean?"

What a good output looks like:

"LLS stands for Lens Loyalty Score. It quantifies a customer's purchase frequency of sunglasses
from the brand. A higher LLS indicates a longer and more consistent relationship with the brand.
As customers make more purchases and their LLS increases, they become eligible for greater
benefits, such as special discounts, advance notice of new styles, and tailored promotions, which
recognize their ongoing patronage. Additionally, a RayCatcher is a new customer who does not yet
have a Lens Loyalty Score (LLS), while a ShadeShifter is a valued customer with multiple
purchases, resulting in a higher LLS and access to exclusive perks and rewards. The LLS is
therefore central to determining customer status and eligibility for rewards within the brand's
loyalty program."

specific_asset_information_tool

Get detailed information about a specific named table or dashboard in your data warehouse. Use this tool when you know the exact name of a table or dashboard and want to learn about its columns, ownership, lineage, or update frequency. It handles one asset at a time.

Parameters:

  • question (required) — your question about the specific asset
  • asset_name (required) — the exact name of the table or dashboard (e.g. database.schema.table or schema.table) Example:
question: "What column includes information about when an order was delivered?"
asset_name: "SUN_SPECTRA.PUBLIC.ORDERS"

What a good output looks like:

Response Text: "The column that includes information about delivered orders is "ACTUAL_DELIVERY_DATE."
It contains the date when the customer order was successfully delivered and is located in the
SUN_SPECTRA.PUBLIC.ORDERS table.
 
Results (1 rows):
Column Name: "ACTUAL_DELIVERY_DATE",
Data Type: "DATE"
Column Full Path: "SUN_SPECTRA.PUBLIC.ORDERS.ACTUAL_DELIVERY_DATE"
Table Full Name: "SUN_SPECTRA.PUBLIC.ORDERS"
Short Description: "Date when the customer order was successfully delivered."

semantic_model_qa

Answer questions about a semantic model using its metadata context.

Parameters:

  • semantic_model_id (required) — the ID of the semantic model
  • question (required) — your natural language question about the model Examples:

Understanding model coverage:

question: "What does this model cover?"
semantic_model_id: "your_model_id_here"

What a good output looks like:

"This semantic model covers customer engagement and support analytics by integrating data on
customer profiles, support ticket records, order transactions including product line items, and
engagement funnel stages segmented by traffic source. It provides insights into the customer
engagement funnel (e.g., viewers, cart adders, purchasers), support ticket volumes and breakdowns
(including ticket categories and issue types), and order activity (including revenue after
discounts, order counts, and delivery outcomes) during the 2024 period."

Finding specific tables:

question: "What table in the model contains information about customer support tickets?"
semantic_model_id: "your_model_id_here"

What a good output looks like:

"The table that contains information about customer support tickets is "SUN_SPECTRA.ZENDESK.TICKETS"."

Debugging & Validation

SQL looks wrong or returns unexpected results? Work through these in order:

  1. Check the semantic layer ID — if you have multiple semantic layers, confirm you're pointing at the right one.
  2. Be more specific in your question — vague questions produce vague SQL. Instead of "show me revenue", try "show me total revenue by region for Q1 2025".
  3. Check your warehouse connection — confirm your DWH connection is active in the Solid UI. The MCP server cannot generate correct SQL if the schema metadata is stale or missing.
  4. Inspect the returned SQL before running it — review table names and joins against your known schema before executing, especially in production.
  5. 401 Unauthorized? — If you're using Option B, confirm the management key is valid and has MCP access. For direct MCP, verify the x-solid-management-key header is set on the transport (not inside tool arguments). For the REST bridge, confirm management_key is in the POST body. There is no JWT to refresh. If results are consistently wrong for a particular metric or table, the issue is likely in the semantic layer definition itself (missing join, incorrect metric logic, etc.) — contact your Solid admin to review the model.

Custom Headers

When using management key auth (direct MCP via x-solid-management-key), you can attach custom headers to enrich Solid's MCP usage logs. Useful for tracing activity across agents and workflows.

HeaderDescription
X-Solid-ClientIdentifies the calling tool or framework (e.g. CrewAI, custom-script)
X-Solid-LabelsComma-separated key=value pairs for tagging requests

Example (any HTTP tool):

{
  "x-solid-management-key": "<your-management-key>",
  "X-Solid-Client": "CrewAI",
  "X-Solid-Labels": "workflow=weekly_report, agent_type=researcher"
}

CrewAI example:

mcp_server = MCPServerHTTP(
    url="https://mcp.production.soliddata.io/mcp",
    headers={
        "x-solid-management-key": os.environ["SOLID_MANAGEMENT_KEY"],
        "X-Solid-Client": "CrewAI",
        "X-Solid-Labels": "workflow=weekly_report,env=production,agent_type=researcher",
    },
    streamable=True,
    cache_tools_list=True,
)

Use X-Solid-Labels to tag by environment (env=production), workflow name, or agent role — whatever makes filtering in your Solid usage dashboard most useful.


Quick Reference

ClientAuth methodWhat to do
Cursor, Claude Desktop, WindsurfBrowser sign-inAdd MCP server URL → sign in when prompted
CrewAIManagement keyPass x-solid-management-key header on the MCP transport — no token exchange
Workato / REST clientsManagement keyPOST to bridge with management_key in the JSON body — no Bearer token
Scripts / CI / HTTP MCP clientsManagement keySame as CrewAI — x-solid-management-key header on direct MCP requests
Microsoft Copilot StudioNative MCP or RESTMCP: API key = management key. REST connector: management_key in body via OpenAPI spec