Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ These changes are allowed by automatic migration, but may cause runtime errors f
- **Adding new columns to the end of a table with a default value.** The new column must be added at the end of the table definition and must have a default value specified. Non-updated clients will not be aware of the new column.
- **Changing or removing reducers.** Clients attempting to call the old version of a changed reducer or a removed reducer will receive runtime errors.
- **Changing tables from public to private.** Clients subscribed to a newly-private table will receive runtime errors.
- **Changing table or column accessor names while preserving canonical names.** The stored data can be migrated, but module and client code generated from the old accessors must be updated.
- **Changing an index source name while preserving the index accessor.** The index source name is the generated or explicit raw schema name used to look up the index, not the canonical index name used to match it across module versions. The stored index can be migrated in place, but SQL or migration output may refer to the new source name.
- **Removing empty tables.** SpacetimeDB can remove a table only if it has no rows. Removing a table disconnects active clients. Clients using bindings or subscription queries generated from the old schema must be updated before reconnecting, because the removed table no longer exists.
- **Removing `Primary Key` annotations.** Non-updated clients will still use the old primary key as a unique key in their local cache, which can result in non-deterministic behavior when updates are received.
- **Removing indexes.** This is only breaking in specific situations. The main issue occurs with subscription queries involving semijoins, such as:

Expand All @@ -48,12 +51,13 @@ These changes are allowed by automatic migration, but may cause runtime errors f

The following changes cannot be performed with automatic migration and will cause the publish to fail:

- **Removing tables.**
- **Removing or modifying existing columns.** This includes changing the type, renaming, or reordering columns.
- **Removing non-empty tables.** Empty tables can be removed automatically, but table removal fails if the existing table contains rows.
- **Removing or modifying existing columns.** This includes changing the type, canonical name, or order of columns. Changing only the generated accessor alias is allowed, but generated module and client code must be updated.
- **Adding columns without a default value.** New columns must have a default value so existing rows can be populated.
- **Adding columns in the middle of a table.** New columns must be added at the end of the table definition.
- **Changing whether a table is used for `scheduling`.**
- **Adding `Unique` or `Primary Key` constraints.** This could result in existing tables being in an invalid state.
- **Changing an index accessor name.** Create a new index accessor instead of renaming an existing one.

## Working with Forbidden Changes

Expand Down Expand Up @@ -91,6 +95,7 @@ For complex schema changes that aren't supported by automatic migration:
During automatic migrations, active client connections are maintained and subscriptions continue to function. However:

- Clients may witness brief interruptions in scheduled reducers (such as game loops)
- Some migrations, such as removing a table, disconnect active clients so they reconnect against the new schema
- New module versions may remove or change reducers, causing runtime errors for clients calling those reducers
- Clients won't automatically know about schema changes - you may need to regenerate and update client bindings

Expand Down
90 changes: 90 additions & 0 deletions docs/docs/00300-resources/00200-reference/00150-mcp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
title: MCP Reference
slug: /resources/mcp
---

SpacetimeDB can serve a host or a single database to MCP-aware agents and editors.
The MCP server exposes tools for inspecting schemas, running SQL, and invoking reducers.

:::warning Unstable Feature
MCP support is currently unstable and subject to breaking changes.
:::

## Starting the MCP Server

Use the `spacetime mcp` command to bridge an MCP client over stdio to a SpacetimeDB host:

```bash
spacetime mcp --server local
spacetime mcp my-database --server local
```

When you omit the database argument, the MCP server is host-wide.
When you pass a database name or identity, the MCP server is scoped to that database.
The database argument can also come from the `SPACETIMEDB_DB_NAME` environment variable.

The command uses your saved SpacetimeDB identity unless you pass `--anonymous`.

## Host-wide vs Database-scoped Tools

The tool shape depends on whether the MCP server is host-wide or database-scoped.
Read the MCP client's tool list before constructing tool calls.

In host-wide mode, every data tool takes a required `database` argument.
The `database` value can be a database name or identity.
Host-wide mode also exposes `list_databases`.

```json
{ "database": "my-database", "sql": "SELECT * FROM message" }
```

In database-scoped mode, the database is fixed by the `spacetime mcp <database>` command.
Data tools do not take a `database` argument, and `list_databases` is not exposed.

```json
{ "sql": "SELECT * FROM message" }
```

## Tools

| Tool | Host-wide arguments | Database-scoped arguments | Description |
| --- | --- | --- | --- |
| `list_databases` | none | not available | Lists the databases owned by your identity on the host. |
| `ping` | optional `message` | optional `message` | Health check that echoes an optional message. |
| `get_schema` | `database` | none | Returns the schema as JSON, including types, tables, and reducers. |
| `sql` | `database`, `sql`, optional `confirmed` | `sql`, optional `confirmed` | Runs SQL and returns rows as JSON. Set `confirmed` to wait for a durably confirmed read. |
| `call` | `database`, `reducer`, optional `args` | `reducer`, optional `args` | Invokes a reducer. `args` is a JSON array of positional reducer arguments. |

For reducer calls with no arguments, omit `args` or pass an empty array.
For reducer calls with arguments, pass values in reducer parameter order:

```json
{ "database": "my-database", "reducer": "send_message", "args": ["hello"] }
```

## Identity and Permissions

MCP tools run with the identity used to start `spacetime mcp`, the same as other SpacetimeDB APIs.

Reducers are the normal write path.
Use `call` to change application state through module logic.
The reducer runs transactionally and either commits or rolls back.

The `sql` tool can read public tables.
SQL writes require ownership of the database.
Prefer reducers for writes so authorization and validation stay in the module.

Private tables are not client-readable through MCP SQL.
The `get_schema` tool can still show private table declarations, so a `no such table` error from `sql` can mean the table is private for the current identity rather than absent from the module.

## Common Errors

| Error | Meaning |
| --- | --- |
| `database argument must be a string` | The server is host-wide and the tool call omitted `database`, or passed a non-string value. |
| `unknown tool: list_databases` | The server is database-scoped, so `list_databases` is not available. |
| `` `x` not found `` | No database named `x` exists on this server for the current identity, or the call used a name where an identity was required. |
| `no such table: x` | The table is private for the current identity, absent from the module, or the call targeted the wrong database. |

Tool failures are returned in the MCP response body.
Read the error text before retrying with a different tool shape or database value.
Loading