Skip to main content

Connections

A Connection is a server-side router for an external API or inference endpoint. You (or a team) configure the base URL and a credential (the key) once; agents call through it and never see or hold the key. One credential can serve several connections, so a key used in two places is stored once and replaced in one step. This lets an agent talk to MiniMax, Anthropic, or any HTTP API without the key ever reaching the client — Tokenrip injects it at the edge. On a chat host (Claude, ChatGPT and other MCP apps), agents call a connection through its operations: calls you save on the connection under a name, each of which becomes its own tool. See Operations.

Calling a connection

A call sends a request through a named connection. The caller supplies the path, method, and body; Tokenrip resolves the connection, injects the secret, and returns the provider’s response. Call your own connection by name, or a team’s connection by name plus the team. Any current member of the team can call it, unless its credential is restricted to named members; no grant is needed:
The same call is POST /v0/connections/call over REST; the dashboard uses POST /v0/operator/connections/call. A call runs once and is never retried; the response is the provider’s status, headers and body. This generic call has no MCP tool, since chat directories reject a tool that takes any method and path; on MCP, agents call the connection’s operations instead. A caller who is not a current member, or is not named on a restricted credential, gets 403 CONNECTION_FORBIDDEN; a missing or disabled connection is 404 CONNECTION_NOT_FOUND. Listing connections (connection_list, GET /v0/connections) tells you for each one whether you may call it now: canCall.

Operations

An operation is one call saved on a connection under a name: a fixed method and path, a described input, and a statement of what the call changes at the provider. Every agent that may call the connection can run its operations: on MCP each one is its own tool, and the CLI and REST call it by name. The key stays on the server, and every call is checked against the connection’s rules and limits like any other.

Declaring an operation

Or open the connection on the dashboard’s Connections page and use Add operation in its Operations section, which shows each operation’s tool name, class, method and path. Over REST, operations live at /v0/connections/:connection/operations[/:operation]. Declaring, changing and removing take the connection’s write right (its personal owner, or a team connection’s creator or the team owner); any member may list and read them. MCP has no tool to declare one. An operation has these parts:

Running an operation

Over REST this is POST /v0/connections/:connection/operations/:operation/call with { "team": "quintel", "input": { … } }. The input is checked against the schema first: a wrong or unknown field is 400 INVALID_FIELD naming it, and nothing is sent. The answer is { status, body }: the provider’s status inside a 200, and the part of its answer the response pointer selects.

Operations on a chat host

Each operation is an MCP tool named <connection>_<operation>, or for a team connection <team>_<connection>_<operation>, lowercased with - as _: team quintel’s posthog connection lists query as quintel_posthog_query. The tool’s title is the declared one, and its description is the declared text followed by where it goes (“Calls us.posthog.com with team quintel’s posthog connection.”). The tool answers { status, body }; a provider error comes back as UPSTREAM_STATUS with the provider’s status and the start of its answer, so the agent can correct its input. An agent sees an operation’s tool when it may call the connection now: the connection is enabled, the agent’s person owns it or is a current member of its team, and, on a restricted credential, the person is named. A connector approved without the connections:execute scope sees none. Tokenrip sends hosts no notice when operations change. A host sees a new, changed or removed operation the next time it lists Tokenrip’s tools: depending on the host, after you reconnect the connector, refresh its tools, or start a new conversation.

How the class is decided

Hosts use a tool’s class to decide when to ask you first. An operation’s class comes from its kinds: Every operation tool is marked as reaching an outside service. One that changes something also takes why, one sentence on what the person is after. The kinds are your statement about your own key’s calls: Tokenrip checks the declaration’s shape and that the call fits the connection’s rules, not what the provider does with it. Spending money is not a kind, so a call that costs money and changes nothing at the provider may be declared a read.

Limits

  • The path is fixed. No path placeholders, per-operation headers or per-operation limits: the connection’s rate limit, daily quota and default headers apply.
  • Inputs carry no secrets. A field whose name says it holds a secret (api_key, token, password, secret, session, code, otp and the like), or a number that only fits a six-digit code, is refused when you declare it. why is reserved, and method cannot sit beside path or url.
  • Size. At most 32 input fields at the top level and 4 levels below it. The input schema and the fixed body may each store 16 KiB, the placements 4 KiB.
  • Tool names are at most 64 characters, never a built-in tool’s name, and unique among the operations on the owner’s enabled connections. If two owners’ operations would give you the same tool name (team acme’s co-posthog and team acme-co’s posthog), neither is listed for you until one is renamed.
  • Answers. On MCP an answer of up to about 31 KiB comes back in the reply; a larger one is refused with RESPONSE_TOO_LARGE, so narrow the call or its response pointer (on an operation that changes something, the call itself went through; only its answer is lost). The CLI and REST return up to 5 MB.
  • Nothing is stored from the answer. The audit log records the call with the operation’s name; neither the input nor the answer is kept.
  • The connection keeps its operations callable. A change to its base URL or allowed paths that would leave an operation outside them, a default query that names an input of a GET or DELETE operation (the input would replace the connection’s value), or a rename that would break a tool name, is refused with 409 OPERATIONS_WOULD_BREAK naming the operations. Disabling the connection hides its operations; deleting it deletes them.

Ownership: personal vs team

A connection is owned by either your account (personal) or a team. A personal connection is private to you — your agent and your operator session in the dashboard see the same one. A team-owned connection is readable and callable by any current team member, and any member may create one. Writes are narrower than reads: update, rotate, disable and delete are allowed for the connection’s creator or the team owner. So a member can wire up the provider they need without waiting on the owner, and nobody but the person who stored a key (or the owner) can rotate or remove it. Credentials have their own, narrower rule: any member may add a team credential, but only its creator or the team owner may rotate, rename, delete or attach it to a connection, and changing the base URL or allowed paths of a connection that uses it needs the same right. Otherwise any member could point someone else’s key at a new address or loosen its limits.
When a member leaves a team, every team connection that uses a credential they created is disabled, whoever created the connection — the upstream key was theirs, and the team’s right to spend it ends with the membership. The exception is an owner handover, where the departing owner’s connections and credentials are reassigned to the new owner instead.
Team ownership lets a whole team share one provider (one key, configured once) instead of each member wiring up their own.

Creating and managing connections

A connection or a credential is named by its id alone (yours, or a team’s you belong to), or by its name: with --team <slug> for a team’s, without for your own. An id you cannot reach answers 404, exactly as an id that does not exist. --auth-type is bearer, header, or basic. Pass the secret with --secret-env or --secret-stdin rather than --secret, so it stays out of shell history. Add --team <slug> to create for a team-owned connection. Secrets are never returned by any read. Creating, updating, and rotating happen over the CLI, REST (/v0/connections and /v0/credentials for every owner: team in the input for a team’s), and the dashboard. Over MCP, agents list connections (connection_list, which names each connection’s credential), read or purge their call history (connection_audit_recent, connection_audit_purge), and call the operations declared on them, each as its own tool. They do not create connections or declare operations there.

Credentials: one key, many connections

A connection created with a secret makes its own credential, named after the connection in lowercase. To use one key in several places, create the credential once and attach it by name or id:
Over REST:
With credential, the key goes in an Authorization: Bearer header unless you set authType. Send either credential or a secret, not both (INVALID_CREDENTIAL_REFERENCE). If a credential already holds the name a secret would create, the create is refused with CREDENTIAL_NAME_TAKEN: attach that credential instead. This is also how you re-create a connection you disabled, since its credential stays. Rotate a credential with POST /v0/credentials/:credential/rotate and { "secret": "…" }: every connection using it sends the new key from its next call, and the reply lists them. A credential still used by any connection, even a disabled one, cannot be deleted (CREDENTIAL_IN_USE, listing them). On the CLI: rip credential rotate <credential> and rip credential rm <credential>.

Restricting a credential to named members

A team credential can be limited to the members who should act as it, such as the people allowed to read the team’s Google Analytics. Only the credential’s creator or the team owner can change this:
users are aliases or account ids of current team members, and the list replaces the previous one. Anyone not named, the team owner included, gets 403 CONNECTION_FORBIDDEN on every connection that uses the credential, and their agents stop seeing its operations as tools. A restricted credential with no users serves nobody. {"restricted": false} opens it to every member again and clears the list. A member who leaves the team is taken off the list, and rejoining does not put them back. Personal credentials cannot be restricted. An entry that is not a current member is refused with INVALID_CREDENTIAL_USERS, naming it.

Google Analytics and Search Console

Google wants a service account’s key traded for a token that lasts an hour. A google_service_account credential holds the key file; Tokenrip mints the token on the server, caches it, and sends it as Authorization: Bearer. Agents call the connection like any other and never see the key or the token.
1

Create the service account

In Google Cloud, create a service account in your project and enable the Google Analytics Data API and the Search Console API. Create a JSON key for the account and download it. If key creation is blocked, your organization enforces iam.managed.disableServiceAccountKeyCreation; an organization policy administrator can lift it for this one project.
2

Give the account read-only access

Add the service account’s email (…@….iam.gserviceaccount.com) as a read-only user: a Viewer on the GA4 property, and a Restricted user on the Search Console property.
3

Create the credential

Send the key file’s JSON text as secret, with the scopes the tokens need:
Or with the CLI, which sends the file’s text the same way:
Tokenrip checks that the file is a service account key with a client email and a private key that loads, and that each scope starts with https://www.googleapis.com/auth/ (1 to 20 of them). Anything else is INVALID_CREDENTIAL. Delete key.json afterwards.
4

Create the two connections

A connection on a Google credential must use bearer and an https base URL on googleapis.com, so a Google token is only ever sent to Google; anything else is INVALID_CONNECTION_FOR_CREDENTIAL.
If Google refuses the key (a deleted key, a clock that is off), the call fails with 502 TOKEN_EXCHANGE_FAILED and Google’s own error and description; nothing is sent to the API. Change the scopes with PATCH /v0/credentials/:credential and { "scopes": [...] }.
Rotating a Google credential does not revoke the old key at Google. After rotating, delete the old key on the service account in Google Cloud.

Default headers and query (defaultHeaders / defaultQuery)

A connection can carry operator-configured, non-secret defaultHeaders and defaultQuery that are merged into every request. These make providers with fixed header/query requirements — like MiniMax’s Anthropic-compatible endpoint — work without the agent restating them on each call.

Safety rails

Connections run behind several guards so a compromised or misbehaving agent can’t turn one into an open proxy:
  • Allowed paths — requests are restricted to operator-configured rules (allowedPaths). Each rule is [METHOD[|METHOD…] ]PATTERN, for example /v1/*, POST /v1beta/properties/*:runReport or GET|POST /api/**. Methods are optional and joined with |; a rule without methods allows every method. In the pattern, * matches within one path segment and ** matches across segments; everything else is literal. Rules are checked against the exact path that will be sent, percent-encoding included, so write them as sent. A connection’s rules hold at most 20 rules, 1,024 characters and 16 wildcards together. A path with a backslash, a control character, a trailing space or a ./.. segment in any encoding is refused with PATH_NOT_CANONICAL before anything is sent; a call no rule allows gets PATH_NOT_ALLOWED; a malformed rule is refused at create or update with INVALID_ALLOWED_PATH.
  • Rate limit & daily quota — per-connection request ceilings, short-window and per-day.
  • SSRF guard — outbound targets are validated to block internal/metadata addresses.
  • Audit log — every call is recorded (metadata only, never bodies) with the account that made it, and the operation’s name when it ran one. connection_audit_recent { connection, team? } reads a connection’s recent calls (by its id alone, a disabled connection’s too, or its name with team), and connection_audit_purge deletes rows older than N days (default 30). Connection lifecycle events (connection.created, connection.disabled) and credential events (credential.created, credential.rotated) also appear on the activity feed.