Repository navigation
EN Team Remote MCP
Français · Type: how-to + reference · Audience: author · Context: hosted Studio · Status: ready · Applies from: 4.2.3
The Studio Server (hosted team Studio) · contract: experimental · verified by CI (support matrix of 4.4.0, 2026-10-23): Postgres, S3 and Keycloak in CI; Chromium and Firefox (job studio-hosted); WebKit on macOS, by hand only · automated checks: jobs
studio-hosted,studio-install-smoke; CI planstudioHosted; 3 test files · people's passes:studio-hostednot run (#149),studio-collabnot run (#150),studio-previewnot run (#166),studio-assets-hostednot run (#167),studio-mcp-remotenot run (#196),studio-oidc-genericnot run (#197) · known limits:mcp-remote-limits
An AI agent (Claude Code, Cursor, any MCP client) can work on a team Studio as a member: with your role, inside the
spans others hold, its writes in the journal under your name. This page connects an agent to a hosted Studio, either
over HTTP to the server's own /mcp, or through the local MCP server pointed at the Studio, and lists the tools each
offers.
An agent that reads, checks and (with a dev's role) edits the hosted game through the same checks as the Studio's page: the gate, the role, the spans, the journal, a retry applied once.
A hosted Studio (the Studio Server) with OIDC, from 4.2.3 (ADR 0029). For the local MCP on your own game folder, see Local MCP: setting up each client and MCP tools.
- A member's account: a
reviewerat least to read and check, adevto write. - The Studio's provider gives the CLI or the agent access tokens as JWTs for the Studio's audience
(
oidc.audience). Keycloak does with an audience mapper; a provider that issues opaque access tokens (GitLab's OAuth applications, at the time of writing) cannot serve the CLI nor the remote MCP (see Generic OIDC and GitLab). - For the local way: the engine repository (or the installed package) on your machine, and the CLI logged in.
On your machine, in the engine repository's folder (or a created project with the package installed). The agent's configuration is your MCP client's file.
-
Choose the way.
-
Remote, over HTTP: the server's
/mcp, in MCP's Streamable HTTP transport, stateless (each POST a whole exchange, answered in JSON). Nothing to run locally, but the token lasts minutes. - Local, over stdio, pointed at the server: the same tools, through the Studio's API, with the CLI's token refreshed by itself. Better for a long session.
-
Remote, over HTTP: the server's
-
Remote: give the client a token. A client that follows MCP's authorization finds the provider at
/.well-known/oauth-protected-resource/mcp(RFC 9728); the token it gets must carry the Studio'soidc.audience. A provider that sets the audience from MCP'sresourceparameter gives<public URL>/mcp: setoidc.audienceto that URL. Keycloak needs an audience mapper either way, and a client registered for the agent. Otherwise give it a token yourself:# on your machine, in the engine repository npm run studio-server -- login --server https://studio.example.fr # once: the device flow npm run studio-server -- token --server https://studio.example.fr # prints an access token
and send it as
Authorization: Bearer <token>:{ "mcpServers": { "quest-n-click": { "type": "http", "url": "https://studio.example.fr/mcp", "headers": { "Authorization": "Bearer <token>" } } } }The token lasts minutes: the Studio refuses an access token that lives longer than 5 minutes, or the configuration's
oidc.maxTokenSeconds(30 to 900). Give the client a new one when it ends. The browser's session cookie is never accepted there.
-
Local: point the stdio server at the Studio. Log in once, then start the MCP server with
--server:# on your machine, in the engine repository npm run studio-server -- login --server https://studio.example.fr npm run -s mcp -- --server https://studio.example.frIn a client's configuration, the command is
npmwith the arguments["--prefix", "/path/to/quest-n-click", "run", "-s", "mcp", "--", "--server", "https://studio.example.fr"]. The token is refreshed by itself; https only.
-
Check it works. Ask the agent to call
list_rooms. Its first instructions say it is on a shared Studio: a part another member holds refuses its write (423), and it should say what it needs in a note.
| Offered on a hosted Studio (both ways) | Not offered there |
|---|---|
list_rooms, get_room, get_ir, get_storyboard, get_notes
|
screenshot (needs a browser on the machine) |
set_layout, set_text, set_value, add_entity, set_storyboard, add_note
|
run_tests (needs the repository) |
validate, solve (without a reality policy: a 501), lint, content_report
|
read_doc, search_docs, list_docs (the documentation) |
world_graph, dialogue_tree, puzzle_graph, storyboard_coverage, playtests
|
asset_prompts, speedrun_verify
|
A tool whose ability the backend lacks is not offered at all. An agent on a hosted Studio reads the documentation
through the local stdio MCP of the same engine version, without --server.
-
A member's write. Each tool call is a request to the Studio's
/apiwith your token: your role, your spans, your name in the journal and the audit. A reviewer's agent cannot write (403). - 423 like you. A span another member holds refuses the write, and the tool returns the message naming them.
-
No base revision. An agent sends no
x-studio-base: its writes are computed by the server on the file as it is now and checked by the validation guard, but not refused because someone wrote the file since the agent read it. - Applied once. Each write carries its own operation id.
-
Notes. A note an agent adds without an author is signed
ai, recorded under your member's name all the same (over HTTP the server never sees the MCP client's name). - Removed, stopped. A member removed is refused at the next call; their tokens are revoked with them.
Guarantee ·
mcp-bearer-only· referenced · scope self-checked by the author (AI), not reviewed/mcpasks for a Bearer token, and refuses a token of another audience, the session cookie, a non-member, and a GET.
Limit ·
mcp-remote-limitsOne JSON-RPC message per request: a batch is refused (400).GETandDELETEon/mcpanswer 405 (no stream, no session). A tool's request gives up after 5 minutes, or when the client goes away. Many expired tokens at once can make the next refusals 429 for a minute (they are counted for the loopback's address); valid requests are never slowed.
list_rooms answers the hosted game's rooms. A write made by the agent appears in the Studio's header as a new
revision, in your name; GET /api/ops lists it.
| Symptom | Cause | Fix |
|---|---|---|
401 with WWW-Authenticate: Bearer resource_metadata="…"
|
No token, or an expired one | Give a token; renew it |
401 the access token is not valid
|
Another audience, an id_token, or a token living longer than allowed | Configure the audience mapper; use an access token |
403 not a member of this project
|
The account has no membership | Ask an owner for an invitation |
not logged in to <url>: run studio-server login --server <url> |
The local way without a login | Log in first |
<url> is not https: the tokens would travel in clear |
An http URL | Use the https URL |
| The tool returns a 423 message | A span someone holds | Leave a note, or wait |
The agent's writes are operations of the journal like yours. The local way keeps tokens in
~/.config/web-scumm/studio-tokens.json (mode 0600).
The agent's operations are yours: your Undo in the Studio takes them back, latest first. To stop an agent at once, stop its process or remove its token from the client. An owner's End sessions on your account refuses every token issued before now, but a local stdio server gets a new one from its refresh token (see Managing members).
-
ADR 0029,
studio-server/src/server/mcp.ts. -
tools/studio/http-backend.ts,tools/mcp/tools-server.ts. - The server's command line.
Generated publication · publication générée — current documentation · documentation courante: quest'n'click 4.4.0 r1, documentation revision · révision de la documentation 8dc717c69acb62c4742b69c54a7e7dfb620f75d8.
Earlier versions and permalinks · versions précédentes et liens permanents: https://wanoo.github.io/quest-n-click/docs/
An edit made in this wiki is overwritten at the next publication · une modification faite dans ce wiki est écrasée à la publication suivante.
Edit the source · Modifier la source · Report an error · Signaler une erreur
Index (6)
Start (6)
Play (9)
Install (17)
- Requirements
- Install from the release archive
- Install from npm, once published
- Install from the repository to work on the engine
- doctor: checking your machine
- Image toolchain
- Audio toolchain: ffmpeg, fluidsynth, Furnace, uv
- Upgrade
- Upgrade notes: 4.4
- Upgrade notes: 4.3
- Upgrade notes: 4.2
- Upgrade notes: 4.1
- Upgrade notes: v3
- Upgrade notes: v2 to v3
- Coming from web-scumm
- Package reference
- Install troubleshooting
Create a game (55)
- Your first game
- Layout of a created project and of the engine repository
- The working loop
- Content principles and the identity contract
- Rooms
- Geometry: placement, walk zones, masks, layers, camera
- Something is visible but unreachable
- Reactions
- Game commands
- Conditions
- Flags, variables and events: which to use
- Custom code
- Characters
- Items and inventory
- World map
- Dialogues
- Scripts and events
- Moving characters: patrols and walks
- Exits
- Chapters and objectives
- State and saves: persistent or temporary, renaming an id, migrations
- Staging: wide rooms and animations
- The stage: lights, particles, floors
- Skin and fonts
- Title and credits
- Heroes: several characters and hero choice
- Built-in minigames
- A custom minigame
- Translations
- Music in stems
- Sound effects
- Voices: per language and per hero
- Images: prompts, cutting sheets, transparency, scale
- Asset provenance
- The storyboard, source of truth
- Puzzle design
- Classic mechanics
- Review pages
- DSL reference
- Checking your game
- What the solver proves
- Solver options
- Playtests
- Remix
- Speedrun for authors
- The sealed ending
- Production template
- Example games
- Working with an AI
- Build and release a game
- Publish on GitHub Pages
- The static game on Clever Cloud
- Other static hosts
- Sub-path, cache and service worker, incomplete deploys, going back
- Testing on a phone over the LAN
Local Studio (24)
- The local Studio: overview and launch
- Edit a room
- Placement and stage
- Preview, apply, undo
- Storyboard
- Assets and cutting
- Check: validator, solver, critical path, heat, health, coverage
- Before and after captures
- Semantic diff
- Play and replay a session
- Rule explainer
- Language and objectives
- Voices and the heroes × languages matrix
- Map
- Notes
- Remix in the Studio
- Music
- The Assistant: bring your own key
- Demo mode and studio-apply
- Local and LAN security
- Studio API
- Local MCP: setting up each client
- MCP tools
- Studio troubleshooting
Team Studio (21)
- What runs where
- Concepts: revision, transaction, span, lease, preview, build
- Starting as an invited dev
- Working together day to day
- Roles and actions: the full matrix
- Invitations
- Managing members
- Write refused on the hosted Studio: stale base revision (409)
- Write refused on the hosted Studio: span locked (423)
- Recovering after a lost lease, a disconnection or a stale preview
- Comments
- Map and semantic diff
- Publishing builds
- Remote MCP
- The game in Git
- Upgrading the engine of a hosted game
- Hosted assets
- The server's command line
- Health and metrics routes
- Trying it locally with compose.yml
- Known limits
Clever Cloud (23)
- Clever Cloud: overview, cost and prerequisites
- Apps and add-ons
- Domains and TLS
- Keycloak
- Generic OIDC and GitLab
- Configuration
- First deployment
- Backups
- RPO and RTO
- Restore the Studio on a fresh installation
- Redeploys
- Upgrading the server and checking state after a migration
- Limits of going back
- Monitoring
- Security
- Rotating keys
- Recovering admin access
- Changing domain or OIDC provider
- Worker, PostgreSQL or Cellar down
- Exporting the game and leaving the installation
- Retention
- Clever Cloud troubleshooting
- Costs and teardown
Reality Bridge and connectors (16)
- The Reality Bridge: what it is
- Quick start
- Guarantees
- Install and run the Bridge
- Backup and restore
- Several tenants
- Signals and the manifest
- The Bridge's command line
- Connectors overview
- Email connector
- Telnet connector
- SSH connector
- Open Badges connector
- The connector SDK
- Security: Biscuit and signatures
- Bridge and connector troubleshooting
Contribute (25)
- Welcome
- Developer setup
- The dev loop
- Before a pull request
- Conventions
- Writing documentation
- Architecture
- Code tour
- Import boundaries
- Which tests run when
- Mutation testing
- The coverage ratchet
- The quality baseline
- CI explained
- Field passes
- Benchmarks
- Releasing
- npm packages
- Decisions and ADRs
- Governance
- Bot pull requests
- Contributing with AI agents
- Security policy
- Code of conduct
- Licences and credits