markaDocs
MCP

Tools

The six operations the hosted MCP gateway serves, and the two tools a client reaches them through by default. Generated from the server's own registry.

These are the six operations POST https://joinmarka.com/api/mcp serves. The list below is generated from the running server's tool registry ({registry.source}) by pnpm generate:mcp-tools, so it is the same set of operations — and the same JSON Schemas for their inputs — the server runs.

By default a client does not see these six in tools/list. It sees two tools:

  • search_tools takes an optional query and returns the matching operations as TypeScript declarations. Omit query to get all six.
  • execute_typescript takes code, a TypeScript program that calls the operations as external_<operation>(input) and returns what it wants back, for example return await external_search_listings({ query: "chair" });. The program runs in a sandbox with a 30-second limit and no network or filesystem access beyond those calls.

Each external_ call runs the operation with the same authentication, ownership checks and input schema as calling it directly. The result of execute_typescript is { success, result, logs, error }. A failed operation call throws inside the program, and a program that throws comes back as success: false with the error, inside an execute_typescript call that itself succeeded, so check success rather than the call status. If your client lists the six operations below as tools instead, it calls them directly.

The SDK's local bridge exposes a different set. Neither server can publish a listing.

Publishing in the app or through POST /api/v1/listings/{id}/publish requires available stock: quantityTotal - quantityReserved > 0, for both unique and multi-quantity inventory. A refusal is the domain error out_of_stock, returned as HTTP 400 by the API. Its message is "All units are held by open orders." when quantityTotal > 0, or "Active listings require stock." when quantityTotal is 0. The app's AI publish action displays the same message as a domain-tagged error.

create_listing_draft

Create a DRAFT listing for the authenticated seller. Does not publish. Once the seller has approved a draft — including when the same message both describes the item and approves creating it — CALL this tool immediately with the agreed values. Do not restate the listing in prose instead of calling it: a written-out proposal is only for the not-yet-approved stage, and after approval it leaves the seller with no draft.

ParameterTypeRequiredNotes
brandstringnullno
categoryPathstringyesSlash-delimited lowercase taxonomy path, e.g. "electronics/cameras". Never an external marketplace's numeric category id.
citystringno
condition"new" | "refurbished" | "like_new" | "good" | "fair" | "for_parts"yes
countryCodestringno
currencystringnoDefaults to "CAD".
descriptionstringyes
imageUrlsstring[]noDefaults to [].
madeInCountrystring | nullnoCountry of manufacture as an ISO 3166-1 alpha-2 code (e.g. CA, DE), stored uppercase; null when not specified. Used as the item's origin country on international shipping labels (customs and duties). A lowercase code is accepted and uppercased; an unknown code is rejected. On an update, null clears it and omitting the field leaves it unchanged.
priceintegeryesPrice in minor units (cents)
titlestringyes

get_listing

Fetch the full public details of one active listing by id, including its seller's id and name.

ParameterTypeRequiredNotes
idstringyesThe listing id

get_seller_info

Get a seller's public profile (name, avatar) and how many active listings they have. Pass the listing's sellerId, or just the listingId of one of their listings.

ParameterTypeRequiredNotes
listingIdstringnullnoA listing id (the id field of a search_listings or get_listing result). The tool looks up that listing's seller. Pass this when you have a listing but not its sellerId.
sellerIdstringnullnoThe seller's user id: the sellerId field of a listing returned by get_listing. Not a listing id.

list_categories

List the active listing categories on Marka (with how many listings each has). Returns the COMPLETE set in a single call — call this only once; a larger limit does not return different categories.

ParameterTypeRequiredNotes
limitintegernoDefaults to 20.

search_listings

Search active Marka listings by keywords and optional price range. An empty query browses every active listing in the price range. Returns listing summaries to show the buyer.

ParameterTypeRequiredNotes
limitintegernoDefaults to 12.
maxPriceintegernoMaximum price in minor units (cents)
minPriceintegernoMinimum price in minor units (cents)
querystringyesKeywords for the item, e.g. 'leather sofa'. Use an empty string to browse every active listing, e.g. 'anything under $200' is query '' with maxPrice 20000.

update_listing_draft

Update fields on a DRAFT listing owned by the authenticated seller. Does not publish.

ParameterTypeRequiredNotes
descriptionstringno
draftIdstringyesThe id of the draft listing to update
imageUrlsstring[]no
madeInCountrystring | nullnoCountry of manufacture as an ISO 3166-1 alpha-2 code (e.g. CA, DE), stored uppercase; null when not specified. Used as the item's origin country on international shipping labels (customs and duties). A lowercase code is accepted and uppercased; an unknown code is rejected. On an update, null clears it and omitting the field leaves it unchanged.
priceintegernoPrice in minor units (cents)
titlestringno

Notes on the schemas

  • Money is integer minor units. Every price, minPrice and maxPrice above is an integer in the minor unit of the listing's currency — 4500 is CA$45.00 on a CAD listing.
  • create_listing_draft and update_listing_draft write to your account. They create and edit drafts, which are not visible to buyers. They also consume your monthly AI copilot run quota (3 on the free plan; unlimited on Pro and Business).
  • The read tools are public data. search_listings, get_listing, list_categories and get_seller_info return what any visitor to the Marka website can see.
  • list_categories returns the complete set in one call. There is no second page; a larger limit only truncates less.

On this page