Integrations
Integrations let the agent call your other systems during a mission — a CRM, a ticketing tool, an internal API — not just operate the app's UI. You connect a REST API or an MCP server to a project, and each endpoint or MCP tool becomes a tool the agent can call.
Calls run on the Appilots server, never in the user's app, so credentials don't leave the server and the model never sees them.
In production, the agent can only call an integration tool when your backend has authorized that exact call for the current user. Connecting an integration is not enough on its own. See Authorizing calls per user.
Add an integration
In the dashboard, open the project and go to Integrations → Add integration.
| Field | Description |
|---|---|
| Name | Shown in the dashboard, and used as the prefix of every tool name (CRM + create_lead → crm_create_lead). |
| Type | REST API or MCP Server. |
| Base URL | https:// origin of the API, or the MCP server's endpoint. Private and internal addresses are rejected. |
| Description | What the integration is for. |
| Authentication | REST only: None or Bearer token. MCP servers must not require authentication. |
Validate URL only checks that the URL is acceptable. It doesn't prove the server is up or that the token works. Those are tested by the first real call (REST) or by Connect (MCP).
REST APIs
- Bearer token — stored encrypted on the server and sent as
Authorization: Bearer <token>. Paste it without theBearerprefix. To rotate it, edit the integration and paste the new one. - Headers — free name/value pairs sent on every call, for example
X-TenantorAccept. Header values are stored in the integration's configuration and are visible to project members, so put secrets only in the token field. The token overrides any manualAuthorizationheader. To controlAuthorizationyourself, choose None and set the header. - Request bodies are always JSON.
Then add one tool per endpoint you want the agent to use:
| Field | Description |
|---|---|
| Tool name | Lowercase, digits, and _, for example create_issue. It can't shadow a built-in agent tool such as navigate. |
| Description | What the tool does and when to use it. The model decides whether to call it from this text alone, so be specific. |
| HTTP method | GET, POST, PUT, PATCH, or DELETE. |
| Path | Relative to the base URL, for example /v1/issues. It can't point at another origin. |
Calls with POST, PUT, PATCH, or DELETE count as writes. A write only counts as done when every external call in that step succeeded, so the agent can't report a save that failed.
MCP servers
After creating the integration, press Connect. Appilots connects over Streamable HTTP (falling back to SSE), discovers the server's tools, and enables them. Turn individual tools off in the list. Rediscover tools refreshes the list; tools the server no longer offers are disabled.
Only MCP servers without authentication are supported for now.
Authorizing calls per user
A shared SDK key can't prove who's using the app, so Appilots never lets the model decide on its own to call your systems. Every call needs a grant: an exact tool and exact arguments that your backend approved for the signed-in user.
-
Your backend checks its own login session and what this user is allowed to do.
-
It requests an end-user token from Appilots with a publish key, listing the grants:
// Server only.const res = await fetch('https://api.appilots.com/api/v1/cli/end-user-token', {method: 'POST',headers: {Authorization: `Bearer ${process.env.APPILOTS_PUBLISH_KEY}`,'Content-Type': 'application/json',},body: JSON.stringify({userId: user.id,integrationGrants: [{ toolId: 'itool_...', arguments: { customerId: user.customerId } }],}),});const { data } = await res.json(); // { token, expiresIn: 300 } -
Your app passes that token to the SDK through
getUserToken(see Sessions & users and Authentication).
The rules:
- Only granted tools are offered to the model. A tool with no grant for this user isn't visible to the agent at all.
- Arguments must match exactly. The call's full argument object must be identical to a granted one. A missing or extra field, or another customer's id, is refused. There are no wildcards.
- Grants last as long as the token: five minutes. Within that time a grant can be used more than once, so protect non-repeatable writes with idempotency on your side.
- Grant only what the user may see in full. The tool's whole response goes to the model. An unfiltered list endpoint isn't safe just because its arguments are empty.
- Up to 16 grants per token.
The arguments are the tool's declared parameters, as one flat object. For a tool with no parameters, grant "arguments": {}.
Limits
| Limit | Value |
|---|---|
| Request timeout | 10 s |
| Response size passed to the agent | 100 KB (the rest is cut off) |
| Redirects | Never followed to another origin |
| MCP connections per workspace | 10 |
Each call's status, latency, and error are recorded and shown on the integration as its last error and last use. Request and response bodies are not stored.
Current limitations
- Tool parameters can't be edited in the dashboard yet. Tools created in the form have no parameters, so they suit fixed endpoints like
GET /v1/status. MCP tools bring their parameters from the server. - The tool id (
itool_…) needed for grants isn't shown in the dashboard yet. - No OAuth2, Basic auth, or API keys in the query string. REST supports a Bearer token or manual headers only. MCP supports servers without authentication only.
Related pages
- Authentication — key scopes and the end-user token
- Security best practices
- AI per app — who serves the model that calls these tools