MCP server
Let your AI coding tool read Gemmein’s docs and check your app’s
safety rules while it builds. @gemmein/mcp gives it Gemmein's guide, SDK
reference, rule and error explainers, and a live check of your app's safety rules, as
tools inside the editor. It helps your agent use
@gemmein/sdk correctly, then checks the result.
For AI apps with no terminal (ChatGPT, Claude, Lovable, Replit, Bolt, v0), the same tools and
the whole Development build are one address: the hosted
connector.
Which way to connect? A chat app, a coding tool on your computer, or the guide on its own, side by side, with what each can do and what needs your approval: Connect your AI.
Set it up
Claude Code:
claude mcp add gemmein -- npx -y @gemmein/mcp
Cursor, or any client that takes an mcpServers block:
{ "gemmein": { "command": "npx", "args": ["-y", "@gemmein/mcp"] } }
Nine tools are read-only. check_integration runs live checks against
your app. With a Development secret key it also writes in the Development environment:
it creates two test people and a probe record, deletes the record, and signs the test
people out of earlier sessions. The test people stay. Live secret keys are refused.
The hosted connector
Add Gemmein to an AI app as a connector, at one address:
https://api.gemmein.com/mcp
It speaks MCP over Streamable HTTP and signs in with OAuth. The ten tools of
@gemmein/mcp and tools_map work with no account. Building your app from the chat needs a free
Gemmein account at app.gemmein.com and one approval in
your browser. Signed in, the connector has 139 tools.
tools_map is a read-only map of those tools in eight groups (start, build,
testing in Development, the site, asking for Live changes, reading Live, customers, and keys and
billing), each tool with one line on when to use it. Give it a goal (take payments, put my site live, sign people in, store data,
run something on a schedule or event, charge credits for an action, read how the business is
doing, handle a customer message, connect a domain, test before publishing) and it returns the
matching group and the order to call its tools in. It runs no other tool and changes nothing.
Add it
- Claude (claude.ai on the web or the desktop app): Customize → Connectors → + Add → Add custom connector →
name “Gemmein”, URL: the address → Authentication: Sign in when needed → Add.
Claude connects without signing in, and the first account tool opens the sign-in and the
approval on app.gemmein.com. On Team and Enterprise, an Owner adds it in
Organization settings → Connectors, then each member connects. Claude Code:
claude mcp add --transport http gemmein https://api.gemmein.com/mcp. - ChatGPT (on a computer, at chatgpt.com): Plugins in the left sidebar → Add (top right) → Add custom MCP server → name “Gemmein”, URL: the address, OAuth → approve on app.gemmein.com. Works on every ChatGPT plan, Free included. Opening the address in a browser answers 405: it speaks MCP, not web pages.
- Lovable: Connectors → + → MCP server → a server name (Gemmein) → Server URL: the address → OAuth → Add & authorize.
- Replit: Integrations → MCP Servers → + Add MCP server → a display name and the address → Test & save.
- Bolt: the chat box’s + → Connectors → Manage connectors → Custom MCP server → a name, the address, transport HTTP, auth MCP OAuth → Connect.
- v0: the prompt form’s + → MCPs → Add MCP → custom → the address → OAuth.
- Any other client: the address, with transport “streamable HTTP”.
What one approval allows
The first time a tool needs your app, the AI app opens your browser on Gemmein’s approval page. You pick the app and press Approve, once. That approval lets the AI app build the app in Development for 30 days: collections, plans, relays, AI tools, email templates, test members and sandbox test payments, through the same checks as the command line. It never sees a secret key.
This approval is separate from the command line’s, and lasts longer: a connector’s
Development approval lasts 30 days, while the one npx gemmein login asks for lasts
7 days. Each is listed on its own on Settings → Approvals.
pullreads the app as itsgemmein/files;syncsends them back, showing the difference first (plan: trueshows it and writes nothing), up to 1 MB a call.- One at a time:
declare_collection,set_payments,put_relay,put_ai_tool,put_ai_alias,put_email_templateandrename_app. - Prove it:
test_member_add,test_mail,test_payandtest_outcome, all in Development.test_paytakes anoutcome:pays,declinedorasks_to_verify(Stripe asks the payer to verify, then it pays). Gemmein pays with Stripe’s published sandbox numbers for that outcome, so no payment details pass through the chat. prove_app: proves a chat-built app in Development as two test members (add them first withtest_member_add). Each private or direct collection keeps each person to their own records, each relay that fires on a new record runs (its email lands in the test mailbox), and each AI tool answers and spends the credits it states, one line per proof. It refuses on Live and runs at most 10 times a day for an app.app_status: the app, its public key, and what going live waits on.- Read Development:
dev_records,dev_people,dev_errorsanddev_logs, under the same customer-details setting as the Live reads. Each read is on Development’s Logs; none reaches Live. - Delete in Development, at once:
dev_delete_collection,dev_delete_relay,dev_delete_ai_toolanddev_delete_email_template(the template goes back to Gemmein’s own design). Each is on Development’s Logs, naming the connection. Live keeps its own copy: a promote never removes anything from Live, and the answer names the Live request that would. - Act on a test member, at once:
test_member_credits,test_member_suspend,test_member_unsuspendandtest_member_cancel_subscription, through the same steps as the Live actions. Only a test member of this app’s Development made withtest_member_add; anyone else is refused withnot_a_test_member. - The site:
site_draft,site_put_fileandsite_publishpublish to the private preview;site_readreads a file as it is now (up to 256 KB a call), so a change starts from the current page;site_status,site_history,site_rollback,site_rebuildandsite_downloadmanage its versions.site_testopens the draft as a customer would before it publishes, andsite_test_resultreads a run again;site_errorsreads what the published pages hit.site_share_linkanswers the preview’s link, on its own address (https://<slug>-dev.gemmein.dev/p/<code>);site_unpublishtakes the preview offline (every version and file is kept) andsite_revoke_previewsturns the preview link off. Both work on Development only; see Your site. - Domains:
domain_checksays what public DNS shows, what Gemmein needs and the one record to change;domain_connect_linkgives you your DNS provider's own guide and the exact steps. Both only read; see Is your domain working? - Live reads (with the Live-read approval):
live_overview,live_people,live_revenue,live_subscriptions,live_records,live_errors,live_logs,live_usage,live_webhooks,live_emailsandlive_inbox.refund_stepsreads one Live payment and answers your exact steps in Stripe for refunding it; refunds are made in Stripe, never from a chat. - Reply to a customer:
inbox_replydrafts the reply; you approve the exact text in your browser before it is sent. - Relays:
relay_runslists a relay’s runs andreplay_relayruns one again. - Your steps:
connect_payments,provider_keyandrequest_server_keyhand you a page of Gemmein’s own, where you paste the key for Stripe, an AI provider or a server key; your AI never sees the key. - Pay for the plan before going live:
buy_planhands you Gemmein’s payment page for the app. You pay in Stripe’s window; the tool pays nothing itself. The app then owns the plan and billing starts. The app stays in Development until you approve going live, which then has no payment step. Details: Usage & billing. - Ask to put a version live:
site_promote, approved like any Live change. - Customers’ follows and circles:
people_graphreads who follows whom, follow requests and circles.remove_from_circle,close_circleandremove_followmoderate them: at once in Development, and on Live as a request you approve.
Reading Live needs its own approval. It is a separate line on the approval page. It changes nothing, and every read is on your Logs. What the AI app reads (your customers’ emails, records and revenue among it) goes to that AI app and its provider, so allow it only for an AI app you trust with that data.
Live changes are approved one at a time. Each Live change has its own tool, with only its
own fields, and asks you to approve that one change in your browser: request_go_live,
request_promote, request_rename_app, request_add_domain,
request_delete_domain, request_accept_terms,
request_revoke_server_key, request_unpublish_site,
request_delete_collection, request_delete_relay,
request_delete_ai_tool, request_grant_credits,
request_suspend_person, request_delete_person and
request_cancel_subscription. A change to one customer (credits, a suspension, a
cancellation, a reply) is approved as it is. Going live is your approval, then paying for the plan
in Stripe’s window, with no code; when buy_plan has already paid for the plan, going
live has no payment step. A change to how the business runs (a
promote, a rename, a domain, deleting Live’s copy of a collection, relay or AI tool,
putting a version live, taking the live site offline) also asks for the code Gemmein emails,
and your authenticator code if you set one up; the whole list is on
Connect your AI.
Your Approve carries the change out, once. live_action_status only reads where it
stands, and with wait: true it answers as soon as the change is done, failed, refused or
expired. A secret key, Stripe’s key and an AI
provider’s key are pasted on a page of Gemmein’s own, and DNS records are handed over
with a link, never in the chat. Paying is your press in Stripe’s window.
The connection is listed on Settings → Approvals as “Connector · builds <app> in
Development”. Revoke it there and it stops at once; disconnecting in the AI app ends it too.
Each step is on Logs. npx gemmein dev serves the same /mcp on your
computer, at http://127.0.0.1:4545/mcp, with no sign-in.
| If… | What happens | What you do |
|---|---|---|
| A tool that needs the app is called before sign-in | The AI app gets HTTP 401 with a sign-in pointer and opens the approval page; after Approve it repeats the call | Approve, if you asked for it |
| A Live-reading tool is called on a connection without Live reads | HTTP 403 with insufficient_scope; the AI app asks you to approve it | Approve only for an AI app you trust with Live data |
| You press Deny, or wait past 10 minutes | The AI app is told access_denied; nothing is handed out | Connect again to ask again |
| The connection was revoked or its 30 days ended | Calls answer HTTP 401 with invalid_token, and the AI app asks you to sign in again | Approve again |
A file in sync breaks a rule | That file is refused with the fix; the others apply | Fix the file and send it again |
A sync is more than 1 MB | HTTP 413 with too_large | Send the files in more than one call |
| Something is deleted in Development after the app went live | Development’s copy goes at once; Live’s stays, and the next promote doesn’t remove it | To remove Live’s copy, approve request_delete_relay, request_delete_ai_tool or request_delete_collection; a Live collection holding records is deleted only on the dashboard |
| Live has no relay or AI tool by the name asked to delete | relay_not_found or ai_tool_not_found; nothing is asked of you | Check the name on Live’s Relays or AI page |
| A test-member tool names a real person, or someone in Live | not_a_test_member; nothing is done | Use a test member added with test_member_add; Live’s customers are changed through the request_* tools |
site_unpublish is asked for the live site | development_only; nothing is sent | Taking the live site offline is request_unpublish_site, with your approval |
buy_plan is called while the account’s last payment has not gone through | billing_past_due (402): “Your last payment didn’t go through. Update your card in Stripe, then go live.” No payment page is made | Update the card or pay the open invoice in Stripe’s billing page (Settings → Usage & billing), then go live |
| A tool can’t finish | connector_error; whatever was applied before it stopped stands | Call pull, check the input against the guide (search_docs), and try again |
What your agent gets
- guide: the full builder's guide, covering the auth flow, the eight safety rules, record shapes, links, uploads, contention and payments.
- reference: every SDK method, with its signature, return shape and error codes.
- search_docs: targeted search over both, when the agent needs one fact.
- changes: what changed in each Gemmein release after the version the agent
knew (
since, such as0.22.1), or the last three: each change as it was and as it is now, with the error codes it added or removed. It is bundled with the server and works offline; every release in full is at docs.gemmein.com/changes.txt. Your agent calls it when what it remembers may be older than the installed release. - explain_rule: what a safety rule allows, what it suits and the mistakes to avoid, or a summary of all eight for planning.
- explain_error: what a
GemmeinErrorcode means and what to do about it. - validate_collection_name: catches a misnamed collection before every read starts returning empty results.
- explain_relay: give it a
gemmein/relays/<name>.jsondefinition and it returns the sentence the dashboard would show, or the one error that names the bad field. It works offline for all thirteen actions:write_record,grant_access,revoke_access,grant_credits,email_person,call_url,fulfil_product,refund_product,grant_plan,revoke_plan,start_run,spend_creditsandrun_function. - reaffirm_template: the CI test script, ready to copy.
- check_integration: runs your isolation and access checks live against your own app and returns structured pass/fail. Details below.
check_integration
check_integration runs the same checks as the
CI test script, from inside your agent while it builds. It checks
that anonymous access is refused where it must be and that collection names are valid.
With your Development secret key, it also checks isolation between two test people,
signed in with fresh test sessions. The result comes back as structured pass/fail, so the agent fixes
what it finds before the app goes live.
It catches the bug that passes with one person and breaks with two: everyone ends up on the same record, which a single-person test never shows. Apps talk to Gemmein in JSON through an API that enforces the safety rules. The API takes named calls only, with no query language, enumerable schema or raw data layer, so attacks that start by mapping the database have nothing to work with. The safety rules are the part to test, and this checks them.
On the hosted connector, check_integration takes the app’s public pk_
key and no secret key. The isolation check between two people is prove_app, run as the app’s
test members, so no key passes through a chat. The secret-key check below belongs to the local
server (npx @gemmein/mcp).
Pass your pk_ app key to run the anonymous checks. The
isolation check between two people also needs an sk_dev key: the
Development-only secret key you create in your dashboard. An sk_dev key works
only against a Development environment: it reaches no real people's data, runs behind the
same rules and rate limits as everything else, and the server refuses it on a Live
environment. Keep it in server environment variables like any secret.
sk_live keys are refused for test sessions.
What happens if…
| If… | What happens | What you do |
|---|---|---|
check_integration gets a key that is not a pk_ app key | It refuses at once and sends nothing over the network | Pass the app's pk_ key |
| It gets only the app key | The anonymous checks run; the isolation check between two people is skipped, and the result says how to run it | Add an sk_dev key for the full check |
| A collection lets anonymous people read what its rule should keep private | The check fails and names the collection | Fix the collection's rule, then run it again |
A collection name is invalid, such as savedGames | The check fails at that name; validate_collection_name suggests the valid one (saved_games) | Rename the collection |
| The API cannot be reached | The tool answers with an error instead of waiting | Check the network, then run it again |
| The isolation check finishes | Its probe record is deleted; the two test people stay in Development | Nothing |
explain_error gets a code that is not a stable Gemmein code | It answers with an error saying so | Call it with no code to list the stable ones |
explain_relay gets a definition with a bad field | It answers the one error that names that field, offline | Fix the field it names |
Thanks for telling us.
Thanks for telling us.
Last updated