Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.neus.network/llms.txt

Use this file to discover all available pages before exploring further.

NEUS MCP uses OAuth 2.0 Authorization Code with PKCE (RFC 6749 + RFC 7636) as the primary authentication flow for MCP clients. OAuth wraps the existing NEUS hosted login. The user sees the same NEUS sign-in page — OAuth provides the standard contract that MCP clients expect.

Flow overview

MCP client discovers NEUS MCP
  → GET /.well-known/oauth-protected-resource
  → GET /.well-known/oauth-authorization-server
  → GET /oauth/authorize (validates OAuth params, renders HostedLoginFlow)
  → User authenticates on NEUS (passkey/wallet)
  → /oauth/authorize continuation: backend issues auth code
  → Redirect to client callback with code
  → POST /api/v1/auth/mcp/token (exchange code for access token)
  → Client uses Bearer token on MCP requests

How /oauth/authorize works

The /oauth/authorize endpoint owns all OAuth validation and orchestrates the login flow. The frontend does not manually invent or own the OAuth callback behavior.
  1. Validates all OAuth parameters: response_type=code, client_id, redirect_uri, code_challenge_method=S256, resource=https://mcp.neus.network/mcp.
  2. If no NEUS session: stores the pending OAuth request server-side, then redirects/renders the existing HostedLoginFlow (the same passkey/wallet login used everywhere on NEUS).
  3. After login: returns to the /oauth/authorize continuation, where the backend issues a one-time authorization code bound to subjectId, client_id, redirect_uri, code_challenge, resource, and scope.
  4. Redirects to redirect_uri?code=...&state=....
The auth code is single-use and expires in 10 minutes.

Discovery

Protected resource metadata

GET https://mcp.neus.network/.well-known/oauth-protected-resource
{
  "resource": "https://mcp.neus.network/mcp",
  "authorization_servers": ["https://neus.network"],
  "scopes_supported": [
    "neus:core",
    "neus:profile",
    "neus:secrets"
  ],
  "resource_documentation": "https://docs.neus.network/mcp/overview"
}
When the MCP server receives an unauthenticated request:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://mcp.neus.network/.well-known/oauth-protected-resource"

Authorization server metadata

GET https://neus.network/.well-known/oauth-authorization-server
{
  "issuer": "https://neus.network",
  "authorization_endpoint": "https://neus.network/oauth/authorize",
  "token_endpoint": "https://neus.network/api/v1/auth/mcp/token",
  "revocation_endpoint": "https://neus.network/api/v1/auth/mcp/revoke",
  "response_types_supported": ["code"],
  "grant_types_supported": ["authorization_code", "refresh_token"],
  "code_challenge_methods_supported": ["S256"],
  "token_endpoint_auth_methods_supported": ["none"],
  "scopes_supported": [
    "neus:core",
    "neus:profile",
    "neus:secrets",
    "offline_access"
  ]
}

Authorization

GET https://neus.network/oauth/authorize
  ?response_type=code
  &client_id=neus-cli
  &redirect_uri=http://127.0.0.1:PORT/callback
  &code_challenge=BASE64URL(SHA256(code_verifier))
  &code_challenge_method=S256
  &state=RANDOM_CSRF_VALUE
  &scope=neus:core neus:profile neus:secrets offline_access
  &resource=https://mcp.neus.network/mcp
ParameterRequiredDescription
response_typeYesMust be code
client_idYesRegistered client identifier
redirect_uriYesMust exactly match a registered URI
code_challengeYesPKCE challenge (BASE64URL of SHA-256 of code_verifier)
code_challenge_methodYesMust be S256
stateYesCSRF protection — returned verbatim
scopeNoDefault: neus:core neus:profile neus:secrets offline_access
resourceYesMust be https://mcp.neus.network/mcp

Token exchange

POST https://neus.network/api/v1/auth/mcp/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
code=AUTH_CODE
redirect_uri=http://127.0.0.1:PORT/callback
client_id=neus-cli
code_verifier=ORIGINAL_CODE_VERIFIER
resource=https://mcp.neus.network/mcp
Response:
{
  "access_token": "eyJ...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "rt_...",
  "scope": "neus:core neus:profile neus:secrets"
}

Refresh tokens

POST https://neus.network/api/v1/auth/mcp/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
refresh_token=rt_...
client_id=neus-cli
resource=https://mcp.neus.network/mcp
Refresh tokens rotate on each use. Include offline_access in the initial scope to receive one.

Token claims

The MCP access token is a JWT:
ClaimValueDescription
isshttps://neus.networkToken issuer
audhttps://mcp.neus.network/mcpResource audience — MCP server validates this
subProfile subject IDUnique user identifier
diddid:pkh:...Decentralized identifier
azpClient IDClient that requested the token
scopeSpace-separatedGranted scopes
token_usemcp_accessToken type — MCP server rejects other values
iatUnix secondsIssued at
expUnix secondsExpires at
OAuth access tokens are valid only when aud is https://mcp.neus.network/mcp, iss is https://neus.network, token_use is mcp_access, and the token is not expired or revoked.

Scope model

ScopeDescriptionDefault
neus:corePublic protocol toolsYes
neus:profileSigned-in profile via neus_meYes
neus:secretsPortable encrypted secretsYes
offline_accessRefresh tokenYes

Revocation

POST https://neus.network/api/v1/auth/mcp/revoke
Content-Type: application/x-www-form-urlencoded

token=eyJ...
token_type_hint=access_token
client_id=neus-cli
Revoking an access token also invalidates all associated refresh tokens.

Compatibility

The existing /verify?intent=mcp flow remains as a compatibility alias. New integrations should use the standard OAuth endpoints.

Registered clients

client_idUse
neus-cliNEUS SDK CLI (neus auth) — loopback redirect on 127.0.0.1
Hosted MCP clients (Cursor, VS Code, Claude Code, OpenAI) should use URL-only config when possible and let the host run OAuth discovery from /.well-known/mcp.json.

Security properties

PropertyEnforcement
PKCE requiredcode_challenge_method=S256 is mandatory
Exact redirect_uri matchPrevents open redirect attacks
State parameter preservedCSRF protection
Resource indicator requiredPrevents token misuse across services
Token audience validatedMCP tokens cannot be used for other NEUS services
Refresh token rotationOld refresh token invalidated on each use
Tokens never in query stringsBearer header only
Single-use auth codesCode invalidated after first exchange
Access key fallbackFor servers and automation where browser is unavailable

Auth

Keys and headers.

Setup

Install and configure.

Endpoints

Discovery URLs.