MCP for agents

Sitebin speaks the Model Context Protocol, so Claude, ChatGPT and any other MCP client can publish a website and manage it afterwards — without you pasting files anywhere. It is the same API, the same permissions and the same quotas, reached over the protocol those clients already speak.

MCP is not a separate permission system. An agent can do exactly what a script holding the same credential can do: on app.sitebin.io that means an account — reached by signing in from the client or with an API token — and a site created anonymously (a Drop) stays outside it, just as it stays outside the API. Self-hosted community instances have no accounts, so the endpoint is open there.

Connect

The endpoint is https://app.sitebin.io/mcp, streamable HTTP. There are two ways to tell it which account the agent is publishing for, and every client supports at least one of them — plus a site's own edit password, which works without any account at all.

Sign in from the client (OAuth)

A client that implements MCP authorization — Claude, ChatGPT's connectors, and most others that can add a remote server — needs only the URL. The first time the agent does something that needs your account, the client registers itself with our authorization server and opens a browser window where you sign in to your Sitebin account, accept the terms if you have not yet, and approve what the agent may do. It then holds an access token bound to this server. No token to create, nothing to paste — and no account needed beforehand: the first sign-in creates it.

claude mcp add --transport http sitebin https://app.sitebin.io/mcp

With an API token

Scripts, CI, and clients that only know how to send a header use an account API token instead. Create one in the dashboard at /account, then pass it as a bearer token:

claude mcp add --transport http sitebin \
  https://app.sitebin.io/mcp \
  --header "Authorization: Bearer $TOKEN"

Clients that only speak stdio, or that cannot set a header, can bridge through mcp-remote, which also handles the OAuth sign-in if you leave the header off:

npx mcp-remote https://app.sitebin.io/mcp \
  --header "Authorization: Bearer $TOKEN"

What the agent can do

ToolWhat it does
create_sitePublish files as a new site. Returns the public URL, the edit id, and — once — the edit password.
list_sitesThe sites your account owns, with their names and custom domains. Needs your account — a sign-in or an API token.
get_siteName, settings, usage and the file list.
update_siteName, mode, entry file, view password, expiry, WebDAV/FTP, SPA fallback, browser caching (cache: auto, revalidate, hour, day, week, year, off). The name is a private label for your site list; an empty string removes it.
list_filesThe site's files with their sizes.
read_fileOne file's contents.
write_filesAdd or overwrite files. With replace, the site ends up holding exactly what was passed.
delete_fileRemove one file.
delete_siteRemove the site and everything in it.
add_domainAttach a custom domain. The domain is attached once its DNS proves it belongs to the site; until then the result lists it under pending_domains with the TXT record (or CNAME) to create, and its warnings say what the check found. The agent creates the record and calls add_domain again, or waits — the instance re-checks pending domains itself. On a container site, target names the HTTP port the domain serves (app:3000). Enterprise.
remove_domainDetach a custom domain, or withdraw a pending claim.
set_domain_redirectMake a custom domain redirect to another of the site's custom domains — example.de to example.at — with 301 (default), 302, 307 or 308, keeping the path. An empty to serves the site again. Enterprise.
set_view_addressSwitch the site's generated address off, or redirect it to one of its custom domains — or back to serve. Needs a custom domain that serves the site. A container site has one generated address per HTTP port; endpoint picks which. Enterprise.
set_domain_targetPoint a container site's custom domain at another of its HTTP ports — without touching the compose file, so the app does not restart. Enterprise.
download_siteThe whole site as a zip.
open_uploadA short-lived token and URLs for files too large to pass as arguments. The agent uploads with its own HTTP client — a zip for a whole site, or single files, or over WebDAV — using the curl commands in the result. The token opens nothing else and expires five minutes after its last use, and an hour after it was opened at the latest.
list_formsThe site's email forms, each with its status and the HTML snippet to paste. Every submission arrives as a plain-text email with the visitor's files and submission.json attached.
add_formAdd a form. Its recipient confirms by email first; until then the form is pending and refuses submissions. Submissions arrive as plain-text emails, not designed ones; the agent is told to have the user add the sender to their safe senders. Needs form mail on the instance; Pro and Studio on the hosted service.
update_formChange a form's name, recipient, captcha, attachments or thank-you page. A new recipient confirms again.
remove_formDelete a form.
resend_form_confirmationEmail the recipient the confirmation link again.

How it behaves

Signed in or with a token, every site the agent creates belongs to your account and gets your plan's quotas and lifetime. list_sites shows them, and the credential replaces the edit password on all of them — so the agent never has to hold a per-site secret, and never has to ask you for one.

Without either, an agent passes a site's edit_password with every call, and that keeps working whether or not the client can sign in. On app.sitebin.io it cannot create sites that way: anonymous publishing belongs on the drop page, in front of a person. A call that needs an account — create_site, list_sites, or a site tool without its password — is answered with a sign-in request, which a client that supports OAuth turns into the browser window above.

Files travel as JSON — {"path": "index.html", "text": "…"}, or base64 for images. One call carries up to 8 MiB, but a model writes every byte of an argument out itself, so for anything beyond a few hundred KB the agent calls open_upload and uploads with curl instead — if it can make HTTP requests of its own. Every site an agent creates or changes is recorded as coming through MCP, with the account and the client's address, which is how abuse gets traced if it ever happens.

Locked sites. A site the operator has locked — held as evidence of abuse — is not served and cannot be changed. get_site and list_sites still answer for it, with a locked object (at, and reason when the operator gave one) and no files; every other tool refuses it with "This site is locked by the operator". The field appears only on a locked site, so every other result is exactly what it was. An account the operator has suspended is refused on every call. A write whose files match a known phishing or scam kit on an anonymous or Free site locks that site on the spot, and the tool answers with the same sentence: "held for review".

A site is public. Anyone with the URL can read it, and an agent publishing on your behalf is publishing to the open web. Don't hand one credentials, private documents or personal data to put online, and remember that a page an agent wrote is a page you are hosting under your account.

Authentication

/mcp accepts three kinds of credential side by side, so none of them ever breaks a script or agent using another:

  • a site's edit password, passed as edit_password to each call on that site;
  • an account API token in an Authorization header — the same token the API takes. It carries no scopes and grants everything its account can do;
  • an OAuth 2.1 access token issued by our authorization server after you signed in and consented. It is valid for /mcp only — the JSON API takes API tokens, not OAuth tokens.

A client may connect without any of them and list the tools. Only a call that needs an account is answered 401 with a challenge naming the metadata and the scopes, which is what starts a sign-in; a call that needs a permission the token was not granted is answered 403 with insufficient_scope, which a client turns into a request for that permission.

How the OAuth connection works

On app.sitebin.io the MCP server is an OAuth 2.1 protected resource and the IT-Trail SaaS Stack that also runs Sitebin's sign-in is its authorization server. The pieces a client relies on:

  • Discovery. A call that needs an account is answered with a WWW-Authenticate challenge pointing at /.well-known/oauth-protected-resource/mcp, which names the authorization server, the resource identifier (https://app.sitebin.io/mcp) and the scopes.
  • Dynamic client registration. The client registers itself with the authorization server (RFC 7591) — no pre-shared client id, which is what lets a connector you have never told us about connect. Registered clients are capped and rate-limited, may only ask for Sitebin's scopes and the standard sign-in ones, may only send you back to your own machine or to a known connector host (Claude, ChatGPT, VS Code), must use PKCE S256, and always ask for your consent.
  • Sign-in, terms and consent. You sign in to the same account you use at app.sitebin.io. If you have not accepted the current platform terms, Sitebin's terms and the data processing agreement, you are shown them first — the same page a sign-in in the browser shows, and a token is never issued past it. Then a consent screen names the client and the scopes it asks for.
  • Scoped, audience-bound tokens. sitebin:sites:read covers list_sites, get_site, list_files, read_file, download_site and list_forms; sitebin:sites:write covers the rest, including add_form, update_form, remove_form and resend_form_confirmation. A token is accepted only when it is an access token whose signature, issuer and expiry check out, whose audience contains this server's resource identifier — so a token minted for another app on the same authorization server is refused — and whose holder has accepted the current terms. Sitebin asks the authorization server about the terms itself, so a client that skipped the sign-in page gets nothing. A first valid token creates your Sitebin account, exactly as a first sign-in in the browser does.
  • Revocation. The Applications page of your account console lists every client you have authorised and lets you revoke it; the client's own settings do the same from its side.
  • Unused registrations expire. A client that was registered and never signed in is removed after three days; one that nobody has used for 90 days is removed too. If a connector you have not used in months stops connecting — an invalid_client error, or a sign-in that never comes back — remove it in your client and add it again; it registers afresh on the spot.

Sitebin itself is a resource server and never an authorization server: it issues no tokens, registers no clients and shows no consent screen. A self-hosted instance gets the same behaviour by pointing SITEBIN_MCP_OAUTH_ISSUER (and optionally SITEBIN_MCP_OAUTH_RESOURCE) at its own sign-in issuer — the two must be the same — when that authorization server offers dynamic client registration, PKCE and audience-bound tokens. The SaaS Stack does so from an mcp block at app onboarding; other compliant issuers work the same way. With the issuer unset, none of this is mounted, and API tokens and edit passwords are the credentials.

Read the consent screen. A dynamically registered client chooses its own display name, and nothing stops one from calling itself something reassuring. Approve an authorization only when you started it yourself, from a client you trust, and grant the read scope alone when the agent does not need to publish.

Connector directories

The OAuth flow above — a protected resource with discovery, dynamic client registration, PKCE and consent — is the one the connector catalogues at Anthropic and OpenAI require of a remote MCP server, and app.sitebin.io supports it. Whether Sitebin appears in those catalogues is up to their operators and their review; until it does, add it as a custom connector by URL, which is the same flow with one more field to fill in.

Rate limits

The same ones the API has: site creation is limited per IP, and password attempts per IP and per site. An agent gets no more room than curl does.