Appearance
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:
| Level | Read Schema | Query Data | Create/Edit Records | Modify Schema |
|---|---|---|---|---|
| Disabled (default) | No | No | No | No |
| Read-Only | Yes | Yes | No | No |
| Data-Only | Yes | Yes | Yes | No |
| Full | Yes | Yes | Yes | Yes |
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 'hello@acme.com'"
Available Tools
Your AI assistant has access to 56 tools organized by category:
Workspace Tools
| Tool | Description |
|---|---|
get_workspace | Get workspace details including its views |
View Tools
| Tool | Description |
|---|---|
list_views | List all views (tables) in a workspace |
get_view | Get view details with column definitions |
create_view | Create a new view (database table) |
update_view | Update a view's name or slug |
delete_view | Delete a view and its data |
Column Tools
| Tool | Description |
|---|---|
list_columns | List columns in a view; supports nameFilter, limit/offset paging, and a compact projection for large views |
add_column | Add a column with a display name and widget type (STRING, EMAIL, DECIMAL, SELECT, …); also creates computed (formula), relationship, and aggregate columns |
update_column | Update display name, widget type, options, form visibility, API key (dataKey), aggregate settings |
preview_column_change | Dry-run: answers whether a change would require a database migration, with full impact analysis |
delete_column | Remove a column |
get_relationship_options | Paginated dropdown options for a foreign-key column |
cancel_migration | Force-cancel a stuck migration that has left a table locked |
Data Tools
| Tool | Description |
|---|---|
get_form_schema | Get the full schema for a view (types, constraints, widgets) |
query_data | Query records with pagination, filtering, and sorting |
get_record | Get a single record by ID |
create_record | Create a new data record |
update_record | Update a cell value in a record |
bulk_edit | Apply the same value(s) to many rows at once (synchronous) |
fill_column | Fill a column across many rows, with an optional row filter |
bulk_update | Bulk update rows — asynchronous, returns a job ID |
bulk_delete | Bulk delete rows — asynchronous, returns a job ID |
bulk_export | Export 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
| Tool | Description |
|---|---|
list_constraints | List validation constraints on a column |
add_constraint | Add a validation constraint (REQUIRED, NOT_BLANK, MAX_LENGTH, EMAIL, etc.) |
update_constraint | Change a constraint's value, message or enabled state |
toggle_constraint | Enable or disable a constraint without deleting it |
delete_constraint | Remove a validation constraint |
list_entity_constraints | List table-level (multi-field) constraints on a view |
add_entity_constraint | Add a table-level constraint |
update_entity_constraint | Update a table-level constraint |
delete_entity_constraint | Remove a table-level constraint |
Relationship Tools
| Tool | Description |
|---|---|
get_relationship_graph | Traverse how a view connects to others via foreign keys (depth 1–5) |
get_available_relationships | Which related tables/columns can still be added |
add_relationship_column | Add a related-record column to a view |
get_relationship_paths | Read the configured join paths for a view |
set_relationship_paths | Configure join paths |
clear_relationship_paths | Reset join paths |
Schema Tools
| Tool | Description |
|---|---|
import_schema | Import an existing database schema — creates views and columns from live tables. Alias of sync_schema |
check_drift_quick | Hash comparison: has the database drifted from stored metadata? |
check_drift | Full drift report against the workspace database |
sync_schema | Detect and apply changes after the database was altered externally. Alias of import_schema |
sync_view_columns | Backfill view columns for views that have none — it does not refresh a view that already has them |
reset_schema | Destructive — 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
| Tool | Description |
|---|---|
list_indexes | List database indexes on a view's table |
create_index | Create an index, including composite and unique |
delete_index | Drop an index |
API Config Tools
| Tool | Description |
|---|---|
get_entity_api_config | Which REST operations a view exposes on the public Workspace API |
update_entity_api_config | Turn read/create/update/delete on or off, set max page size |
Filter Preset Tools
| Tool | Description |
|---|---|
list_filter_presets | List saved filter/sort/column configurations for a view |
get_filter_preset | Read one preset |
create_filter_preset | Save a reusable filter/sort/column configuration |
update_filter_preset | Update a preset |
delete_filter_preset | Delete a preset |
get_filter_preset_tags | List tags used across a view's presets |
External Identity Tools
| Tool | Description |
|---|---|
get_external_idp_config | Read 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/mcpWhat happens next is automatic:
- The client calls the URL with no credential and gets a
401naming/.well-known/oauth-protected-resource/mcp. - That document names the authorization server, whose own document at
/.well-known/oauth-authorization-serverlists the endpoints. - The client registers itself and gets a
client_id. Registering grants it nothing. - 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.
- 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:
| Scope | MCP access |
|---|---|
workspace:read | Read-Only |
workspace:write | Data-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:
- Initialize — your first request must be an
initializecall. The server returns anMcp-Session-Idheader in the response. - Include the session ID — all subsequent requests must include the
Mcp-Session-Idheader 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:
| Migration | Reads blocked? | Writes blocked? |
|---|---|---|
| Column type change (PostgreSQL) | Yes | Yes |
| Column type change (MySQL) | No | Yes |
| Add NOT NULL (PostgreSQL) | Yes | Yes |
| Add NOT NULL (MySQL) | No | No |
| Add unique constraint | No | Yes |
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"
}