Endpoints
| Step | Method | URL |
|---|---|---|
| Client lookup | GET | https://mcp.echozero.app/oauth/client |
| Authorize | GET | https://mcp.echozero.app/oauth/authorize |
| Approve (Dev Portal) | POST | https://mcp.echozero.app/oauth/authorize/approve |
| Token | POST | https://mcp.echozero.app/oauth/token |
| Introspect | POST | https://mcp.echozero.app/oauth/introspect |
| Verify status | GET | https://mcp.echozero.app/status |
PKCE parameters
| Parameter | Required | Value |
|---|---|---|
response_type | Yes | code |
client_id | Yes | Registered client id (e.g. echozero-cli) |
redirect_uri | Yes | Must match a registered redirect URI exactly |
scope | Yes | Space-delimited OAuth scopes (see below) |
state | Yes | Opaque CSRF token - validate on callback |
code_challenge | Yes | BASE64URL(SHA256(code_verifier)) |
code_challenge_method | Yes | S256 |
code_verifier (43-128 random characters) and keep it secret until token exchange.
Browser consent flow
Redirect to authorize
Send the user to
GET https://mcp.echozero.app/oauth/authorize with PKCE code_challenge, state, scope, and redirect_uri.User approves in Dev Portal
EchoZero redirects to the Dev Portal consent page. If the user is not signed in, they authenticate first, then approve the requested scopes.
Receive authorization code
EchoZero redirects back to your
redirect_uri with ?code=...&state=.... Verify state matches what you sent.Verify the token
After login, confirm the token is active:{ "active": true, "sub": "...", "client_id": "...", "scope": "...", "exp": ... } when valid.
OAuth scopes
Scopes map to API key permissions. Request only what your integration needs:| Scope | Access |
|---|---|
read:agents / write:agents | List and manage developer agents |
read:strategies / write:strategies | Strategy configuration |
read:wallet / write:wallet | Wallet balances and mode |
read:trades / trades:execute | Trade history and execution |
read:tokens | Token metadata |
read:earn | Earnings and claims |
read:analytics | Dashboard analytics |
read:ai / write:ai | AI chat and tooling |
read:notifications / write:notifications | Notification preferences |
agents:read, bots:write, etc.) are also accepted. admin:* is not available via OAuth.
Token lifetime and refresh
| Token | TTL | Notes |
|---|---|---|
| Authorization code | 5 minutes | Single use; exchanged immediately |
| Access token | 1 hour (expires_in: 3600) | No refresh_token is issued today |
offline_access or refresh grant at this time.
code_verifier requirements
43-128 characters from [A-Z], [a-z], [0-9], ., -, _, ~ (unreserved URI characters).
OAuth error responses
| Condition | HTTP | Message / behavior |
|---|---|---|
| Expired or reused code | 400 | Invalid or expired authorization code |
| PKCE mismatch | 400 | Invalid code_verifier |
Wrong redirect_uri | 400 | Redirect URI mismatch |
Invalid client_id | 400 | Unknown client |
Invalid state on callback | — | Your app should reject the callback |
MCP with OAuth
OAuth tokens work on MCP the same way as API keys:POST https://mcp.echozero.app/mcpwithAuthorization: Bearer <access_token>on every request, includinginitialize.- Save the
mcp-session-idresponse header frominitialize. - Send
mcp-session-id: <session>on subsequent MCP calls (tools/list,tools/call, SSE stream, etc.).
initialize example.
Assistant setup (coming soon)
Coming soon: The public skills pack (
EchoZeroApp/skills) and ez login CLI are not yet published. Use the PKCE flow above or API keys until the skills repo is public.Directory integrations
For ChatGPT, Claude, Gemini, and other assistant directories, use connector metadata from:/public/directory/* with authorize URL, token URL, and recommended scope lists.