Selat

Open source tool gateway

One gateway, every tool, any agent

Your agent needs GitHub. Then Gmail, then Drive. Each one wants its own OAuth dance, its own refresh loop, its own error shape, and you write all of it again for the next agent. Selat carries that part. Your agent holds one bearer, and it does not change when you connect or disconnect anything.

Or run it yourself, Apache-2.0, no account:npx @fajarhide/selat

The pitch

The code you stop writing

You can call the vendor APIs directly, and for one agent against one service you probably should. Selat starts paying for itself at the third upstream, or the second agent, or the first time a refresh token rotates at 3am.

Without Selat
// a vault
await store.put(userId, 'github', encrypt(tok))

// a refresher, on a timer, forever
if (tok.expires_at < now()) {
  tok = await gh.refresh(tok.refresh_token)
  await store.put(userId, 'github', encrypt(tok))
}

// a client, a schema, an error shape
const gh = new Octokit({ auth: decrypt(tok) })

// then all of it again for Gmail, Drive,
// Discord, Notion, Slack
With Selat
const res = await fetch(
  `${SELAT}/v1/tools/github__list_issues/call`,
  {
    method: 'POST',
    headers: {
      authorization: `Bearer ${SELAT_TOKEN}`,
      'content-type': 'application/json',
    },
    body: JSON.stringify({
      owner: 'vercel', repo: 'next.js',
    }),
  },
)

Getting started

Three steps to a first tool call

  1. 01

    Sign in

    Google or GitHub. A workspace is created and one gateway credential is shown, once.

  2. 02

    Connect an upstream

    From the dashboard, in a consent screen or a pasted key. OAuth, refresh and revocation are ours to carry.

  3. 03

    Point your agent at the gateway

    The credential does not change when you connect or disconnect anything later.

HTTP
curl -s https://api.selat.weekndlabs.com/v1/tools \
  -H "Authorization: Bearer slt_live_..."

curl -s -X POST https://api.selat.weekndlabs.com/v1/tools/github__list_issues/call \
  -H "Authorization: Bearer slt_live_..." \
  -H 'content-type: application/json' \
  -d '{"owner":"selat","repo":"selat","state":"open"}'
MCP client
{
  "mcpServers": {
    "selat": {
      "type": "http",
      "url": "https://api.selat.weekndlabs.com/mcp",
      "headers": {
        "Authorization": "Bearer slt_live_..."
      }
    }
  }
}

Objections

What people ask before they try it

Why not a server per vendor?
You end up running one process per service, each with its own auth story, and your agent sees an unbounded tool list. Selat is one endpoint, one token, and a catalog you can filter.
Why not my model vendor’s connectors?
They work well inside that vendor. Selat runs the same tools against any runtime, including the one you wrote yourself, on your own hardware with your own OAuth applications.
What if the tool list gets huge?
Agents degrade well before any API limit, so the catalog is capped at 60 tools per workspace and every tool can be toggled. When the cap bites it says so, rather than quietly shortening the list.

Pricing

Priced on calls, not seats you forgot about

Free

Free

  • 5,000 tool calls per month
  • 1 seat
  • Calls stop at the cap until the next period

Pro

$29/mo

  • 50,000 tool calls per month
  • 3 seats
  • Calls stop at the cap until the next period

Team

$99/mo

  • 250,000 tool calls per month
  • 10 seats
  • Calls stop at the cap until the next period

Enterprise

Talk to us

  • SAML and SCIM
  • Self-host or BYOC support
  • DPA, SLA and data residency
sales@selat.com

Every number here is read from the same plan table checkout uses, so a price on this page and a price on an invoice cannot drift apart.

Connect an upstream, point your agent at it, make the call

Start free