Two agents, one limit, one refused.

Actions

Let it act without handing over your keys

Your agent calls tools by name. Anlyon holds the credentials and makes the call, so the model never sees a key, and a stray sentence can’t steal one.

agent.ts
// The secret goes in once. No API ever returns it.await anlyon.secrets.put("STRIPE_KEY", {  value: process.env.STRIPE_KEY!,});await anlyon.actions.create({  name: "refund-customer",  method: "POST",  urlTemplate: "https://api.stripe.com/v1/refunds",  headers: { Authorization: "Bearer {{secret:STRIPE_KEY}}", "Content-Type": "application/x-www-form-urlencoded" },  requiresApproval: true,});// The agent knows the tool's name. That's all it knows.await anlyon.actions.invoke("refund-customer", { charge: "ch_1" });

What it does

Execution

Execute with credentials the model never sees

Your action template references {{secret:STRIPE_KEY}}. Anlyon resolves it server-side, at call time, on the wire out. The key exists in the request Anlyon makes, never in the context the model reads.

The vault

A vault with no read endpoint

Secrets go in. Nothing gets them out. Not the model, not your code, not you. It isn’t an ACL you could misconfigure. The endpoint was never built. A secret is also bound to where it may be sent, and that binding is checked again at the moment of the call.

Approval

Pause sensitive production actions for human approval

Turn on approval for an action and the call parks until you or a teammate signs off in the dashboard. Everything else still runs inline, at full speed.

A pattern

A support agent that can issue refunds

It decides a refund is warranted. A human decides whether it happens, and the request to Stripe leaves from Anlyon.

Free tier, no credit card. One command if you use Claude or Cursor.

$ claude mcp add anlyon -- npx -y @anlyonhq/mcp-server