Connect an MCP server
Connect a remote MCP server, such as your helpdesk's or your CRM's, and devboxes can call its tools for your Organization. devboxes holds the server's credentials and makes every call itself, so no task workspace or Chat ever receives them. Owners and admins connect and disconnect servers; every member can list them and call their tools.
devboxes reaches servers over HTTPS on public addresses only, and does not follow redirects.
Connect a server
Connect the MCP server at https://mcp.example.com/mcp to my devboxes Organization as Helpdesk. If it needs a sign-in, give me the link.
To do it yourself:
-
Find out how the server lets devboxes in:
detect.json { "organizationId": "<organization id>", "url": "https://mcp.example.com/mcp" }devboxes invoke integrations.detect --input @detect.jsonaccessisanonymouswhen the server needs no credentials,oauthwhen you sign in, andcredentialswhen it needs a key. Foroauth,registrationisdynamicwhen devboxes registers itself with the server's sign-in, andown-clientwhen you create an OAuth client at the provider first. -
Connect it. Give it a
namethat is unique in your Organization:connect.json { "organizationId": "<organization id>", "name": "Helpdesk", "url": "https://mcp.example.com/mcp", "auth": { "kind": "oauth" } }devboxes invoke integrations.connect --input @connect.json- For a server that needs no credentials, use
"auth": { "kind": "none" }. - For a key, use
"auth": { "kind": "headers", "headers": { "Authorization": "Bearer <key>" } }, with the header the server's documentation names. - For OAuth with your own client, add
"client": { "id": "<client id>", "secret": "<client secret>" }toauth. Registerhttps://<your devboxes API>/api/integrations/oauth/callbackas its redirect URL. catalogue.list gives this address asredirectUrlon the servers that need your own client.
With OAuth, open the returned
authorizationUrlwithin 15 minutes and sign in. Only you can finish this sign-in: when the browser is not signed in to devboxes as you, devboxes asks you to sign in first. The connection ispendinguntil you finish, and the page you land on says whether it connected. When the sign-in did not finish, for example because you declined access,integrations.listshows why in the connection'sfailure. Connecting again under the same name replaces a pending connection once the new sign-in has started. If it can't start, the pending connection and itsfailurestay. When you connect again to the same URL without aclient, devboxes signs in with the client the pending connection used. Without OAuth, devboxes reads the server's tools at once, and the connection isconnected. - For a server that needs no credentials, use
Call a tool
integrations.tools returns a connection's tools with their input schemas. integrations.refresh-tools reads them from the server again.
{
"organizationId": "<organization id>",
"connectionId": "<connection id>",
"tool": "search_tickets",
"input": { "query": "refund" }
}devboxes invoke integrations.call --input @call.jsonThe result is the server's answer: its content, and isError when the tool failed. In Chat, devboxes calls these tools when your Chat policy allows integrations.call.
devboxes refreshes an OAuth sign-in by itself. When the provider refuses the refresh, integrations.list shows the connection as reconnect: disconnect it with integrations.disconnect and connect it again.
Make a server sensitive
Mark a connection sensitive with integrations.configure-sensitivity and "integration": { "kind": "integration", "id": "<connection id>" }. Then only an owner calls its tools directly, in Chat through a chat account linked to them. See Approve work that reaches a sensitive integration.
Connect GitHub Issues
Connect the GitHub issues of the devboxes GitHub App installation and bind a repository, so that the devboxes label starts a task.
Set up Personas and memory
Create a Persona that shapes how devboxes answers, add to Organization memory, store your own preferences, correct how devboxes answers, and deactivate a Persona.