Skip to content

AI Integration (MCP)

SchemaStack supports the Model Context Protocol (MCP) — an open standard that lets AI assistants like Claude interact directly with your workspace data. Instead of copy-pasting data or writing API calls, your AI assistant can browse schemas, query data, and even create records through a natural conversation.

What Can AI Do With Your Workspace?

Once connected, an AI assistant can:

  • Browse your schema — list workspaces, views (tables), and columns
  • Query data — search and retrieve records with pagination
  • Create and edit records — insert new rows or update existing values
  • Manage schema — create views, add columns, set up validation constraints
  • Understand your data model — read form schemas to understand column types and constraints

Access Levels

Each workspace has its own MCP access level, giving you fine-grained control over what AI clients can do:

LevelRead SchemaQuery DataCreate/Edit RecordsModify Schema
Disabled (default)NoNoNoNo
Read-OnlyYesYesNoNo
Data-OnlyYesYesYesNo
FullYesYesYesYes

TIP

Start with Read-Only to let AI assistants explore and query your data safely. Upgrade to Data-Only or Full when you need AI-assisted data entry or schema management.

Setting Up MCP Access

1. Enable MCP for Your Workspace

In the Admin app, open Workspace → MCP, set the access level to Read-Only, and save. MCP is Disabled by default, so this step is required — keys created while the workspace is disabled are rejected until you raise the level.

Only workspace administrators (OWNER or ADMIN role) can change MCP settings.

Prefer the API?
http
PUT /api/workspaces/{workspaceUuid}/mcp-config
Authorization: Bearer <your-token>
Content-Type: application/json

{
  "accessMode": "READ_ONLY"
}

2. Create an MCP API Key

On the same page, choose Create API key. Copy the key — it starts with mcp_ and is shown only once.

A key carries its own access level, and the effective level is the lower of the key's level and the workspace ceiling. You can also scope a key to specific views, so an assistant only ever sees the tables you point it at.

3. Connect Claude Desktop

Add SchemaStack as an MCP server in your Claude Desktop configuration file:

json
{
  "mcpServers": {
    "schemastack": {
      "url": "https://schemastack.io/mcp",
      "headers": {
        "Authorization": "Bearer mcp_your_key_here"
      }
    }
  }
}
json
{
  "mcpServers": {
    "schemastack": {
      "url": "https://schemastack.io/mcp",
      "headers": {
        "Authorization": "Bearer mcp_your_key_here"
      }
    }
  }
}

4. Connect Claude Code

Add SchemaStack as an MCP server in your project's .mcp.json file:

json
{
  "mcpServers": {
    "schemastack": {
      "type": "url",
      "url": "https://schemastack.io/mcp",
      "headers": {
        "Authorization": "Bearer mcp_your_key_here"
      }
    }
  }
}

5. Start Using It

Once connected, you can ask your AI assistant things like:

  • "What workspaces do I have?"
  • "Show me the columns in the Customers view"
  • "Query the first 10 orders"
  • "Add a new column called 'priority' to the Tasks view"
  • "Create a new customer record with name 'Acme Corp' and email '[email protected]'"

Available Tools

Your AI assistant has access to 56 tools organized by category:

Workspace Tools

ToolDescription
get_workspaceGet workspace details including its views

View Tools

ToolDescription
list_viewsList all views (tables) in a workspace
get_viewGet view details with column definitions
create_viewCreate a new view (database table)
update_viewUpdate a view's name or slug
delete_viewDelete a view and its data

Column Tools

ToolDescription
list_columnsList columns in a view; supports nameFilter, limit/offset paging, and a compact projection for large views
add_columnAdd a column with a display name and widget type (STRING, EMAIL, DECIMAL, SELECT, …); also creates computed (formula), relationship, and aggregate columns
update_columnUpdate display name, widget type, options, form visibility, API key (dataKey), aggregate settings
preview_column_changeDry-run: answers whether a change would require a database migration, with full impact analysis
delete_columnRemove a column
get_relationship_optionsPaginated dropdown options for a foreign-key column
cancel_migrationForce-cancel a stuck migration that has left a table locked

Data Tools

ToolDescription
get_form_schemaGet the full schema for a view (types, constraints, widgets)
query_dataQuery records with pagination, filtering, and sorting
get_recordGet a single record by ID
create_recordCreate a new data record
update_recordUpdate a cell value in a record
bulk_editApply the same value(s) to many rows at once (synchronous)
fill_columnFill a column across many rows, with an optional row filter
bulk_updateBulk update rows — asynchronous, returns a job ID
bulk_deleteBulk delete rows — asynchronous, returns a job ID
bulk_exportExport rows to CSV or JSON — asynchronous, download link via SSE

Known issues in query_data filters

IN / NOT_IN currently match nothing (single-parameter binding bug), and a filter on a raw foreign-key column that has a relationship display column is silently ignored — the response is the unfiltered result. Verify totalRecords before acting on filtered data, and prefer EQ filters on regular columns. Both issues are tracked. The generated REST API's filter[...] syntax is unaffected.

Constraint Tools

ToolDescription
list_constraintsList validation constraints on a column
add_constraintAdd a validation constraint (REQUIRED, NOT_BLANK, MAX_LENGTH, EMAIL, etc.)
update_constraintChange a constraint's value, message or enabled state
toggle_constraintEnable or disable a constraint without deleting it
delete_constraintRemove a validation constraint
list_entity_constraintsList table-level (multi-field) constraints on a view
add_entity_constraintAdd a table-level constraint
update_entity_constraintUpdate a table-level constraint
delete_entity_constraintRemove a table-level constraint

Relationship Tools

ToolDescription
get_relationship_graphTraverse how a view connects to others via foreign keys (depth 1–5)
get_available_relationshipsWhich related tables/columns can still be added
add_relationship_columnAdd a related-record column to a view
get_relationship_pathsRead the configured join paths for a view
set_relationship_pathsConfigure join paths
clear_relationship_pathsReset join paths

Schema Tools

ToolDescription
import_schemaImport an existing database schema — creates views and columns from live tables. Alias of sync_schema
check_drift_quickHash comparison: has the database drifted from stored metadata?
check_driftFull drift report against the workspace database
sync_schemaDetect and apply changes after the database was altered externally. Alias of import_schema
sync_view_columnsBackfill view columns for views that have none — it does not refresh a view that already has them
reset_schemaDestructive — drop all schema metadata and re-import from the database

Two names, one operation

import_schema and sync_schema run exactly the same sync. Both are safe to run repeatedly, and neither duplicates existing views — use whichever name reads better for what you are doing.

sync_view_columns is narrower than its name suggests: it only fills in views that have no columns at all, and skips any view that already has them. It cannot repair a view whose columns have drifted — use sync_schema for that.

Index Tools

ToolDescription
list_indexesList database indexes on a view's table
create_indexCreate an index, including composite and unique
delete_indexDrop an index

API Config Tools

ToolDescription
get_entity_api_configWhich REST operations a view exposes on the public Workspace API
update_entity_api_configTurn read/create/update/delete on or off, set max page size

Filter Preset Tools

ToolDescription
list_filter_presetsList saved filter/sort/column configurations for a view
get_filter_presetRead one preset
create_filter_presetSave a reusable filter/sort/column configuration
update_filter_presetUpdate a preset
delete_filter_presetDelete a preset
get_filter_preset_tagsList tags used across a view's presets

External Identity Tools

ToolDescription
get_external_idp_configRead the workspace's external OIDC configuration. Requires a full-access key — this is authentication configuration, not workspace data

Configuring the external identity provider is not available over MCP, at any access level. Pointing a workspace at an OIDC issuer grants standing access to everyone holding that issuer's tokens, and it outlives revoking the key that set it — so "revoke the credential" would stop being a complete response to a leak. It stays an administrator action: the admin UI, or PUT /api/workspaces/{uuid}/external-idp with a signed-in session.

Connecting a Hosted AI Client

Announcement

The walkthrough version of this section, with the full flow diagram: Add your database to Claude with one URL.

Claude Desktop, Claude Code and Cursor read a config file, so pasting an mcp_ key works. A hosted client — one where you only ever type a URL, like adding a connector in Claude or ChatGPT — has nowhere to put a key. Those clients sign in with OAuth, and SchemaStack now tells them how without you configuring anything.

Give the connector this URL:

https://schemastack.io/mcp

What happens next is automatic:

  1. The client calls the URL with no credential and gets a 401 naming /.well-known/oauth-protected-resource/mcp.
  2. That document names the authorization server, whose own document at /.well-known/oauth-authorization-server lists the endpoints.
  3. The client registers itself and gets a client_id. Registering grants it nothing.
  4. Your browser opens the SchemaStack consent screen. You sign in if you are not already, and see which application is asking and what for. Because the URL named no workspace, the screen also lists the workspaces you can reach so you can choose one. If the application registered itself rather than being added by an administrator, the screen says so.
  5. Approving returns the client an access token for the workspace you chose, and it can use the tools that workspace allows.

WARNING

The consent screen shows a name the application chose for itself. Anyone can register a client under any name, so treat the name as a claim, not a recommendation — only approve a connection you started yourself and recognise.

Naming the workspace up front

You can skip the picker by naming the workspace in the URL:

https://schemastack.io/mcp?workspace=<workspaceUuid>

Open the workspace in the admin app to find its UUID; it is in the address bar. Worth doing when you are writing setup instructions for other people, or connecting an account that can reach many workspaces and you want no ambiguity about which one. The consent screen then shows that workspace instead of a list, and offers no choice — if you cannot reach it, consent is refused rather than quietly falling back to one you can.

Either way the token is bound to one workspace: pointing it at another workspace's URL is refused.

The list only ever contains workspaces you can already reach. An organisation owner or admin sees every workspace in the organisation; everyone else sees the ones they are a member of. A workspace in maintenance mode is offered to administrators only, exactly as it is elsewhere.

Cutting off a connection

Workspace → OAuth2 lists the applications with active sessions in the workspace, including ones that registered themselves, and who granted them. An administrator can revoke a whole application's sessions or one person's.

Revoking takes effect immediately, including for a token the application is already holding. Access tokens are not stored anywhere and cannot be reached, so a revocation records the moment it happened and any token issued before that is refused from then on — on MCP and on the Workspace API alike.

Signing In With OAuth Instead of a Key

An MCP client can also authenticate with an OAuth 2.0 access token — the same token the Workspace API accepts, obtained through an Authorization Code + PKCE flow. Use this when an application acts on behalf of a person who signs in, rather than holding a workspace key of its own. An administrator registers the application first, under Workspace → OAuth2 in the admin app, which is where its client ID and redirect URIs come from.

Point the client at the workspace you mean:

https://schemastack.io/mcp?workspace=<workspaceUuid>

The ?workspace= parameter is optional — the token already says which workspace it is for — but when you supply it, it has to match. That way a token for one workspace cannot be pointed at another workspace's address.

What an OAuth token is allowed to do

An access token is capped lower than an API key:

ScopeMCP access
workspace:readRead-Only
workspace:writeData-Only
Full is not reachable with an OAuth token

Consenting to a scope called "write" means agreeing to let the application write records — not to let it drop a column or change a type on a database you own. Schema changes stay with mcp_ keys, which an administrator creates knowingly.

The workspace access level still applies on top, so a workspace set to Read-Only keeps an application with workspace:write at Read-Only, and a workspace with MCP Disabled refuses the token outright.

TIP

Disabling an OAuth2 client in Workspace → OAuth2 cuts off its MCP access straight away, without waiting for its access tokens to expire.

Transport Protocol

SchemaStack uses the Streamable HTTP MCP transport (not SSE). This is the newer, stateless-friendly transport from the MCP specification (2025-03-26).

How It Works

All communication happens via POST requests to a single /mcp endpoint. The server uses sessions to track state:

  1. Initialize — your first request must be an initialize call. The server returns an Mcp-Session-Id header in the response.
  2. Include the session ID — all subsequent requests must include the Mcp-Session-Id header from step 1.

Most MCP clients (Claude Desktop, Claude Code, Cursor) handle this handshake automatically. If you're building a custom integration, here's the flow:

bash
# Step 1: Initialize and capture the session ID
curl -D- -X POST https://schemastack.io/mcp \
  -H "Authorization: Bearer <your-mcp-api-key>" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0", "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-03-26",
      "capabilities": {},
      "clientInfo": {"name": "my-app", "version": "1.0"}
    }
  }'
# → Response includes: Mcp-Session-Id: abc123...

# Step 2: Call tools with the session ID
curl -X POST https://schemastack.io/mcp \
  -H "Authorization: Bearer <your-mcp-api-key>" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "Mcp-Session-Id: abc123..." \
  -d '{"jsonrpc": "2.0", "id": 2, "method": "tools/call",
       "params": {"name": "get_workspace", "arguments": {}}}'

TIP

If you see the error Mcp-Session-Id header not found, your client is skipping the initialize handshake. Make sure it sends an initialize request first and includes the returned session ID on all follow-up requests.

Schema Migrations

When an admin changes a column's type or adds constraints, a schema migration runs on the database. During this time, the affected table may be temporarily unavailable.

If your AI assistant tries to read or write data on a table that's being migrated, it will receive an error like:

Table 'customers' is currently being migrated (operation: abc-123, impact: BLOCKING). Please retry in ~15 seconds.

The AI assistant can inform you and retry after the migration completes. Most migrations take seconds — only large tables with type changes take longer.

What's blocked depends on the migration type:

MigrationReads blocked?Writes blocked?
Column type change (PostgreSQL)YesYes
Column type change (MySQL)NoYes
Add NOT NULL (PostgreSQL)YesYes
Add NOT NULL (MySQL)NoNo
Add unique constraintNoYes

TIP

If your AI workflow needs uninterrupted access, coordinate schema changes with your team to avoid running migrations during active AI sessions.

Security

  • Authentication: an mcp_ API key, or an OAuth 2.0 access token. Your browser session token is not accepted — signing in to the admin app grants an AI client nothing.
  • Authorization: the workspace MCP access level is the ceiling, and it is Disabled until an administrator raises it. A key may carry a lower level than the ceiling, and may be scoped to named views; the effective permission is always the lower of the two. An OAuth token additionally cannot exceed Data-Only.
  • Workspace isolation: a credential reaches exactly one workspace — the one it was issued for. There is no credential that spans an organisation.

WARNING

An mcp_ key is a workspace credential, not a personal one: anyone holding it has the access level it carries, whoever created it. Keep keys at the lowest level that does the job, scope them to specific views where you can, and revoke them in Workspace → MCP when an integration is retired.

Checking MCP Status

To check the current MCP configuration for a workspace:

http
GET /api/workspaces/{workspaceUuid}/mcp-config
Authorization: Bearer <your-token>

Response:

json
{
  "accessMode": "READ_ONLY"
}

SchemaStack Documentation