Skip to Content
Trading APIOAuth for AI assistants
View as Markdown

OAuth for AI assistants

This page is for developers building an MCP client. To connect an assistant you already use, see Trade from an AI assistant (MCP).

The Neurobot MCP server follows the MCP authorization specification : OAuth 2.1 with PKCE, dynamic client registration and resource indicators. A client that implements it connects without any Neurobot-specific code.

Authorization server (issuer)Protected resource
https://api.neurotrading.iohttps://api.neurotrading.io/mcp

Discovery

A request to /mcp without a token answers 401 with a WWW-Authenticate header that points at the protected resource metadata:

HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer realm="neurobot", resource_metadata="https://api.neurotrading.io/.well-known/oauth-protected-resource/mcp"
DocumentURL
Protected resource metadata (RFC 9728)/.well-known/oauth-protected-resource/mcp (also served at /.well-known/oauth-protected-resource)
Authorization server metadata (RFC 8414)/.well-known/oauth-authorization-server

The authorization server metadata lists the endpoints, all on the issuer’s origin:

EndpointPath
Authorization/authorize
Token/token
Dynamic client registration (RFC 7591)/register
Revocation (RFC 7009)/revoke

The flow

  1. Register the client: POST /register with your client_name and redirect_uris. Public clients send "token_endpoint_auth_method": "none"; confidential clients get a client_secret and may send it in the body (client_secret_post) or as HTTP Basic (client_secret_basic). Redirect URIs must be https, http on localhost / 127.0.0.1 (any port), or your app’s own scheme such as cursor://…. Show a real client_name: it’s what the user sees.
  2. Authorize: send the user’s browser to /authorize with response_type=code, client_id, redirect_uri, state, a PKCE code_challenge with code_challenge_method=S256, and resource=https://api.neurotrading.io/mcp. Neurobot opens its consent screen on the web dashboard, where the user signs in, chooses Paper Trading only or live trading, and allows or denies.
  3. Callback: the browser comes back to your redirect_uri with code, your state and iss (the issuer). A denial comes back with error=access_denied. The user has 10 minutes to answer; the code is good for 5 minutes and one exchange.
  4. Exchange the code at /token (grant_type=authorization_code, code, code_verifier, client_id, redirect_uri, resource).
  5. Call /mcp with Authorization: Bearer <access_token>.
  6. Refresh at /token with grant_type=refresh_token. Every refresh returns a new refresh token and spends the old one, so store the new one.
{ "access_token": "nmcp_at_…", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "nmcp_rt_…", "scope": "trading:paper" }

Scopes

The user picks the access level on the consent screen; the token’s scope says which one they chose.

ScopeMeaning
trading:paperPaper Trading only. Every wallet, balance and trade the connection sees is Paper Trading, whatever mode the account is in elsewhere, and it can’t switch the account’s mode.
trading:liveActs in the account’s current mode, real funds included.

Request trading:paper trading:live (or no scope) to let the user choose. Request trading:paper alone and the consent screen offers Paper Trading only. A refresh can’t widen the scope: to change it, the user connects again.

Tokens

  • Access tokens last 1 hour and are good for /mcp only. They aren’t API session tokens, and the REST API refuses them.
  • Refresh tokens last 30 days from their last use.
  • A 401 with error="invalid_token" from /mcp means the token expired or the connection was ended: refresh, or send the user through the flow again.
  • POST /revoke with either token ends the whole connection. The user can also end it from Settings → AI connections on the dashboard.

The token endpoint, registration and revocation accept requests from any origin (CORS), so a browser-based client works too. /mcp never accepts the dashboard’s session cookie, only the Authorization header.