Add tools and connections#
An agent can use up to 16 tools, each reached through the tool gateway on its machine. This page covers the ready-made connections, signing in with OAuth, adding any MCP server or HTTP API, the web, the model provider's own search, and exposing a credential as an environment variable when nothing else will do.
Before you begin#
- The editor or admin role.
- For a tool that needs a key: a credential
of the workspace holding it. Each connection says which keys it needs
(usually
token) and how to get the token, step by step. - Tools are part of an agent version: adding one writes a new version (Create and change an agent).
Add a connection#
| Connection | Kind | Credential keys | Access levels | Sign in with |
|---|---|---|---|---|
| GitHub | MCP (GitHub's MCP server) | token |
read, write, approval | GitHub |
| GitHub (REST API) | HTTP https://api.github.com |
token |
read, write, approval | GitHub |
| Slack | HTTP https://slack.com/api |
token |
read, write, approval | Slack |
| Notion | HTTP https://api.notion.com |
token |
read, write, approval | — |
| Linear | HTTP https://api.linear.app |
token |
read, write | — |
| Jira, Confluence | HTTP https://<site>.atlassian.net |
basic (email:token) |
read, write, approval | — |
| Gmail, Google Drive, Google Calendar | HTTP (Google APIs) | client_id, client_secret, refresh_token |
read, write, approval | |
| Brave Search, Tavily, Exa | HTTP | token |
read | — |
| Sentry | HTTP https://sentry.io |
token |
read, write, approval | — |
| Stripe | MCP https://mcp.stripe.com |
token |
read, write, approval | — |
| Web browsing | web | none | read, write, approval | — |
The access levels are written as policy for you:
- Read only: the connection's reading tools or
GET/HEADrequests; - Read and write: everything the credential allows;
- Writes need approval: reading is free; each write waits for a person (see Approvals).
- In New agent (or New version), Simple mode, press Add connection and pick the service. Web browsing has its own button.
- Choose the Credential that holds its key — or New credential, following the steps shown — and the Access level.
- Repeat for each service, then save the agent.
In Advanced, the connection is a tool in Tools and its access level is rules in Tool policy, which you can edit.
A connection is a tool and a few rules. GitHub's REST API, read only:
{
"tools": [
{"name": "github", "kind": "http", "url": "https://api.github.com", "credential": "github-token",
"headers": {"Accept": "application/vnd.github+json"}}
],
"policy": {
"tools": "@id(\"github-reads\")\npermit (principal, action == Action::\"http\", resource in Server::\"github\")\nwhen { [\"GET\", \"HEAD\"].contains(resource.method) };\n"
}
}
GET $WS/agent-templates lists every connection (connectors) with
its URL, credential keys, setup steps and the policy of each level
(presets).
Sign in with Google, Slack or GitHub#
For Gmail, Google Drive, Google Calendar, Slack and GitHub, Connect with … makes the credential by signing in instead of pasting a token.
- Once, make an OAuth client of your own at the provider (a Google
Web application client, a Slack app, a GitHub OAuth app), and register
the redirect URI the dialog shows:
https://console.astralyx.cloud/api/v1/oauth/callback. - Keep its client ID and secret as a credential of the workspace with the
keys
client_idandclient_secret, in Vault (KV v2), AWS Secrets Manager, Google Secret Manager or Azure Key Vault — a store your machines may write to. - In the connection, choose Connect with Google (or Slack, GitHub), pick the OAuth client credential and the new credential's name, and sign in at the provider. You have 10 minutes.
- Back in the console, the connection shows Connected, with the scopes granted. If the token later expires or is revoked, Sign in again writes into the same credential.
The sign-in is completed on one of your machines: it holds the PKCE verifier, reads the client secret from your store, exchanges the one-time code and writes the token (for Google, a refresh token) into the same store, next to the client, marked as the connection's. It never writes over a secret it did not make. Only the one-time code passes through Astralyx — useless without the verifier and the client secret — and no token, client secret or verifier does. The agent never sees any of them.
Add any MCP server or HTTP API#
In Advanced → Tools, press Add a tool and fill in:
- Name: a DNS label, at most 32, unique in the agent — what
policies name (
Server::"<name>"). - Kind: MCP (streamable HTTP) or HTTP.
- URL: the MCP endpoint, or the API's base URL (
http://orhttps://, no user or password in it). - Credential, Key (
tokenby default), Header (AuthorizationwithBearerby default) — or OAuth refresh with a token URL. - Fixed headers that are not secret (
Notion-Version: 2026-03-11).
Then permit what it may do in Tool policy.
{
"tools": [
{"name": "fs", "kind": "mcp", "url": "http://mcp-fs.internal:8080/mcp"},
{"name": "tickets", "kind": "http", "url": "https://tickets.example.com/api",
"credential": "tickets-key", "credential_key": "key", "header": "X-Api-Key"},
{"name": "calendar", "kind": "http", "url": "https://www.googleapis.com",
"credential": "google-oauth", "auth": "oauth2-refresh", "token_url": "https://oauth2.googleapis.com/token"}
]
}
How the credential is sent:
header |
prefix |
Sent as |
|---|---|---|
| empty | empty | Authorization: Bearer <value> |
X-Api-Key |
empty | X-Api-Key: <value> |
| empty | - |
Authorization: <value> (Linear's keys) |
| empty | Basic |
Authorization: Basic <value> (an encoded email:token) |
With auth: oauth2-refresh, the credential holds client_id,
client_secret and refresh_token; the gateway exchanges them at
token_url (https://) for an access token, cached until a minute
before it expires. See Agent specification.
The tool must be reachable from your machine. Its address is not checked by Astralyx: an MCP server inside your network is fine.
Permit what the tool may do
Adding a tool permits nothing. Until a permit names it, every call is
denied with no policy permits it. For an MCP server, permit tools by
name (resource.name); tools/list shows the agent only the tools the
policy allows.
The web#
A web tool ("kind": "web", no URL, no credential) lets the agent
fetch any public page; the Assistant gets a web_fetch tool that returns
pages as text. Each request is decided like an HTTP tool's — method, host,
path, query — and recorded with its URL. Addresses inside your network,
the machine itself and the cluster are never reached, whatever the policy
says. Narrow it with Web browsing: block a domain or only a domain:
@id("web-reads-some-sites")
permit (principal, action == Action::"http", resource in Server::"web")
when { ["GET", "HEAD"].contains(resource.method) &&
(resource.host == "docs.rs" || resource.host == "crates.io" || resource.host like "*.rust-lang.org") };
The provider's own search#
Anthropic's and OpenAI's models can search and fetch the web themselves, on the provider's side. Such tools are removed from every request unless the policy permits them. In the console, tick Let the model search the web with its provider's search; it writes:
@id("model-web-search")
permit (principal, action == Action::"model/server_tool", resource)
when { ["web_search", "web_fetch"].contains(resource.tool) };
Each search is recorded with its query and the pages it returned.
A credential as an environment variable#
When a program the agent runs itself needs a key — a CLI that talks to a
service directly — expose a credential's key as an environment variable
(Advanced → Secrets as environment variables, or spec.secrets:
{"credential", "key", "env"}, at most 16).
Warning
The agent sees these values. Anything it can read it can repeat, send or leak. Prefer a connection: its credential is added by the gateway and never reaches the agent. The program also needs the sandbox policy to let it reach its host.
Variable names are capital letters, digits and _, not starting with
ASTRAEUS_ or NPM_CONFIG_, and not one the run sets itself
(OPENAI_API_KEY, ANTHROPIC_BASE_URL, HOME, PATH…).