# API and MCP | Neeed Directory

Canonical page: https://mcp-preview.neeed.directory/docs/api

Read the Neeed Directory catalog from your own code or agent. Every endpoint is a GET that answers JSON and allows cross-origin requests; only live listings are returned. No key is needed.

## Endpoints

Base URL: https://mcp-preview.neeed.directory/api/v1. OpenAPI document: https://mcp-preview.neeed.directory/api/v1/openapi.json.

- `GET /api/v1/search`: Search or list products. Live listings, newest first. Narrow them with a full-text query and by category, label or tag; every filter is optional.
- `GET /api/v1/categories`: List categories. Every category with the number of live listings it holds, by name.
- `GET /api/v1/products/{slug}`: Get a product. One live listing by slug. A listing that is not live is a 404.

## Limits and caching

- 30 searches and 60 other calls per IP per minute, then a 429 until the minute ends.
- Answers can be served from the edge for up to five minutes, so a change to a listing takes that long to reach the API.
- Errors are a JSON object with a code and a message; a 400 adds the rejected parameters under data.issues.

## MCP server

https://mcp-preview.neeed.directory/api/mcp: the three reads as tools, `submit_product`, which saves a listing draft or, signed in, submits it, and `my_listings`, `check_badge`, `update_listing`, `upgrade_listing` for a signed-in maker's own listings. Streamable HTTP, stateless, no session. The reads and `submit_product` need no key and no sign-in. With Claude Code: `claude mcp add --transport http neeed https://mcp-preview.neeed.directory/api/mcp`. In any MCP client configuration: `{ "mcpServers": { "neeed": { "type": "http", "url": "https://mcp-preview.neeed.directory/api/mcp" } } }`.

- `search_products`: Search the live listings on Neeed Directory, newest first. Every argument is optional: a full-text query over name, tagline and description, and category, label or tag slugs to narrow by. Returns products with their slug, tagline, description, website and pricing model, plus the total match count.
- `list_categories`: Every category on Neeed Directory with its slug, name and the number of live listings it holds.
- `get_product`: One live listing on Neeed Directory by slug, with its full description, website, labels, tags and pricing model, plus its premium profile (highlights, who it is for, FAQ) and promo code when it has them.
- `submit_product`: Without sign-in, saves a private draft listing on Neeed Directory and returns a claim link: nothing is published or charged until the maker opens it, signs in and submits. Signed in with permission to edit listings, submits the listing to the maker's account: Neeed's automatic check publishes it or holds it for review, and Premium returns a Stripe Checkout link the maker pays in the browser.
- `my_listings`: Your listings on Neeed Directory, newest first: status, plan, badge, the admin's feedback when there is any, and the page to open. Pass a slug to get one.
- `check_badge`: Looks for the Neeed badge on one of your Free listings' sites now and answers found, missing or inconclusive, with the markup to add. It records nothing: the maker presses Verify on the listing's edit page to make the link dofollow or bring a hidden listing back.
- `update_listing`: Edits one of your listings: name, punchline, description, category, pricing model or Twitter handle, under the dashboard's rules. Editing a listing that is not live sends it back for review; a live listing stays live. A rejected listing cannot be edited.
- `upgrade_listing`: Returns a Stripe Checkout link that upgrades one of your live Free listings to Premium, with the price. Nothing is charged until the maker opens the link and pays in the browser.
- Prompt `submit_to_neeed` (argument: website): Drafts a Neeed listing from a product's website, has the maker approve it, and saves it with submit_product.

## Sign in to manage your listings

`search_products`, `list_categories`, `get_product`, `submit_product` work without signing in. `my_listings`, `check_badge`, `update_listing`, `upgrade_listing` need a signed-in maker.

The assistant signs in with OAuth. Neeed shows which app is asking and what it may do, and nothing is shared until the maker approves.

- `listings:read` (See your listings): Needed by `my_listings`, `check_badge`, `update_listing`, `upgrade_listing`. The assistant sees the account's listings with their status, plan, review feedback and badge status.
- `listings:write` (Edit your listings): Also needed by `update_listing`, `upgrade_listing`. With it, `submit_product` submits the listing straight to the account, answers `already_listed` for a site that is live on Neeed and `already_submitted` for a site the account already submitted, and saves a draft with a claim link when the site offers no usable cover image or icon. Without it, the tool saves a draft with a claim link.
- `offline_access` (Stay connected until you disconnect it): Lets the assistant renew its access without asking again.
- Access tokens last one hour. Refresh tokens last 30 days, are replaced on every use and exist only with "Stay connected until you disconnect it".
- A connected assistant can change a listing's name, punchline, description, category, pricing model and X handle under the dashboard's review rules, create a listing through `submit_product`, and get a Checkout link for Premium. It cannot pay, publish without the automatic check, see other makers' listings, or read the account's email address, billing details or password. Payment always happens in the browser on Stripe.
- To disconnect an assistant, open Settings, then Connected apps, and choose Disconnect. Access stops at once.
- After a disconnect, an assistant that still holds its expired sign-in is refused on every call, reads included, until the maker signs in again or clears the stored sign-in (in Claude Code: `/mcp`, then clear authentication).

## Submitting through MCP

- Without sign-in, `submit_product` saves a private draft and returns a claim link.
- Nothing is published or charged until the maker opens the link, signs in and submits through the normal form at https://mcp-preview.neeed.directory/submit. Every listing then goes through the automatic check.
- The link works once and expires in 7 days.
- 5 drafts per IP in any 24 hours, under an overall cap over the same window, so a refused call succeeds once earlier drafts are 24 hours old.

## The Product object

- id (string (uuid))
- slug (string)
- name (string)
- punchline (string): The one-line tagline
- description (string): HTML, as the listing page renders it
- url (string (uri)): The listing on Neeed Directory
- website (string): The product's own site
- logo (string (uri) or null)
- cover (string (uri) or null)
- category (string or null): Category slug
- labels (string[]): Label slugs
- tags (string[]): Tag slugs
- product_type ("software" | "digital_product" or null)
- pricing_model ("free" | "freemium" | "paid" | "open_source" or null)
- twitter (string or null): X handle, without the @
- featured (boolean)
- listed_at (string (date-time) or null): When the listing went live
- highlights (string[]): Premium profile: what it does, one fact per line
- ideal_for (string[]): Premium profile: who it is for
- faq (FaqItem[]): Premium profile: questions answered from the product's site
- promo (Promo or null): The maker's promo code for visitors, or null

## Feeds

- https://mcp-preview.neeed.directory/feed.xml: the 50 newest listings.
- https://mcp-preview.neeed.directory/categories/{slug}/feed.xml: the same feed narrowed to one category.
- https://mcp-preview.neeed.directory/sitemap.xml: every public URL, split into pages, categories, products, alternatives and weekly recaps.
