One URL for Claude Desktop, Claude Code, claude.ai or any MCP client. Your browser opens, you approve, and it can build everything a workspace has.
https://app.simplebackend.dev/mcp
There is no API key to create, copy or paste. That URL is the whole of it, because the client asks the server what it needs.
Claude Code, from the directory you work in.
claude mcp add --transport http \ simple-backend \ https://app.simplebackend.dev/mcp
Or claude.ai. Both take the same URL as a custom connector, with nothing to install.
| 1 | Settings → Connectors |
| 2 | Add custom connector |
| 3 | Paste the URL above |
Either way, your browser opens. Not on a form asking you for a token — on this platform's own sign-in, and then on a consent page naming the workspaces the credential would cover. You approve it there, on a page you can read, and the client is handed something scoped to exactly that.
Each one is a thin call into a path the console and the CLI already take, so nothing here is a second implementation that could disagree with them.
| Group | Tools |
|---|---|
| Docs | read_docs is the manual, served by the server itself, so a model connected to nothing else still finds it; get_skill hands back the Skill and where to save it |
| Account | list_workspaces create_workspace list_keys |
| Team | list_members invite_member remove_member — by email; the owner invites |
| Functions | get_source list_functions add_function remove_function deploy releases rollback |
| Running it | test_function runs a candidate in the real sandbox and stores nothing; call_function calls what is live, with no key in the conversation |
| Settings | settings set_var set_secret remove_setting; outbound_calls restrict_outbound for where functions may call |
| Sign-in | sign_in configure_sign_in — off until switched on; list_users disable_user delete_user |
| Pages | list_pages publish_page unpublish_page |
| Preview | preview promote_preview discard_preview rotate_preview — a release and pages staged together at a private address, then made live together; preview: true on the tools that change things stages instead |
| Data | list_kinds describe_kind find_records index_field declare_field forget_field set_strict |
| Watching it | read_log is the last runs; usage is how many and how slow, per function; cache_usage and list_files are what the workspace is holding against its quotas |
| Feedback | send_feedback sends a feature request or a bug report to the team, when you agree to it |
The data tools read your records. describe_kind reports what is stored under each field without returning a value; find_records returns the records themselves. Grant read-only, or a single workspace, on the consent page if that is not what you want a chat to reach. read_log returns the run log — function names, releases, timings, whether each run succeeded, the caller (an IP, or an API key’s label, never a key) and the error text, which is whatever your function put there. If your errors quote customer data back, the log carries it and so does anything you connect to the log.
The workspaces your account owns or is a member of, and nothing else. Every tool checks the workspace argument against that list before it touches anything — the check is not on the model's good behaviour.
| Property | How it works |
|---|---|
| Access token | Signed, one hour, and bound to this host as its audience — a token minted for another server fails here exactly like a forgery |
| Refresh | Rotates on every use, stored only as a hash. Replaying a rotated token revokes the whole chain |
| Expiry | Thirty days idle, ninety days absolute, both enforced as refusals |
| Redirects | An allowlist in code, matched on scheme, host, port and path prefix. A look-alike host is rejected, and the rejection is recorded |
| Revoking | Access is re-checked when the credential refreshes, so removing an account’s access to a workspace stops the credential reaching it within the hour. [a screen for revoking one credential on its own is not built yet] |
The tools are discoverable; the two rules that are not are how deploy wants a whole release, and that rollback wants the full hash. This is that, in markdown.
Paste into a CLAUDE.md, or hand it over in chat. Click in the box, select all, copy.
For writing the functions themselves rather than operating a workspace, take the Skill instead.
Anything that speaks MCP over streamable HTTP and can register itself. Claude Code and Claude.ai are what we use daily; ChatGPT, Cursor, VS Code and Perplexity are in the redirect allowlist and should work.
A client we have not listed cannot connect until its callback is added — a deliberate trade. In a flow with no client secret, the redirect is the only thing standing between an authorization code and whoever asked for it, so it fails closed.
Once connected, ask in plain language:
> which workspaces do I have? > deploy this manifest to acme > why did the last five runs fail? > roll acme back to the release before this one
The console writes a manifest for you. If you would rather write it yourself, it is a file called swarm.edn beside your source, and it is what the CLI and Claude both deploy.
{:backend/version 1
:tenant "acme"
:functions
[{:name :contact/submit
:file "fns/contact.clj"
:entry contact/submit
:trigger {:type :http :method :post :path "/contact"}
:allow :public
:needs #{:db/write}}
{:name :report/nightly
:file "fns/report.clj"
:entry report/run
:trigger {:type :cron :schedule "0 3 * * *"}
:needs #{:db/read :http/out}
:limits {:timeout-ms 30000 :isolation :process}}]}Each key is a control from the Settings tab: :allow is who may call it, :needs is the checkboxes, :limits is the time limit and whether the function is isolated. The nightly function has no :allow because it has no URL — it is required on an HTTP trigger and never defaulted, since the value a forgetful default would pick is either an endpoint nobody decided to expose or a function that is deployed and unreachable.
One value exists in the file that the console does not offer: :allow :signed-in, for your own signed-in end users. It refuses every call. End-user authentication is not built, and the gateway refuses rather than guessing — the console leaves it out entirely so nobody picks it by accident.
sb test # run the candidate ON THE PLATFORM, in the real sandbox sb deploy # validate, store, activate sb rollback # the release before this one
sb test is the reason it exists: it is the Run panel without the browser. A function that passes on your laptop has been tested in a different language, so it sends the candidate to the workspace and runs it there. It writes to the real database, so point pipelines at a staging workspace.
The MCP manages workspaces you already have. Make the first one in the console — that part takes a browser exactly once.