Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.closient.com/llms.txt

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

The Closient MCP server is an OAuth 2.1 resource server, classified per RFC 9728 (Protected Resource Metadata) and the MCP Authorization spec. Most tools are public — no token, no setup, frictionless adoption for AI agents discovering Closient through tools/list. A single tool today (generate_qr_url) is gated behind a scoped OAuth token because it touches the paid QR-generation pipeline. The pattern is extensible: future protected tools join the same step-up flow.

Two roles, two endpoints

Closient acts as both authorization server and resource server in this stack:
RoleWhat it doesDiscovery endpoint
Authorization ServerIssues and validates OAuth tokens, hosts the consent screen, manages refresh./.well-known/oauth-authorization-server
Resource Server (MCP)Validates the bearer token, enforces scopes, dispatches the tool call./.well-known/oauth-protected-resource
The two discovery endpoints conform to RFC 8414 (authorization server metadata) and RFC 9728 (protected resource metadata) respectively. Compliant MCP clients fetch them automatically — you do not need to configure URLs by hand.

Public tools — no token

These tools accept anonymous calls. No header, no setup:
  • ping
  • validate_gtin
  • resolve_gtin
  • lookup_product
  • search_products
  • get_product_detail
  • compare_products
  • check_availability
If you pass a valid token alongside one of these calls, Closient records the authenticated principal in the audit log (see MCP Identity Propagation) but the call behaves identically. This is forward-compat plumbing for future features like “authenticated tier: higher rate limit.”

Protected tools — step-up flow

generate_qr_url requires a bearer token with the qr:generate scope. The step-up flow is what makes the user experience smooth: the client doesn’t have to authenticate up front, only when it actually tries to use a protected tool. Step by step:
  1. First call without a token. The MCP client calls the tool anonymously. Closient returns 403 Forbidden with this header:
    WWW-Authenticate: Bearer error="insufficient_scope" scope="qr:generate"
        resource_metadata="https://www.closient.com/.well-known/oauth-protected-resource"
    
  2. Client reads resource_metadata and fetches the protected resource metadata document to learn the authorization server URL and supported scopes.
  3. Authorization flow. The client opens the consent screen in the user’s browser (using PKCE per the OAuth 2.1 spec), the user approves, and the client exchanges the authorization code for an access token + refresh token.
  4. Retry with the token. The client retries tools/call generate_qr_url with Authorization: Bearer <token>. Closient validates the token, confirms the qr:generate scope, and dispatches the call.
The whole flow happens transparently in Tier 1 MCP clients (Claude Desktop, Cursor, VS Code) — the user sees a single consent prompt and then the tool just works.

Scopes

Closient currently exposes one MCP-specific scope. Future protected tools will register additional scopes following the same domain:action convention.
ScopeRequired forDescription
qr:generategenerate_qr_urlGenerate GS1 Digital Link URLs for QR/Data Matrix encoding. Counts against the user’s QR quota.
REST-API scopes (accounts:read, products:read, etc.) are independent of MCP. They authenticate REST-API calls; they do not unlock additional MCP tools.

Token lifetimes

TokenLifetime
Access token24 hours
Refresh token90 days
When an access token expires, the MCP client uses the refresh token to mint a new one without prompting the user. Expired refresh tokens require the user to consent again.

Client registration

The MCP spec (Nov 2025 revision) supports three registration paths. All work against Closient:
  1. Client ID Metadata Documents (CIMD) — preferred. The client advertises its metadata at a public URL; Closient fetches it on first contact. No upfront registration required.
  2. Dynamic Client Registration (RFC 7591) — the client POSTs to the authorization server’s /register endpoint and receives a client_id + client_secret. Useful for clients that want a stable identity but don’t have a public metadata URL.
  3. Pre-registration — for known clients like Claude Desktop and VS Code, Closient maintains pre-registered application records. No action on your part; the client uses its built-in client_id.
Tier 1 MCP clients pick the right registration path automatically.

Manual token minting

For local development, scripted integrations, or MCP clients that don’t implement the OAuth flow, you can mint a token by hand:
# 1. Register a client (one-time)
curl -X POST https://www.closient.com/o/register/ \
  -H 'Content-Type: application/json' \
  -d '{
    "client_name": "my-mcp-test-client",
    "redirect_uris": ["http://localhost:8765/callback"],
    "grant_types": ["authorization_code", "refresh_token"],
    "scope": "qr:generate"
  }'

# 2. Send the user through the consent flow
open "https://www.closient.com/o/authorize/?response_type=code&client_id=<CLIENT_ID>\
&redirect_uri=http://localhost:8765/callback&scope=qr:generate&code_challenge=<PKCE>&code_challenge_method=S256"

# 3. Exchange the resulting code for an access token
curl -X POST https://www.closient.com/o/token/ \
  -d 'grant_type=authorization_code' \
  -d 'code=<AUTH_CODE>' \
  -d 'redirect_uri=http://localhost:8765/callback' \
  -d 'client_id=<CLIENT_ID>' \
  -d 'code_verifier=<PKCE_VERIFIER>'
Then call the protected tool with Authorization: Bearer <access_token>.

Verifying scope coverage

A quick way to sanity-check that a token has the right scope before calling a protected tool:
curl -sS https://www.closient.com/mcp/http \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Accept: application/json, text/event-stream' \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"generate_qr_url","arguments":{"gtin":"00614141123452"}}}'
A successful response confirms the token holds qr:generate. A 403 with error="insufficient_scope" means the token is valid but missing the scope — re-run the consent flow and accept the qr:generate request.

Audit & identity

Every tool call (public or protected) emits one structured closient.mcp.audit log line with the agent’s client_id and (for authorization_code tokens) the consenting end user. See MCP Identity Propagation for the full audit schema and the get_current_end_user() accessor for tool authors. For protected tools, @user_action on the underlying service-layer function (e.g. apps.products.services.qr_url.build_digital_link_url) also records a durable database audit row — the answer to “who generated this QR code?” is queryable forever from the audit_events table.

See also