Skip to content
Tarn & Timber Docs
Esc
↑↓navigate↵open⌘Jpreview
On this page

Connect an MCP client

Connect an AI assistant with user consent and tool-specific permissions.

Add your deployment’s MCP resource origin as a Streamable HTTP MCP server in Claude, ChatGPT, Cursor or VS Code. For the existing personal deployment that origin is https://mcp.tarnandtimber.com; it is an example, not a shared production service. When hosting your own shop, use the origin you set as shop_mcp_origin (setup). Keep that canonical identifier exact, without a trailing slash.

The server’s 401 challenge points to protected-resource metadata, and that metadata lists the authorization servers to use: the shop’s sign-in service (auth.issuer, for Poppy agents) and the Auth0 tenant (the same issuer when both share the login domain). The authorization server metadata at that issuer advertises Dynamic Client Registration (registration_endpoint), Client ID Metadata Documents (client_id_metadata_document_supported), PKCE S256 and the resource parameter. The server accepts two kinds of token, both issued for this exact URL; a token for the Shop API is refused.

Standard MCP clients connect the usual way and need no Poppy support:

  1. Dynamic Client Registration: the client reads the metadata, registers at registration_endpoint, then runs the authorization code flow with PKCE and resource set to the server URL.
  2. Client ID Metadata Documents: the client uses the URL of its metadata document as client_id. A tenant admin registers each such client once (Auth0 “manual CIMD”), so a new client works after that registration.

Either way you sign in and consent to the client and its permissions, and the client gets a plain OAuth access token with no Poppy Session. The server calls the shop on your behalf with the tool’s own scopes, and refusals name the OAuth scope (for example orders:write). Registered clients are third-party clients that reach only these MCP resources, with agent scopes only.

Poppy agents sign in at the shop’s sign-in service and get a Session-backed token. Its permissions are the ones the token carries that the live Session still grants, and refusals name the account scope (poppy:read, poppy:write or checkout).

Signed-in calls use your account cart; a signed-out Poppy Session has its own cart. The assistant cannot add or change saved cards, manage sign-in security, delete your account, or use backoffice operations. Confirm your cart, shipping address and total before letting it check out using a saved card.

Tools OAuth scope Poppy scope
searchProducts, getProduct, listCollections catalog:read none
getCart cart:read none
addCartItem, updateCartItem, removeCartItem cart:write none
checkoutSavedCard checkout checkout
getProfile, listAddresses account:read poppy:read
addAddress, deleteAddress account:write poppy:write
listPaymentMethods payment_methods:read poppy:read
listOrders, getOrder orders:read poppy:read
cancelOrder, requestReturn orders:write poppy:write

There is no request idempotency: every call to a tool such as checkoutSavedCard acts, and an idempotency_key argument is ignored. Before retrying a call that may have timed out, read the orders (listOrders) to see whether it already went through.

If a call gets insufficient_scope, authorize the named scopes: a Poppy Session is told the account scope it needs (poppy:read, poppy:write or checkout) and a signed-out Session gets sign_in_required; a standard client is told the OAuth scope above. If it gets invalid_token, sign in again. A 503 with Retry-After: 5 means authorization infrastructure is unavailable; retry later. An API business error appears in the tool’s reply with its stable code.

See the request flow, token exchange, and shop proxies.

Was this page helpful?