- @exysh/sdk: a typed client for the API v1, plus a verifier for webhook signatures.
- @exysh/mcp: an MCP server that gives AI agents (Claude Code, Claude Desktop, Cursor and any other MCP client) tools to manage your servers, orders, invoices and support tickets.
TypeScript SDK
EXY_API_TOKEN environment variable.
- Typed: every path, parameter, request body and response is typed. The
paths,operationsandwebhookstypes are exported too. - No exceptions on HTTP errors: a call resolves to
{ data, error, response }and never throws on an error status. - Options: the client is built on openapi-fetch. The second argument of
createClientaccepts its options, for examplebaseUrlor a customfetch. - Paid calls:
POST /v1/orders,POST /v1/servers/{id}/renewandPOST /v1/servers/{id}/upgradestake anIdempotency-Keyheader. Generate one key per purchase and reuse it when you retry; see Order and renew servers. - Webhooks:
verifyWebhookchecks the signature and the timestamp of a delivery. Pass the raw body before parsing it; see Webhooks.
MCP server
The MCP server runs locally on your machine over stdio. It talks only tohttps://api.exy.sh/v1, through @exysh/sdk, with your own token. Nothing else has to be installed.
1
Create a token
Create a token under Settings → API with only the scopes the agent needs.
vms.read, billing.read and tickets.read are enough to try it out.2
Add the server to your client
The token is read from the Claude Desktop, Cursor and other clients (JSON config):
EXY_API_TOKEN environment variable, never from an argument.Claude Code:EXY_API_TOKEN the server exits immediately with a message on stderr.
Scopes and tools
The agent only gets the tools its token’s scopes allow.What the server guarantees
- Confirmation:
delete_serverandreinstall_serverrequireconfirmName, like the API. The server never fills in the name itself. Whether your client asks you before running a destructive tool is up to the client. - Paid calls:
order_serverandrenew_serverrequire anidempotencyKeyfrom the caller. The server never retries a call and never makes up a key. After a timeout, call again with the same key: the API returns the first result and charges once. - Errors: an error comes back with the HTTP status and the API’s
codeandmessage; a429also carriesretryAfterSeconds. - Token: the server logs nothing and never returns the token in a result.