Serveur MCP distant managé pour vos agents IA
Zerolith expose un serveur MCP (Model Context Protocol) distant et managé. Branchez Claude Code, Cursor, VS Code ou n'importe quel client compatible : votre agent écrit, déploie, invoque et administre vos fonctions serverless hébergées en France. Vous n'avez ni serveur MCP à héberger, ni clé API à lui confier.
Ce que c'est
Le Model Context Protocol est le standard par lequel un assistant découvre et appelle des outils externes. Un serveur MCP distant (remote) est joignable en HTTP : rien à installer, rien à faire tourner sur votre poste, et la même connexion fonctionne depuis n'importe quelle machine où vous êtes authentifié.
Le serveur MCP de Zerolith tourne sur exactement le même code que l'API REST et l'interface web. Il n'existe pas de chemin privilégié réservé aux agents, donc un outil MCP ne peut jamais faire ce que votre compte ne peut pas faire lui-même.
https://zerolith.io/mcp
Document de découverte OAuth (RFC 9728) : https://zerolith.io/.well-known/oauth-protected-resource
Connecter un client
Le transport est HTTP. Pointez votre client sur l'URL ci-dessus : l'autorisation OAuth 2.1 se déclenche à la première connexion, dans votre navigateur.
Claude Code
Une seule commande. Le navigateur s'ouvre pour l'autorisation, puis les outils apparaissent dans la session.
claude mcp add --transport http zerolith https://zerolith.io/mcp
Cursor, VS Code et autres clients
Les clients qui se configurent par fichier acceptent ce bloc ; le nom et l'emplacement du fichier varient d'un client à l'autre.
{
"mcpServers": {
"zerolith": {
"type": "http",
"url": "https://zerolith.io/mcp"
}
}
}Authentification et révocation
L'accès passe par OAuth 2.1 : pas de clé API à recopier dans la configuration d'un client, donc pas de secret longue durée qui traîne dans un fichier de config.
- Enregistrement dynamique du client (RFC 7591) : votre agent s'enregistre lui-même. Vous n'avez aucun identifiant applicatif à créer, à copier ni à stocker quelque part.
- PKCE en S256, obligatoire : un code d'autorisation intercepté est inutilisable sans le vérificateur, qui ne quitte jamais votre agent.
- Jeton lié à sa ressource (RFC 8707) : un jeton émis pour zerolith ne vaut rien ailleurs, et un jeton émis pour un autre service ne vaut rien ici. Même volé, il n'ouvre pas la mauvaise porte.
- Rotation des jetons de rafraîchissement : chaque renouvellement invalide le précédent, si bien qu'un jeton dérobé puis rejoué se signale de lui-même.
- Deux portées, pas davantage : mcp:read pour consulter, mcp:write pour agir. Une portée demandée que nous ne connaissons pas est refusée, jamais élargie en silence.
Révocation : changer votre mot de passe invalide immédiatement les autorisations MCP en cours (refresh tokens et codes d'autorisation non consommés), en plus de vos sessions web.
Ce qu'un agent peut faire
Connecter un agent, c'est lui déléguer des actions, pas vos secrets. Voici jusqu'où il peut aller, et ce qu'il ne verra jamais.
- Il n'agit que dans votre compte. Chaque outil est borné à vos propres ressources : interroger l'identifiant d'une fonction qui ne vous appartient pas répond « introuvable » et jamais « interdit ». Nous ne confirmons même pas son existence.
- Vos clés API restent invisibles. Elles sont stockées hachées et ne s'affichent qu'une seule fois, à leur création, dans l'interface. Aucun outil MCP ne les renvoie, et l'agent n'en a pas besoin : il s'authentifie avec son propre jeton.
- Vos secrets aussi. Une variable d'environnement de type secret est écrite dans le cluster et n'est jamais relue : l'agent peut la créer, la remplacer ou la supprimer, mais pas en lire la valeur. Vous non plus, d'ailleurs.
- Le jeton de votre base de données et vos clés de stockage ne sortent pas davantage. L'agent peut créer la base, l'attacher à une fonction, lancer vos migrations ou déclencher un export sans jamais recevoir l'identifiant qui l'ouvre.
- Les actions qui modifient l'état sont déclarées comme telles. Chaque outil annonce s'il écrit, ce qui permet à votre client MCP de vous demander confirmation avant de laisser l'agent agir.
Vous coupez l'accès quand vous le décidez, depuis la page MCP de votre tableau de bord. La révocation invalide immédiatement le jeton d'accès déjà émis, et pas seulement son renouvellement : autrement un agent garderait la main jusqu'à l'expiration du jeton pendant que l'interface afficherait « déconnecté ». Réinitialiser votre mot de passe coupe lui aussi tout accès MCP en cours.
Les outils exposés
41 outils, tous limités au périmètre de votre compte. Les descriptions ci-dessous sont celles que le serveur annonce à votre client, mot pour mot : c'est le contrat que lit l'agent.
| Outil | Portée | Description |
|---|---|---|
| whoami | mcp:read | Return the authenticated account and credit balance. |
| get_catalog | mcp:read | List languages, size presets, deploy defaults, and pricing. |
| list_functions | mcp:read | List all of the caller's deployed functions. |
| get_function | mcp:read | Get one function by id (config, URL, attached env vars, and current source code — read this before update_function to edit code in place). |
| deploy_function | mcp:write | Deploy a new function. Requires a verified account. Pass `database` (a name) to auto-create-or-reuse a private database and attach it — the function code then just reads DATABASE_URL / DATABASE_AUTH_TOKEN (requires databases enabled). Pass kind='migrate' for a schema migrator: it runs once on demand and has no URL at all. |
| update_function | mcp:write | Update a function (code and/or config). Requires a verified account. |
| delete_function | mcp:write | Delete a function. Requires a verified account. |
| invoke_function | mcp:write | Invoke a deployed function once (credit-gated); returns HTTP status. |
| get_function_metrics | mcp:read | Live status metrics for one function (rps, latency, instances, cpu/mem). |
| get_function_logs | mcp:read | Recent stdout/stderr of one function, newest first. This is the function's OWN output; the platform's request log is not included. Optionally filter by a plain substring (not a pattern). Paginate backwards with end_cursor_ns. |
| get_database_logs | mcp:read | Recent log lines of one database's sqld engine, newest first. Platform storage identifiers are redacted. Optionally filter by a plain substring (not a pattern). |
| get_usage_summary | mcp:read | Billing summary: balance plus requests, GB-seconds and cost billed, with the compute/storage split (database storage is billed on the tier held). Covers the CURRENT CALENDAR MONTH by default — pass period='all' for the account lifetime. The range aggregated is returned as since/until; the balance is always current. |
| list_env_vars | mcp:read | List the caller's account-level env vars (config values readable; secret values are write-only and never returned). |
| get_env_var | mcp:read | Get one account env var by id (config value readable; secret value never returned — use its value to edit a config var in place). |
| create_env_var | mcp:write | Create an account env var. Requires a verified account. |
| update_env_var | mcp:write | Replace an account env var's value. Requires a verified account. |
| delete_env_var | mcp:write | Delete an account env var (409 if still referenced by a function). Requires a verified account. |
| list_custom_domains | mcp:read | List the caller's custom domains: the hostname, its status (pending/verified/active), and the exact DNS records to publish. Use this to tell the user what is still missing — `pending` means the ownership TXT record has not been seen yet, and `last_error` says why. |
| add_custom_domain | mcp:write | Claim a hostname for one of the caller's functions. Nothing is routed yet: the response carries a TXT record the user must publish to prove they control the domain, plus the CNAME to point at us. Once both exist the platform provisions TLS and the route automatically, usually within a minute. |
| delete_custom_domain | mcp:write | Release a custom domain. Removes its route and certificate; the hostname stops serving immediately and becomes claimable again. |
| create_presigned_url | mcp:write | Mint a presigned URL that invokes ONE function until ONE deadline, with no API key needed by whoever calls it — the credential is in the URL. Use it to hand a webhook sender, a browser or a third party temporary access to a private function instead of sharing an account API key. The URL is returned ONCE and never again; the deadline defaults to 7 days and can be set with `expires_at`. Revoke it early with revoke_presigned_url. |
| list_presigned_urls | mcp:read | List a function's presigned URLs: label, deadline, whether each is still live, when it was last used, and when it was revoked. The URL and its token are never returned — they exist only in the create response. Expired and revoked entries are listed too, because 'why did this URL stop working' is asked after the fact. |
| revoke_presigned_url | mcp:write | Revoke a presigned URL before its deadline. It stops authorizing invocations within seconds (the edge caches decisions briefly). Irreversible — mint a new one if it was a mistake. |
| list_databases | mcp:read | List the caller's private databases (tier, always_on, status). The auth token is never returned — it is injected into attached functions. |
| get_database | mcp:read | Get one private database by id (tier, size, always_on, attached functions, and the injected env-var names). The token value is never returned. |
| create_database | mcp:write | Create a private database. Requires a verified account (+ databases enabled). Returns the injected env-var names (DATABASE_URL, DATABASE_AUTH_TOKEN); the token value is write-only and never returned. |
| delete_database | mcp:write | Delete a private database (409 if still attached to a function). Requires a verified account. |
| attach_database | mcp:write | Attach a database to a function (injects DATABASE_URL / DATABASE_AUTH_TOKEN and redeploys it). One database per function. Requires a verified account. |
| detach_database | mcp:write | Detach a database from a function (drops the injection and redeploys it). Requires a verified account. |
| get_database_metrics | mcp:read | Live status for one database: CPU, memory, running instances and the bytes its data volume holds, against the provisioned storage tier. When instances is 0 the database is asleep: CPU/memory are 0, but volume_used_bytes is still its last measured size (a sleeping database takes no writes) — report it as such, not as live. |
| set_database_size | mcp:write | Change a database's CPU/memory preset (same size names as functions — see get_catalog). Requires a verified account. RESTARTS the database: an awake one is briefly unavailable and in-flight connections drop; the data is untouched. Sending the preset it already has changes nothing and restarts nothing. |
| set_database_tier | mcp:write | Raise a database's provisioned storage tier (see get_catalog for the ladder). UPGRADE ONLY — a lower tier is refused, because the cap bounds a database that is already larger and shrinking needs compaction, not a smaller number. Use this when writes start failing with 'database or disk is full'. Requires a verified account. RESTARTS the database, and the new cap only applies once that restart completes — a write retried immediately may still fail; wait a few seconds. Storage is billed on the tier held, so the charge rises from the next billing window. |
| rotate_database_token | mcp:write | Withdraw this database's current access token and issue a new one. Use after a suspected leak: the token is injected into attached functions' environment by design and carries no expiry, so rotating is the only way to withdraw it. RESTARTS the database and redeploys every attached function; anything still holding the old token (a copied value, a local script) stops working immediately. The data is untouched. Requires a verified account. |
| set_database_always_on | mcp:write | Switch a database between scale-to-zero and always-on. Always-on keeps one instance up so no query pays a cold restore from S3, and bills its compute continuously; scale-to-zero costs nothing while idle. Storage is billed either way. Requires a verified account. RESTARTS the database, so an awake one is briefly unavailable. |
| set_database_stable_window | mcp:write | Set how long a database stays up after its last query before scaling to zero (6s–1h). Waking it costs a cold start plus a restore from S3, so a longer window absorbs spaced-out bursts for a fraction of what always_on costs. Only takes effect while always_on is false. Requires a verified account. RESTARTS the database, so an awake one is briefly unavailable. |
| export_database | mcp:write | Export a database to a portable SQL dump you can download and restore anywhere (gunzip | sqlite3). Poll get_database_export for the download link. Use this before deleting a database, and whenever the account is low on credit: a database whose account stays at a zero balance has its DATA deleted once the retention window (see get_catalog databases.retention_days) elapses. Requires a verified account. |
| get_database_export | mcp:read | Status of a database's latest export, with a time-limited download URL once it is ready (status 'ready'). 'pending' means the dump is still running — poll again; 'failed' carries the reason. The URL expires (see get_catalog databases.export_url_ttl_seconds); calling this again mints a fresh one. |
| list_database_exports | mcp:read | The export history of a database, newest first: when each dump was taken, how big it was, and whether it is still downloadable. Only ONE dump is kept per database — older entries read 'superseded', meaning the record remains but the file was replaced by the newer export. |
| set_database_migrator | mcp:write | Designate one of your functions as a database's schema migrator (attaches it so it receives DATABASE_URL/DATABASE_AUTH_TOKEN). Requires a verified account. The function should be idempotent — it runs on demand via run_migration. |
| unset_database_migrator | mcp:write | Remove a database's migrator designation. The function stays attached (it may still use the database) — use detach_database to drop the injection too. Requires a verified account. |
| run_migration | mcp:write | Run a database's designated migrator function once, on demand. Always invoked through the internal signed-token path, never the function's public route. Credit-gated. Returns the invocation outcome (ok/status). |
19 de ces outils concernent les bases de données privées, une fonctionnalité optionnelle. Là où le déploiement ne l'active pas, ils ne sont ni annoncés par tools/list ni appelables.
Ce que l'agent ne peut pas faire
Le serveur MCP n'est pas un accès administrateur. Il est soumis aux mêmes règles que le reste de la plateforme :
- Périmètre du compte uniquement : une ressource qui ne vous appartient pas répond 404 et jamais 403, si bien que l'agent n'apprend même pas qu'elle existe.
- Les opérations d'écriture exigent un compte vérifié, et sont refusées quand le crédit est épuisé.
- Les valeurs de secrets ne sont jamais relues : aucun outil ne peut les renvoyer, ni à l'agent ni à vous.
Ce que ça coûte
Piloter la plateforme par un agent ne coûte rien en soi. Les appels d'administration (créer une fonction, lister vos bases, consulter vos métriques, modifier une variable) passent par l'API de la plateforme et ne sont pas facturés.
Ce qui est facturé, c'est l'exécution. Une invocation déclenchée par un agent est comptée exactement comme n'importe quelle autre, et elle est soumise au même contrôle de crédit : un solde épuisé la refuse en bordure, avant même que votre code ne démarre. Un agent ne peut donc pas creuser votre solde à votre insu.
Questions fréquentes
Le serveur MCP est-il hébergé chez vous ou chez moi ?
Chez nous. C'est un serveur MCP distant, joignable en HTTP à l'URL publiée sur cette page. Vous n'avez rien à installer ni à maintenir, et il reste joignable depuis n'importe quel poste où vous vous authentifiez.
Dois-je confier une clé API à mon agent ?
Non. L'accès passe par OAuth 2.1 avec PKCE : le client obtient un jeton lié à son audience, révocable à tout moment, et aucune clé API longue durée n'est stockée dans la configuration de l'agent.
Quels clients MCP sont compatibles ?
Tout client parlant MCP sur transport HTTP avec autorisation OAuth 2.1 : Claude Code, Cursor, VS Code et les autres implémentations conformes. Le serveur n'a aucun traitement spécifique par client.
Puis-je héberger le serveur MCP moi-même ?
Ce n'est pas nécessaire, c'est justement ce que le service managé vous épargne. Le protocole reste standard et les mêmes actions sont disponibles via l'API REST, donc rien ne vous enferme.
Le serveur MCP est-il facturé en plus ?
Non. Le MCP n'est pas facturé : vous payez l'exécution de vos fonctions (GB-secondes) et leurs invocations, exactement comme si vous les aviez déployées à la main.
Donnez un FaaS à votre agent
Créez un compte, connectez votre client MCP, et laissez l'agent déployer sa première fonction. Crédit offert à l'inscription, sans carte bancaire.
Commencer »