MCP
Every project exposes a management MCP endpoint at https://shovelbase.com/api/mcp/<ref>. Point an AI client at it — Claude Code, Claude Desktop, Cursor, anything that speaks the Model Context Protocol — and it can operate the project the way you do in the portal: run SQL and migrations, deploy functions, set secrets, flip feature flags, create buckets and queues, publish websites, configure auth, read logs and analytics.
Don't confuse it with the MCP endpoints you write — functions deployed with --mcp that expose your app's tools to AI clients, served on the project host at /mcp/v1/<name>. Those are your product's data plane. This page is the control plane: the endpoint that configures the project itself, and it ships with shovelbase rather than being something you build.
An agent writing your app already needs a backend behind it — a table and the policies that guard it, a bucket, a function holding an API key, a flag to ramp the feature it just built. Without a control plane it can only write code and then hand you a list of things to go and click, which is where the loop breaks: it can't see whether the migration applied, so it guesses, and you become the integration layer between an agent and a dashboard.
The useful part isn't automating the clicking. It's that the agent can observe what it did — read back the schema it changed, tail the logs of the function it deployed, check the flag it flipped, query the rows it inserted. That closes the write-then-verify loop that separates an assistant that suggests changes from one that can actually finish a task and know it worked.
The trade-off is that a token here is real access. sql_query runs arbitrary SQL as the project owner, and bucket_delete means it. The token is scoped to one project and revocable in a click, but treat it as production credentials: give an agent its own project to work in when the work is exploratory, and keep the token for a project with real user data as deliberate a decision as handing someone the portal password.
- Building the backend alongside the app
- The agent writing your checkout page creates the
orderstable, writes the RLS policies, deploys the function that talks to Stripe and puts the key in Secrets — in the same pass as the client code, instead of leaving you a SQL snippet to paste. - Debugging what it just shipped
- Deploy a function, call it, read its logs, fix the bug, redeploy. Every step is a tool, so the agent iterates on real output rather than asking you what the error said.
- Answering questions about the running system
- “Which buckets are public?” “What redirect URLs does auth accept?” “How many signups this week, and from where?” — schema, configuration and Signals are all readable, so the answer comes from the project instead of from memory.
- Routine operations you'd rather describe than perform
- Ramping a flag from 10% to 50%, rotating a secret, taking a backup before a risky migration, republishing a site and flushing its CDN.
Connecting a client
Open the project's Settings → API tab and create an MCP access token. The value — it starts with sb_mcp_ — is shown once, along with a ready-made connect snippet; only its hash is stored, so a lost token is rotated, never recovered.
claude mcp add --transport http shovelbase-<ref> \ https://shovelbase.com/api/mcp/<ref> \ --header "Authorization: Bearer sb_mcp_..."Any other MCP client wants the same two facts — the URL and the header. The transport is Streamable HTTP, stateless: the client POSTs a JSON-RPC message and gets one JSON response back, with no session to keep alive.
{ "mcpServers": { "shovelbase-<ref>": { "type": "http", "url": "https://shovelbase.com/api/mcp/<ref>", "headers": { "Authorization": "Bearer sb_mcp_..." } } }}Note the host: the management endpoint lives on shovelbase.com, not on your project host. <ref>.shovelbase.com/mcp/v1/… is where your own MCP functions serve.
Tokens
A token belongs to one project and one client — name them after the client (“Claude Code on my laptop”) so the list stays meaningful. The table on Settings → API shows each token's prefix, when it was created, and when it was last used, which is how you tell a live integration from one you set up months ago and forgot.
| Action | What happens |
|---|---|
| Rotate | Issues a new secret for the same token — the name and its place in the list stay put, so the client only needs its header updated. The old value stops working immediately, which makes this the fix for a leaked or lost token. |
| Revoke | Deletes the token. The next call from anything holding it gets a 401. Use it when a client, a laptop, or a person goes away. |
A token acts as the account that created it and inherits that account's standing — suspend the account and its tokens are held back exactly as the portal holds back the person. If that account is later removed from the organization, the owner takes over, so someone leaving doesn't silently break every agent wired to the project. Tokens are created, rotated and revoked in the portal only: a client holding one can't mint itself another.
What it can do
Every tool maps to the same operation the portal screen performs, so anything you can do on a project's pages an agent can do through the endpoint. Call tools/list for the current catalogue with full argument schemas; broadly:
| Area | Tools |
|---|---|
| Database | sql_query, tables_list, migrations_list, migration_apply, table_import_csv, backups_list, backup_create, backup_restore |
| Functions | functions_list, function_get, function_deploy, function_delete, schedule_create, schedule_run, secrets_list, secrets_set, secrets_unset |
| Feature flags | flags_list, flag_create, flag_update, flag_delete |
| Queues | queues_list, queue_create, queue_send, trigger_create, webhook_create, and their list/delete counterparts |
| Storage | buckets_list, bucket_create, bucket_update, objects_list, object_upload, object_delete, object_sign_url |
| Websites & domains | sites_list, site_upload_file, site_set_primary, site_invalidate_cache, domain_connect, domain_record_upsert, distribution_create |
| Auth | auth_config_get, auth_config_update, auth_provider_update, auth_provider_delete, auth_apple_secret_generate, auth_users_list, auth_user_send_email, auth_emails_update |
| Signals & logs | signals_overview, signals_events, signals_users, logs_read, metrics_read, services_status, services_restart |
Tools are annotated as read-only or destructive, so a client can show you a confirmation prompt for backup_restore and not for flags_list. Failures come back as the portal's own error message — a limit hit, a bad cron expression, SQL that wouldn't run — so the agent can correct itself rather than reporting a dead end.
The docs come with it
Knowing the arguments to flag_create isn't the same as knowing how flags are meant to be used, so the endpoint serves these docs too. Every page you're reading here is available through the same connection, in markdown:
| Tool | What it gives the model |
|---|---|
docs_index | The table of contents, grouped as this sidebar is — every page with its summary, its sections, and the tools that page explains. |
docs_read | A page, or a single section of a long one, so a client spends context on the part that answers its question. |
docs_search | The pages and sections that discuss a term, with a snippet of each — for when you know the concept but not the page. |
sdk_versions | The currently published CLI and SDK versions with the exact install command for each, read live from the release pointers. |
Because packages are served from version-pinned URLs rather than a registry, the install lines inside the pages are resolved the same way — an agent reading the quick start over MCP is told to install the version that's current today, not the one that was current when these docs were published.
Pages are also exposed as MCP resources at shovelbase://docs/<slug>, so clients that surface resources let you @-mention a page directly in a conversation.
The link runs both ways, which is the point: each tool's description names the page that explains it, and each page lists the tools that operate it. An agent about to call flag_create can read the rollout semantics first and discover that percentage membership is sticky per user — the kind of design detail that decides whether a feature ramp behaves properly or takes the feature away from people who already had it.
docs_search("row level security") # → permissions, database, sdk-jsdocs_read("permissions") # the page, plus the tools it coversdocs_read("functions", "secrets") # just that sectionWhat a token can't do
The endpoint is deliberately narrower than a portal login. A token authorizes one project and nothing around it:
- No other project. The project comes from the token, not from a tool argument, so there is no parameter to point at a sibling — pointing a token at another project's endpoint URL is refused outright.
- No org-level changes. Renaming the organization, inviting or removing members, deleting the project, and managing sources all stay in the portal, even when the token's account is the owner.
- No self-issued credentials. A client can't create, rotate or revoke MCP tokens — including its own.
MCP, the CLI, and the Management API
These are three doors into the same control plane, and they stay in step because they run the same code underneath — a capability added to the portal shows up in all of them. Choose by who's driving:
| Surface | For | Credential |
|---|---|---|
| CLI | You, in a terminal — and CI | Login token from shovelbase user login |
| Management API | Scripts and your own tooling | The same token, as a bearer |
| MCP endpoint | AI clients | A project MCP token (sb_mcp_…) |
| Surface | Availability |
|---|---|
| Portal UI | Settings → API: create, rotate and revoke tokens, and see when each was last used |
| CLI | None — tokens are portal-only; for terminal work the CLI already covers the same operations |
| SDK / HTTP | The endpoint itself: JSON-RPC 2.0 over Streamable HTTP (POST), bearer-authenticated |