Make spacetime list, rename and mcp respect the project's server - #5883
Open
krisajenkins wants to merge 1 commit into
Open
Make spacetime list, rename and mcp respect the project's server#5883krisajenkins wants to merge 1 commit into
spacetime list, rename and mcp respect the project's server#5883krisajenkins wants to merge 1 commit into
Conversation
krisajenkins
force-pushed
the
list-respects-config-server
branch
from
September 8, 2026 10:58
36c73f7 to
6dd5ef6
Compare
krisajenkins
marked this pull request as ready for review
September 8, 2026 11:07
Put yourself in a project directory with a perfectly ordinary
`spacetime.json`:
```json
{
"server": "local",
"module-path": "./spacetimedb"
}
```
Run `spacetime call my-db my_reducer` and it hits your local server, as
you'd expect. Now run `spacetime list` to see what's actually running
there. You get maincloud.
The reason is that server resolution from `spacetime.json` is entirely a
side effect of *database* resolution. `db_arg_resolution.rs` walks the
config looking for a database target that matches the database argument,
and the server comes back attached to that target. Every command with a
database argument — `call`, `logs`, `sql`, `describe`, `delete`, `lock`,
`unlock`, `subscribe` — is therefore covered. `list` has no database
argument, so there was nothing to hang the lookup off, and it read
`--server` straight from clap:
```rust
let server = args.get_one::<String>("server").map(|s| s.as_ref());
let token = get_login_token_or_log_in(&mut config, server, !force).await?;
```
`None` then falls through to the CLI's global default server. `rename`
and `mcp` have the same shape and the same bug: `rename` addresses its
database by identity rather than by name, and `mcp`'s database argument
is optional because omitting it serves the whole server.
The consequence is worse than a wrong table. That `server` argument is
also what scopes the *auth token*, so `list` was authenticating against
maincloud with your maincloud credentials and reporting maincloud's
databases as though they were the project's. Nothing errors, the output
is a perfectly plausible list of databases you really do own, and the
same command run with an explicit `--server local` works fine — so it
reads as the user having misremembered which databases they published
rather than as a bug in the CLI.
Add `resolve_config_server`, which reads the server from the config
without going via a database target, and use it in the three affected
commands. It answers only when every target in the config agrees on one
server; a multi-database config spanning several servers has no single
right answer, so it leaves the CLI default alone rather than guess. A
root-level `server` with no `database` at all — the config above — is
handled, and children inherit it.
`mcp` deliberately only takes the server from the config, not the
database: omitting its database argument is a documented mode that
serves the whole server, and inferring one would silently remove that
mode inside a project directory.
- Each affected command gains `--no-config`, matching the commands that
already resolve through `db_arg_resolution.rs`.
- Explicit `--server` still wins over the config, as everywhere else.
# API and ABI breaking changes
None.
# Rollback safety impact
n/a
# Expected complexity level and risk
2 — the resolution helper is a small pure function over the already
existing `collect_all_targets_with_inheritance`. The risk worth naming
is behavioural rather than structural: these three commands now talk to
a different server when run inside a project whose config names one, and
`list` will consequently use that server's token. That is the intended
fix, but it is a visible change for anyone who was relying on `list`
always showing the default server from within a project directory;
`--no-config` restores the old behaviour.
# Testing
- [x] Four unit tests over `single_config_server`: root-level server with
no database, children inheriting the root server, a config that
omits `server`, and children that disagree.
- [x] Ran against a live setup with `maincloud` as the default server and
a `spacetime.json` naming `local`: config-driven `list` matches
`list --no-config -s local`, `list --no-config` matches the default
server, and an explicit `--server` still overrides the config.
- [x] `cargo test -p spacetimedb-cli` (180 passed), clippy and fmt clean.
- [ ] Reviewer: check the `mcp` judgement call above — should
`spacetime mcp` in a project directory also infer the database?
krisajenkins
force-pushed
the
list-respects-config-server
branch
from
September 8, 2026 16:01
6dd5ef6 to
81e9b32
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Create a project, and configure it to work against your local server, by putting this in
spacetime.json:{ "server": "local", "module-path": "./spacetimedb" }If you run
spacetime call my-db my_reducerit hits your local server, asyou'd expect. However,
spacetime listdoesn't - that ignores the config andgoes to maincloud. Same for
spacetime renameandspacetime mcp- theyignore the config and go to maincloud.
Whatever the behaviour should be, it should be consistent across all
commands. This PR assumes we want to consistently respect
spacetime.json.The cause is that server resolution from
spacetime.jsonis entirely aside effect of database resolution.
db_arg_resolution.rswalks theconfig looking for a database target that matches the database argument,
and the server comes back attached to that target. Every command with a
database argument —
call,logs,sql,describe,delete,lock,unlock,subscribe— is therefore covered.listhas no databaseargument, so there was nothing to hang the lookup off, and it read
--serverstraight from clap:Nonethen falls through to the CLI's global default server.renameand
mcphave the same shape and the same bug:renameaddresses itsdatabase by identity rather than by name, and
mcp's database argumentis optional because omitting it serves the whole server.
The consequence is worse than a wrong table. That
serverargument isalso what scopes the auth token, so
listwas authenticating againstmaincloud with your maincloud credentials and reporting maincloud's
databases as though they were the project's. Nothing errors, the output
is a perfectly plausible list of databases you really do own, and the
same command run with an explicit
--server localworks fine — so itreads as the user having misremembered which databases they published
rather than as a bug in the CLI.
Add
resolve_config_server, which reads the server from the configwithout going via a database target, and use it in the three affected
commands. It answers only when every target in the config agrees on one
server; a multi-database config spanning several servers has no single
right answer, so it leaves the CLI default alone rather than guess. A
root-level
serverwith nodatabaseat all — the config above — ishandled, and children inherit it.
mcpdeliberately only takes the server from the config, not thedatabase: omitting its database argument is a documented mode that
serves the whole server, and inferring one would silently remove that
mode inside a project directory.
--no-config, matching the commands thatalready resolve through
db_arg_resolution.rs.--serverstill wins over the config, as everywhere else.API and ABI breaking changes
None.
Rollback safety impact
n/a
Expected complexity level and risk
2 — the resolution helper is a small pure function over the already
existing
collect_all_targets_with_inheritance. The risk worth namingis behavioural rather than structural: these three commands now talk to
a different server when run inside a project whose config names one, and
listwill consequently use that server's token. That is the intendedfix, but it is a visible change for anyone who was relying on
listalways showing the default server from within a project directory;
--no-configrestores the old behaviour.Testing
single_config_server: root-level server withno database, children inheriting the root server, a config that
omits
server, and children that disagree.maincloudas the default server anda
spacetime.jsonnaminglocal: config-drivenlistmatcheslist --no-config -s local,list --no-configmatches the defaultserver, and an explicit
--serverstill overrides the config.cargo test -p spacetimedb-cli(180 passed), clippy and fmt clean.mcpjudgement call above — shouldspacetime mcpin a project directory also infer the database?