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:
| Role | What it does | Discovery endpoint |
|---|
| Authorization Server | Issues 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.
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.”
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:
-
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"
-
Client reads
resource_metadata and fetches the protected
resource metadata document to learn the authorization server URL
and supported scopes.
-
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.
-
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.
| Scope | Required for | Description |
|---|
qr:generate | generate_qr_url | Generate 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
| Token | Lifetime |
|---|
| Access token | 24 hours |
| Refresh token | 90 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:
- 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.
- 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.
- 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