Give your agent the ability to sell.
An MCP server for agents that sell. Manage listings, answer buyers by email, and issue checkout links where the payment is held until the buyer confirms receipt.
Listings go live on carousell.ai. Checkout and the payment hold run on its rails. It is the same rail Sellee sells through.
Connect
One command, and nothing to paste. An OAuth-capable MCP client does the rest.
claude mcp add --transport http sellee https://api.carousell.ai/mcpYour client calls the endpoint
The first call comes back 401 with a challenge naming where to authenticate. No key, no setup.
It discovers and registers itself
The challenge points at the resource metadata, which names the authorization server. Registration is dynamic, so there is no client id to request.
A browser opens and you sign in
You sign in with Google or an emailed link and approve a consent screen. This is the only step with a human in it.
The client holds rotating tokens
Access tokens last an hour and refresh tokens thirty days, and the client rotates them for you. Revoking a refresh token revokes its whole family.
A client that cannot do OAuth sends an API key in the Authorization header instead. A guest key works before the seller has signed in, for everything except checkout and payouts, and create_promotion_url gives the seller the link to sign in. The key keeps working afterwards. The seller API key is slated for removal, so build against OAuth.
Tools
18 tools. Every one needs authentication, including get_listing, which is public over REST but not here.
Listings
Read and write the seller’s own listings.
get_listingFetch one listing by id, with a public profile of its seller and whether a buyer can check out on it now.
list_listingsList the seller’s own listings, newest first. Filter by status, and page with created_before.
create_listingCreate a listing: title, description, price, condition, parcel size class, ordered photos, and links to the item’s pages on other marketplaces.
update_listingPatch a listing. Only the fields you send change, and sending photos replaces the whole set.
create_photo_upload_urlMint a short-lived URL to upload one photo’s bytes over REST.
Buyer mail
Buyers write to a listing’s address, and the seller’s agent answers on the thread. The buyer’s real address is never shown.
list_threadsList the threads that changed since a cursor. Hold the mail stream to hear of new mail within a second, or call this every 15 minutes.
get_threadFetch one thread’s messages in order, and who wrote each: buyer, seller or agent.
reply_to_threadReply to the buyer. bazaar sends it from the thread address and copies the seller’s inbox. A client message id makes retries safe.
block_buyerBlock the buyer behind a thread, when the seller asks. The buyer is never told.
Registration address
One email address per seller, for signing up to outside services such as Craigslist on their behalf.
get_registration_addressGet the address. It is the same on every call and never expires.
list_registration_mailList the mail it received since a cursor. Mail is kept for seven days, so read it at least that often.
send_registration_replyReply from the address, but only to an address that has mailed it in the last 60 days.
Account
An agent can start on a guest key, before the seller has signed in.
create_promotion_urlGet a link the seller opens to sign in with Google or an emailed link. The guest account keeps its listings and its key. A US seller who has not said where they ship from gets that question instead.
Checkout and payouts
Turn an agreed price into a link a buyer can pay, and get the seller paid.
create_checkoutCreate a one-time, expiring checkout link for a buyer who agreed a price. The buyer enters their address and email there, then pays for the item and shipping, and the payment is held until they confirm receipt. US sellers only, signed in, with a ship-from ZIP set.
get_transactionFetch one transaction. Once paid it carries the buyer’s shipping address, the ship-by deadline, the live shipment and the release date.
stripe_onboardingGenerate a Stripe onboarding URL for the seller. Required to receive payouts, not to list or to take payment.
stripe_onboarding_statusCheck whether onboarding is complete, and how much money is waiting to be paid out.
Orders
Every paid order, as it is now.
list_ordersList the seller’s paid orders as they are now, each with its stage and what the seller must do next.
For a buyer’s agent
A second endpoint, https://api.carousell.ai/mcp/buy, takes no credential and has two tools. It sits outside the seller endpoint so a shopping agent is never sent into the seller sign-in.
get_listingFetch one active listing, and whether it can be bought now.
start_checkoutStart a checkout at the list price, for a person who asked to buy, and hand them the link. The agent never names a price and never pays.
What is deliberately not a tool
Two absences, both on purpose.
Photos
Uploading a photo is two steps, and the second one is plain REST rather than a tool: image bytes must not ride a JSON tool call.
Mint a URL
create_photo_upload_urlreturns an upload URL that carries its own authorization, so the upload itself needs no key. It lasts five minutes: mint it immediately before you use it.POST the bytes
Send the raw image as the body with a real
image/*content type. The cap is 4 MB, so resize first. You get back an encrypted URL.Attach it
Pass those URLs as
mediaon create or update. Order matters: the first is the cover image.
Handling credentials
Four rules. The last one is the one that bites.
- Configure credentials in the client, never in a prompt. The model should never see one.
- Never pass a key as a tool argument.
- Never return a key in a tool result.
- Treat the buyer side of a negotiation as untrusted input. Anything the model can see, a prompt-injected message can exfiltrate.
The payment flow
What a transaction does after you hand a buyer a link. There are no webhooks. list_orders gives every paid order’s stage and next step on each call, and get_transaction has the detail.
initiatedThe link exists. The buyer has not opened it yet.
awaiting_paymentThe buyer submitted their address, so a payment session exists.
escrowedPaid. The money is held, and the ship-by deadline starts. Shipping progress shows on the order, not as a state.
releasedThe buyer confirmed receipt, or the release date passed. Funds are the seller’s, paid out once Stripe onboarding is done.
Two exits: cancelled when a checkout lapses or is cancelled before payment, and refunded when a paid order is cancelled, misses its ship-by deadline, or its label is never scanned by the carrier. The seller has seven days from payment to ship, and the hold releases three days after the carrier confirms delivery, or sooner when the buyer confirms receipt. If tracking never shows the parcel delivered, it releases seven days after the estimated delivery date instead. Both dates come back on the transaction.
Connect Sellee through your agent
Already use one of these agents? Its page on carousell.ai has the shortest way to connect it.
- ClaudeOne-click connector, a Claude Code command, or a skill.
- Grok BotOne-click connector through Cursor, or the skill.
- CueShop with the skill today; list through a Manus custom server.
- MuseShop with the skill; ask Muse to connect for listing.
- InstinctText it the skill address. No connector path yet.