SatGate

MCP serverCommerce & finance

Budget, payment and audit controls for AI agent API calls and MCP tool calls.

Available today. Use it from your connected AI after setup.

Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.

Then ask your AI: use SatGate

Install SatGate

The server’s own address, for the clients that take one directly. Or connect ahel onceand every client you use reads it from one address, with the account kept on ahel rather than in each client’s config.

  • Claude Code

    claude mcp add --transport http --scope user satgate 'https://satgate-mcp-saas.fly.dev/sse'

    Run it once in your project, then open /mcp to approve any sign-in the server asks for.

  • Claude Desktop

    https://satgate-mcp-saas.fly.dev/sse

    Add a custom connector in Settings, paste this address, and approve the sign-in.

  • Cursor

    cursor://anysphere.cursor-deeplink/mcp/install?name=satgate&config=eyJ1cmwiOiJodHRwczovL3NhdGdhdGUtbWNwLXNhYXMuZmx5LmRldi9zc2UifQ==

    Open the link and Cursor adds the server at that address.

  • ChatGPT

    https://satgate-mcp-saas.fly.dev/sse

    In Settings, enable Developer mode, create an MCP app, and paste this address. Your plan and workspace must allow custom apps.

  • Codex

    codex mcp add satgate --url 'https://satgate-mcp-saas.fly.dev/sse'

    Run it once, then sign in with codex mcp login satgate if the server asks for an account.

From the project's README

As published by satgate-io/satgate in README.md.


SatGate is a gateway in front of APIs and MCP tools. It meters agent and MCP traffic (Observe), enforces owner budgets before work runs (Control), and charges outside agents on the routes you choose (Admit; the Charge policy in the dashboard). Every allow or deny comes with a signed receipt.

Try it as an agent. This hosted route costs 10 sats:

curl -i -H "X-SatGate-Tenant: satgate-demo" https://api.satgate.io/paid/agent-demo

The unpaid call returns HTTP 402 with a Lightning invoice and terms. Agent instructions are in llms.txt.

Build Agents with SatGate

SatGate's developer primitive is three calls: issue(), pay(), and verify().

import os
from satgate import SatGate

satgate = SatGate(api_key=os.getenv("SATGATE_API_KEY"))

capability = satgate.issue(
    task="research market prices",
    agent="research-agent",
    allow=["mcp:web.search", "api:prices.read"],
    budget_usd=25,
    expires_in="1h",
)

receipt = satgate.pay(
    upstream="https://api.example.com/search",
    capability=capability,
    max_usd=4.20,
)

verified = satgate.verify(receipt)
print(verified.decision, verified.evidence_pack_id)

Install today:

pip install satgate
npm install @satgate/sdk

The public packages install today; the issue/pay/verify API namespace is in private beta. Calls without private-beta access raise a structured error instead of returning fake receipts:

SatGateAuthError: This API namespace requires private beta access. Visit cloud.satgate.io/docs to request access.

Runnable examples:

  • examples/python/issue_pay_verify.py
  • examples/node/issue-pay-verify.mjs

Works with: MCP · OpenAI tools · Anthropic tools · LangChain · CrewAI · Raw HTTP


🎬 See SatGate in Action

  


☁️ Don't want to self-host? Try SatGate Cloud

Managed SaaS — zero setup, multi-tenant isolation, enterprise dashboard. Free Observe tier. No credit card required.


The Problem

AI agents are making API calls autonomously. They spawn sub-agents, call MCP tools, and run overnight while you sleep.

Your existing stack answers: "Is this request authenticated?"

Nobody answers: "Should this agent have authority to spend, delegate, or invoke this paid resource?"

✓ Network Firewall    → "Can this packet enter?"
✓ Application Firewall → "Is this request safe?"
? Economic Firewall    → "Should this agent act, spend, or pay?"

That's the gap. SatGate fills it.

What is SatGate?

SatGate is an Economic Firewall for AI agent requests. Drop it in front of your APIs and MCP tools to enforce scoped authority, budgets, paid-rail context, and Evidence Pack receipts before agents act.

Not another routing layer. Routing gateways (Bifrost, LiteLLM, Portkey) optimize which provider handles a call. SatGate governs whether the call should happen at all based on authority, policy, budget, and paid-rail context.

Use them together:

Agent → SatGate (economic governance) → Routing Gateway → LLM Providers

Features

  • 🛡️ Capability Tokens (Macaroons) — Cryptographic credentials with built-in caveats, delegation, and next-request revocation. Not API keys — tokens that agents can safely sub-delegate.
  • 🎯 MCP-Aware — Parses MCP JSON-RPC tool calls. Know that Agent X spent $47 on search_database and $12 on send_email — not just "1,000 requests."
  • 💰 Budget Enforcement — Hard stops per agent, team, or API. When the budget hits zero, requests are blocked. Not logged. Not alerted. Blocked.
  • ⚡ Paid-Rail Governance — Govern paid API access across L402, x402, API-key billing, and enterprise ledgers without making any one rail the control plane.
  • 🔒 Default-Deny — All routes require valid credentials unless explicitly public. Zero Trust by design.
  • 🚀 <50ms Overhead — Lightweight Go proxy. Adds governance without adding latency.
  • 📦 Self-Hosted — Your infrastructure, your rules. Single binary, Docker, or Kubernetes.
  • 🔌 Drop-in — Works with any HTTP backend. REST, GraphQL, MCP servers. No code changes.

Quick Start

60-Second Demo

# Download the binary (macOS Apple Silicon — see Releases for other platforms)
curl -L https://github.com/satgate-io/satgate/releases/latest/download/satgate-darwin-arm64 -o satgate
chmod +x satgate

# Start with example config (mock Lightning, auto-generated keys)
export ADMIN_TOKEN=my-secret-token
export LIGHTNING_BACKEND=mock
./satgate --config examples/gateway.yaml

Try the three policies:

# 1. Public — no auth needed
curl http://localhost:8080/health

# 2. Protected — mint a capability token, then use it
curl -X POST http://localhost:8080/api/capability/mint \
  -H "X-Admin-Token: my-secret-token" \
  -H "Content-Type: application/json" \
  -d '{"scope": "api:read", "duration": "1h"}'

# Use the token:
curl -H "Authorization: Bearer YOUR_CAPABILITY_TOKEN" \
  http://localhost:8080/api/capability/ping

# 3. Paid — get a payment challenge (L402 today; x402/other rails as governed context)
curl http://localhost:8080/api/micro

Public → Protected → Paid. Three policies, one gateway; paid rails are governed context, not the product boundary.

Hosted paid demo (Admit; Charge in the dashboard). No local Lightning node:

curl -i -H "X-SatGate-Tenant: satgate-demo" https://api.satgate.io/paid/agent-demo

Unpaid calls return 402. Price is 10 sats. Show the invoice to the owner, poll payment status, then retry. Poll rules are in llms.txt.

📖 Full Quick Start Guide →

Other Install Methods

# Docker
docker run -v $(pwd)/gateway.yaml:/etc/satgate/gateway.yaml \
  -e ADMIN_TOKEN=my-secret-token -e LIGHTNING_BACKEND=mock \
  -p 8080:8080 ghcr.io/satgate-io/satgate:latest

# Build from source
git clone https://github.com/satgate-io/satgate.git
cd satgate && go build -o satgate ./cmd/satgate

Configuration

version: 1

server:
  listen: ":8080"

admin:
  capabilityRootKey: "${CAPABILITY_ROOT_KEY}"

lightning:
  provider: "${LIGHTNING_BACKEND}"
  config:
    connectionString: "${NWC_CONNECTION_STRING}"

upstreams:
  api:
    url: "http://localhost:3000"

routes:
  - name: public-health
    match:
      pathPrefix: /health
    upstream: api
    policy:
      kind: public

  - name: protected-api
    match:
      pathPrefix: /api/
    upstream: api
    policy:
      kind: capability
      scope: "api:read"

  - name: premium-api
    match:
      pathPrefix: /premium/
    upstream: api
    policy:
      kind: l402  # paid-rail policy; use payment_context to preserve L402/x402/ledger evidence
      priceSats: 100

Policy Types

PolicyDescriptionUse Case
publicNo authenticationHealth checks, docs, webhooks
capabilityRequires valid MacaroonProtected API endpoints
l402Requires Lightning payment and records paid-rail contextMonetized endpoints; x402/ledger context can be preserved in Evidence Packs

How It's Different

SatGateRouting GatewaysTraditional API Gateways
Primary concernEconomic governanceProvider routingTraffic management
Budget enforcementHard caps (blocked at limit)Soft alerts only❌
MCP cost attributionPer-tool granularity❌❌
Credential modelMacaroons (delegatable)API keysAPI keys / OAuth
Agent delegationSub-tokens with reduced budgets❌❌
Paid-rail governanceL402, x402, API-key billing, enterprise ledgers❌❌
Works alongside—✅ Use together✅ Use together

Architecture

┌──────────────────────────────────────────────────┐
│                    SatGate                        │
│                                                   │
│  Request → Route Match → Policy Check → Proxy    │
│                             │                     │
│              ┌──────────────┼──────────────┐     │
│              │              │              │      │
│          [public]    [capability]   [paid rail]  │
│          pass        verify token     verify     │
│                      check budget     payment    │
│                      log MCP tool     context    │
└──────────────────────────────────────────────────┘

Key Concepts:

  • Macaroons: Bearer tokens with embedded caveats (expiry, scope, budget, IP). Not API keys — they support delegation without server roundtrips.
  • Delegation: Agent A gives Agent B a sub-token with reduced permissions and a $50 budget cap. B can't escalate.
  • MCP Parsing: SatGate reads MCP JSON-RPC payloads to attribute costs to specific tool calls, not just HTTP endpoints.
  • Paid-rail context: SatGate treats L402, x402, API-key billing, and enterprise ledgers as rails to govern around. Evidence Packs preserve which rail was involved without making the rail the product.

SDKs

LanguagePackageDocs
Pythonpip install satgateREADME
JavaScriptnpm install @satgate/sdkREADME

MCP Proxy (NEW)

SatGate now includes a native MCP proxy that governs tool calls for any MCP-compatible agent:

# Run MCP proxy with 1000-credit budget
satgate-mcp --config satgate-mcp.yaml
  • Budget enforcement: Hard 402 when agents exhaust their allocation
  • Delegation: Parent agents mint sub-agent tokens with carved budgets
  • Per-tool costs: web_search: 5, dalle_generate: 50 (wildcard patterns supported)
  • Two transports: stdio (local sidecar) or SSE/HTTP (remote multi-agent)
  • Three auth modes: none, static token, macaroon (HMAC chain)

See pkg/mcpserver/README.md for full documentation.

Documentation

☁️ SatGate Cloud & Enterprise

Self-hosting not your thing? SatGate Cloud is the fully managed version — same gateway, zero ops.

The open-source gateway handles protection, budgets, and paid-rail enforcement. SatGate Cloud adds the control plane:

  • 📊 Observe — Real-time dashboards, usage attribution, cost center tagging
  • 🎚️ Control — Budget and policy enforcement before agent requests execute
  • 🤖 SatGate Mint — Zero-touch agent provisioning (K8s, AWS, OIDC)
  • 🏢 Multi-tenant — Team isolation, RBAC, SSO/SCIM
  • 📝 Audit — Tamper-evident logging, compliance exports

Start Free → (Observe mode is free, unlimited, forever)

Contributing

We welcome contributions! See CONTRIBUTING.md for guidelines.

git clone https://github.com/satgate-io/satgate.git
cd satgate
go mod download
go test ./...
go build -o satgate ./cmd/satgate

License

Apache License 2.0 — see LICENSE for details.

Links


Signals

GitHub stars
11
Forks
3
Last commit
Sep 2026
Weekly downloads
6
Advanced
Delivery
satgate MCP server → your ahel connector (mcp.ahel.ai) → your AI.
Item type
mcp-server
Key
io-github-satgate-io-satgate
Source
github.com/satgate-io/satgate
Hosted endpoint
https://satgate-mcp-saas.fly.dev/sse