Connect an AI agent over MCP
Add Demofy to Claude or ChatGPT with a sign-in, or give Claude Code, Codex or any MCP client an API key, and confirm each call that cannot be undone.
Demofy runs an MCP server, so an AI app such as Claude, ChatGPT, Claude Code or Codex can make and manage demos for you in the middle of a conversation. It is the API behind a different door: the same account, the same allowances, and nothing the composer cannot do.
What an agent can do
Make a demo from a URL and a sentence of intent, check on it while it renders, read its script,
answer a sign-in pause, rename it and cancel it. It can also propose an edit, ship it, re-render a
demo, shoot it again against the live app, and delete it. It can list your saved logins and the
voices a demo may narrate with, so it names them rather than guessing. Ask your agent to call
search_tools and it will list exactly what it can reach.
Two ways in, one account
The server answers at https://app.demofy.io/api/mcp over Streamable HTTP. There are two ways to
sign an AI app in, and both end up as you, in one workspace, with the same reach:
- Sign in with a button. Claude, ChatGPT and any other app that can add a custom connector need only the address above. The app sends you to Demofy, you sign in the way you always do (Google, Apple or email) and press Allow. No key is made, copied or pasted.
- An API key. For a command-line agent such as Claude Code or Codex, and for a script. Signed in,
open Settings → API keys, create a key, and give it to your agent as
Authorization: Bearer <key>. It is the same key the API takes.
Either way, a demo the agent makes counts against your allowance exactly like one made at the composer. Keep an API key in an environment variable rather than in a config file you might commit, as both command-line examples below do.
Claude and ChatGPT
In the app's connector settings, add a custom connector, name it Demofy and give it
https://app.demofy.io/api/mcp. When the app asks you to connect, a Demofy page opens in your browser.
If you are not signed in it asks you to sign in first, then comes back.
The page names the app, says where it will send you back to, names the workspace it would act in and lists what it could do, in plain words, with Allow and Deny. Demofy names an app itself only when it can tell who it is from where the app sends you back; any other app is shown under the name it gave itself, marked as not checked by Demofy. Read that line before you press Allow.
Approving gives the app the same reach an API key has: your demos, your saved logins by name, the voices and your media library. It does not reach your account, your plan or your keys. It acts in the one workspace the page named; to use it in another, switch to that workspace and approve it again.
Disconnect an app
Settings → Connected apps lists every app you have approved, with the workspace it acts in. Disconnect one and its very next request is refused; to come back it has to ask you again. Revoking an API key in Settings → API keys does the same for that key.
Claude Code
Set the key in your shell as DEMOFY_API_KEY, then, in your project:
claude mcp add --transport http --scope project demofy https://app.demofy.io/api/mcp --header 'Authorization: Bearer ${DEMOFY_API_KEY}'
That writes a .mcp.json at the project root which holds the variable's name, never the key:
{
"mcpServers": {
"demofy": {
"type": "http",
"url": "https://app.demofy.io/api/mcp",
"headers": { "Authorization": "Bearer ${DEMOFY_API_KEY}" }
}
}
}
Codex
Set the key in your shell as DEMOFY_API_KEY, then:
codex mcp add demofy --url https://app.demofy.io/api/mcp --bearer-token-env-var DEMOFY_API_KEY
Codex stores the variable's name, never the key, and asks for your approval before it runs
execute_typescript, since a program can change something.
Any other client
Point it at the URL above as a Streamable HTTP (remote) MCP server. A client that can sign in on its own
needs nothing else; one that cannot should send a key as Authorization: Bearer <key>. Most clients can
read the key from an environment variable; check your client's own MCP documentation for its spelling.
For people building a client
A request with no credential is answered 401 with a WWW-Authenticate: Bearer challenge whose
resource_metadata points at
https://app.demofy.io/.well-known/oauth-protected-resource/api/mcp, and so is a key or a token that is
wrong, expired or revoked. That document names the authorization server, which publishes its own
metadata at https://app.demofy.io/.well-known/oauth-authorization-server. Sign-in is OAuth 2.1:
authorization code with PKCE (S256), refresh tokens that rotate, and token revocation.
A client can register itself, either by dynamic client registration or by giving a client ID metadata
document, and may be a public client with no secret. Ask for the resource https://app.demofy.io/api/mcp:
an access token is good for that address alone, and the server refuses a token made for any other. Ask
for offline_access to be given a refresh token. A token whose scopes open no tool is answered 403
with error="insufficient_scope" and the scopes to ask for.
Two tools by default
By default the server offers an agent two tools: search_tools, which describes what it can reach as
TypeScript functions, and execute_typescript, which runs a short program that calls them. An agent
can then make a demo and check on it in one step rather than one round trip per call. A client that
wants every tool listed by name can use https://app.demofy.io/api/mcp?tools=all instead. That form is for an
API key: an app that signs you in with OAuth (Claude, ChatGPT) must be given the plain
https://app.demofy.io/api/mcp, because the sign-in is made for exactly that address and a client refuses a
server whose address does not match.
Calls that cannot be undone
Shipping an edit, re-rendering, shooting a demo again and deleting one spend a demo or lose work, so
none of them runs on the first call. The first call is refused with CONFIRMATION_REQUIRED and a
confirmToken; the agent shows you what it is about to do, and calls again with the same arguments
and the token once you agree. A token is good for one call with those exact arguments, and only for
a few minutes.
Every call an agent makes is recorded against the key or the connected app it came through. Disconnect the app, or revoke the key, and the next call is refused.