Connect accounts
Define an OAuth provider, and set an MCP server's credential to its name:
base_url: https://agents.example.com
oauth: providers: github: issuer: https://github.com/login/oauth resource: https://api.githubcopilot.com/mcp/ client_id: ${GITHUB_CLIENT_ID} client_secret: ${GITHUB_CLIENT_SECRET} scopes: [repo] flow: device
mcp: github: url: https://api.githubcopilot.com/mcp/ credential: githubRestart the daemon, then connect your account:
wardrik connection connect githubSign in to github at https://github.com/login/device with the code BCDF-GHJKConnected github.- An agent calls the server with its owner's account.
flow: deviceprints a code to enter at the provider. The command exits when the sign-in is granted, declined or expired.- Without
flow: device, it prints a link. Sign in, then enter the code the page shows, or runwardrik connection pair github CODE. - A code is single-use, valid for 10 minutes, and only for the user who started the sign-in.
Your accounts
Section titled “Your accounts”wardrik connection ls # available providers, and your connectionswardrik connection disconnect github # delete it; the next call prompts againEach command runs as the token's user. Users manage only their own accounts.
Calls before connecting
Section titled “Calls before connecting”If an agent calls the server before its owner connects, the call pauses. The sign-in link is never added to the conversation or a notice. Get it from:
- the notice's Show link button in Slack, visible only to the user who clicks it;
GET /v1/agents/{agent}/interrupts/{interrupt}/authorization, as{"url": ..., "code": ...}.
Once the account is connected, the call resumes.
OAuth apps added at runtime
Section titled “OAuth apps added at runtime”An org or user can add their own OAuth app while the daemon runs:
echo "$LINEAR_SECRET" | wardrik vault put LINEAR_SECRET --org acme --for client_secretwardrik provider add linear --org acme \ --issuer https://linear.app --client-id abc123 --secret LINEAR_SECRET --scope readwardrik provider ls --org acmeFor a provider name, the first match is used: the user's app, the org's, then config.yaml's.
Over HTTP
Section titled “Over HTTP”curl -s -H "authorization: Bearer $TOKEN" http://127.0.0.1:4747/v1/connections# {"connections": [{"provider": "github", "connected": false, "signing_in": false}]}
curl -s -X POST -H "authorization: Bearer $TOKEN" http://127.0.0.1:4747/v1/connections/github# {"provider": "github", "connected": false, "authorization": {"url": "https://…", "code": "BCDF-GHJK"}}signing_inistruewhile a sign-in you started is in progress.POST /v1/connections/{provider}/paircompletes a browser sign-in with its code.DELETE /v1/connections/{provider}deletes the connection.- Apps added at runtime are at
/v1/owners/{owner}/providers. See the HTTP API reference.
Details
Section titled “Details”- Browser sign-ins redirect to
{base_url}/oauth/callback. Register that URL with the provider. See A public address. - A provider needs an
issuer, aresource, or bothauthorization_endpointandtoken_endpoint. Every key is inconfig.yaml› oauth. - Without a
client_id, the daemon registers a client with the provider on the first sign-in. - An HTTP server receives the token as
authorization: Bearer <token>. A command server receives it in the environment variable named bycredential_env. - Tokens are refreshed on expiry. If a refresh fails, the user is prompted to connect again.
- Connections are stored in the vault.