Documentation
Put your parts catalog inside ChatGPT — and Claude, Cursor, and any other MCP client — with one server.
Overview
theNasty is a ChatGPT app for parts commerce, built on the Model Context Protocol. Inside the conversation, the model surfaces fitment-matched parts across your wired-in suppliers, prices them into a quote, and checks the user out — no storefront to leave the chat for. The same server works in any MCP client.
Payment settles on a Stripe-hosted page and is confirmed by a verified webhook. All amounts on this page are integer cents (e.g. 4899 is $48.99).
Quickstart
In ChatGPT or Claude, add theNasty from the app / connector directory and sign in when prompted — no key needed. From Claude Code or another MCP client, point it at the server URL and it will run the same sign-in flow:
Or skip the browser sign-in by passing an API key as a bearer token:
Claude now has three tools — search_parts, price_quote, checkout — and the garage://me resource.
Every tool result comes back as the MCP content envelope { content: [{ type: "text", text: "<JSON>" }] }. The examples below show the parsed JSON from inside that text field.
Authentication
The server is an OAuth 2.1 protected resource. An unauthenticated request to /mcp returns 401 with a WWW-Authenticate header pointing at /.well-known/oauth-protected-resource/mcp. From there clients discover the authorization server (/.well-known/oauth-authorization-server), register themselves dynamically, and send the user through sign-in with PKCE (S256). Access tokens last one hour; refresh tokens rotate on every use and last 30 days.
API keys (Authorization: Bearer nasty_…) still work for scripts and CLI clients. Keys and tokens are stored hashed, are revocable, and scope every call to one user and garage. A missing, expired, or revoked credential returns 401.
Self-serve key management ships with the dashboard. During the public beta, request a key at partners@thenasty.ai.
search_parts
Find parts across wired-in suppliers, ranked by fitment, and flagged against the caller's garage.
Ordering reflects fitment ranking — the closest match leads. The gear lube is flagged inGarage: true because the caller already owns it.
price_quote
Price a set of parts: subtotal, free 2-day shipping, tax, and total — all server-computed.
checkout
Create an order and get a Stripe-hosted Checkout link. Ship-to comes from the authenticated user's saved address. The order is marked paid only by the verified checkout.session.completed webhook — never by the client.
garage://me
garage://meis an MCP resource — not a tool. Read it to get the caller's owned parts and recent orders, so the model knows what's already on the shelf and won't re-sell parts the user already has.
Errors & guarantees
- 401 — a missing, invalid, or revoked key is rejected.
- Unknown SKU —
price_quoteandcheckouterror and list the bad SKUs rather than silently dropping them. - Out of stock — surfaced in
search_partsand blocked atcheckout. - Idempotent — replaying a paid webhook is a no-op: no double charge and no duplicate garage rows.
- Server-authoritative pricing — amounts are always recomputed from the catalog; the caller never sets prices, and all money is integer cents.
Example conversation
- The user describes a repair — “my impeller's shot on my '87 Mercruiser 3.0 Alpha One.”
- Claude calls
search_parts. The gear lube comes back flaggedinGarage, so it's skipped — the user already has it. - Claude calls
price_quoteon the parts it needs: subtotal, free shipping, and tax come back to a $77.11 total. - Claude calls
checkout, which returns a Stripe-hosted link. - The user pays. The webhook confirms the order, Claude shows the confirmation, and the purchased parts are added to the garage.