# BoxFetch BoxFetch is an agent-first marketplace where AI agents discover and buy agent-readable assets and media on behalf of a human. Purchases settle in internal BoxFetch credits through the native BoxFetch wallet rail. Credits are spend-only, not cash, and not buyer-redeemable. A human BoxFetch account holds the credits, funds them through Stripe Checkout, and sets the approval and spend policy that governs what an agent may buy. ## For AI agents - You can read this file, the discovery documents, the public marketplace showcase, public search, and public item detail without an account or token. - You cannot preview, quote, or purchase without a credential, and a credential only exists after a HUMAN claims you. You cannot claim yourself. - You CAN start that yourself: register a provisional identity, then show your human the claim link you get back (see "Cold start" below). - Tell your user plainly: purchases are governed by their approval policy, and a purchase pauses for their explicit approval. - Never ask your human for a password, an OAuth code, an email verification code, a payment credential, a provider secret, or a session cookie. BoxFetch never needs you to relay any of those. ## Cold start (no BoxFetch credential — start here) 1. POST /api/mcp/public - MCP Streamable HTTP handshake with NO credential. Tools: boxfetch_discover, boxfetch_search_public, boxfetch_get_public_item, boxfetch_register_agent, boxfetch_check_claim_status. Nothing on this endpoint can spend, read entitled content, or touch a human account. If you prefer plain HTTP, the same rail is steps 2-5 below. 2. GET /api/public/agentic/search?q=... - anonymous buyer-visible inventory. 3. GET /api/public/agentic/items/{assetId} - public-safe detail for one listing. 4. POST /api/public/agentic/agents/register - create a PROVISIONAL agent identity. You receive THREE separate values: - claimRequestId: PUBLIC. It is the only claim value that appears in the claim URL. Safe to show, log, and pass through a login round trip. - claimPollSecret: SECRET. Yours alone. Send it only in a POST body. Never put it in a URL, never show it to your human, never write it down anywhere someone else reads. - claimCode: a short human-readable fallback for the claim page. Show your human the claim URL. It contains no secret. 5. POST /api/public/agentic/agents/claim-status - poll with claimPollSecret in the request BODY. While pending you get "pending"; once your human confirms you get "claimed". This endpoint NEVER returns a credential in any state. 6. POST /api/mcp/standard with NO credential. The 401 carries a WWW-Authenticate challenge naming /.well-known/oauth-protected-resource/api/mcp/standard. Your MCP client follows that to the authorization server metadata, registers itself, and runs the ordinary OAuth 2.1 authorization-code + PKCE flow. Your human approves the agent and the scopes in a browser; your client receives the access token at the token endpoint. Nothing hands you a credential as tool output. ## Account and onboarding (route your human here) - /claim/agent - where your human confirms your claim (registration returns the exact per-claim URL; do not construct it yourself) - /signup - create a BoxFetch account - /login - sign in to an existing account - /boxfetch/join - first-50 launch access (buyer, seller, or both) - /boxfetch/agent-setup - set agent permissions, budgets, and purchase controls - Start the protected connection from the MCP client. The client follows OAuth discovery, dynamic registration, human consent, PKCE token exchange, and MCP session initialization; the human never copies the OAuth access token. - Account -> BoxFetch / Account -> Agentic - revoke grants or agents, set spend limits and approval policy, and approve controlled-beta purchases. Pre-issued bearer management is an operator/development fallback, not public onboarding. ## Public pages - /mcp - overview of the MCP surface and the agent flow - /mcp/guide - setup guide for connecting an MCP-capable client - /marketplace - public showcase of approved + listed assets ## Public machine-readable discovery - /.well-known/boxfetch-mcp - discovery document (JSON) - /.well-known/oauth-protected-resource/api/mcp/standard - RFC 9728 protected-resource metadata (JSON) - /.well-known/oauth-authorization-server - RFC 8414 authorization-server metadata (JSON) - /api/public/mcp/manifest - MCP connector manifest with tool schemas (JSON) - /api/public/openapi - OpenAPI 3.1 contract for the public agent-facing routes (JSON) ## Agent-facing endpoints - POST /api/mcp/public - UNAUTHENTICATED MCP Streamable HTTP bootstrap. initialize, notifications/*, tools/list, tools/call over the five public tools above. Nothing that spends or reads entitled content is reachable. - POST /api/mcp/external - existing custom HTTP tool API. Primary shape: { "toolName": "search_assets", ...input }. Also supports { "tool": "search_assets", "input": {} }. - POST /api/mcp/standard - MCP Streamable HTTP JSON-RPC endpoint, bearer required. Supports initialize, notifications/*, tools/list, and tools/call. initialize returns Mcp-Session-Id, notifications/initialized activates it, DELETE releases it, and GET returns 405 because no server-initiated SSE stream exists; Origin is validated on every method. Protocol revisions honored: 2025-11-25 and 2025-06-18 — negotiated at initialize, not assumed. 2025-03-26 is NOT offered: that revision requires JSON-RPC batch reception, which this transport does not implement. Authorization is standard MCP OAuth 2.1: RFC 9728 protected-resource metadata, RFC 8414 authorization-server metadata, RFC 7591 dynamic client registration, authorization code with mandatory PKCE (S256), and RFC 8707 resource binding. Tokens are scoped, agent-bound, expiring, refreshable, and revocable. A manually configured bearer header remains available as an explicitly labelled operator/development fallback, not the supported connector path. ## Tools exposed over MCP (OAuth access token required; scope-gated) - search_assets - list approved + listed assets - preview_asset - buyer-safe preview, no full content (explicit assetId) - quote_asset - short-lived dynamic price quote (explicit assetId) - purchase_asset - settle internal BoxFetch credits against a fresh quote; requires Idempotency-Key - get_purchase_approval - poll a human approval request - get_asset_content - retrieve entitled native content after capture (descriptor-only for R2) - submit_usage_feedback - record validated feedback for a captured purchase - get_agent_budget - read the calling agent's credit budget snapshot; requires the separate boxfetch:budget scope, which is NOT in the default read set, because it exposes wallet balance, recent spend, and the owner's configured spending and approval limits - boxfetch_media_quote / boxfetch_media_purchase / boxfetch_media_access - explicit mediaAssetId only; internal credits only; no playback/download/provider data ## Status - Internal BoxFetch credits only. Buyers fund credits through Stripe Checkout (test or live per environment). Seller external payout and buyer cash-out are not live. - BoxFetch is NOT a listed or official connector inside Claude or ChatGPT today. Manual configuration of the MCP endpoint with a user-generated bearer token is required. - No public media discovery over MCP. Media and native R2 delivery never expose provider URLs, signed URLs, object keys, storage paths, or raw bytes. - This file and the discovery documents linked above are public-safe and contain no tokens, secrets, or user identifiers.