Findings on what compounds and supplements do in the body, with evidence strength, quote and paper.
- Passed: Handshake
- Passed: Tools listed
- Passed: Updated recently
Median latency 699 ms · Last checked
Explore
Evidence for your next connection.
Independent measurements of remote MCP servers. Every observation has a timestamp.
Read-only probesMCP server · Other
Find B2B companies that fit your buyer, with their contacts and register IDs, and write outreach.
2 failed · 8 not measured
Median of successful probes over 7 days
Share of countable probes over 30 days, including daily rollups. Auth challenges are excluded.
Tool definitions returned by this server
Independent monitoring
Responded
The server completed its last measured handshake. This is an observation, not a guarantee.
Last checked| Test area | Passed | Failed | Unmeasured |
|---|---|---|---|
ConnectionCan a client connect and discover tools? | 5 | 0 | 0 |
Reliability & speedDoes it respond consistently and quickly? | 0 | 0 | 4 |
Access & authenticationWhat is required to use this server? | 1 | 0 | 2 |
Tool qualityAre the tool definitions usable by an agent? | 3 | 1 | 0 |
Publisher identityCan the publisher be traced to its source? | 3 | 1 | 2 |
Unmeasured means there is not enough evidence to decide. How these checks work
Start using Prosp
Choose your client, copy the configuration, then enable the server in your client’s MCP settings.
Run this command in your terminal, then restart Claude Code.
Claude Code
claude mcp add --transport http prosp https://api.prosp.cc/mcp-rpcCapabilities
Mark one or more company domains as delivered so they are not returned again in future discoveries or searches. Pass the `domains` list. Job-blind: each domain is acknowledged across ALL your discoveries. Idempotent — an unknown or already-acknowledged domain is a harmless no-op that contributes 0 to the returned count. Does not cost credits.
DiscoveredCancel a running discovery job by its jobId, freeing its slot so a new find_prospects can start. Credits are refunded ONLY when the run had delivered zero prospects at cancel time; if prospects were already delivered you keep them and are not refunded (they stay retrievable via get_discovery_results). Only the job's owner may cancel; cancelling an already-finished job is a harmless no-op that returns its current state.
DiscoveredMoves a `queued`, `enriching` or `composing` generation to the terminal state `canceled` with `canceled_reason` = `caller_request`. **Refund rule:** the debit is returned if composition has not started (`status` is `queued` or `enriching`); once `composing` has started the cancel is accepted but the credits are not returned. Canceling an already `canceled` generation is idempotent and returns it unchanged. Canceling a `succeeded` or `failed` generation is **`409 not_cancelable`**. An expired id is `410 generation_expired`.
DiscoveredRemoves the profile. Idempotent: deleting when no profile is set also returns `204`. **No credit cost.**
DiscoveredDisconnect your Odoo CRM. Future discovered prospects will no longer sync to it. Idempotent — safe to call even if nothing is connected.
DiscoveredStart a B2B prospect-discovery job. Debits 100 credits and returns a jobId immediately; the job runs asynchronously (~5-25 min). Poll get_discovery_status with the jobId, then call get_discovery_results when it reaches a terminal state.
DiscoveredRegisters one message generation and returns immediately with `202 Accepted`. Poll the status resource named in `Location` (or honour `Retry-After`) until `status` is terminal; the finished message is embedded in that resource. The API composes text; it does **not** send it, and it does not replace the recipient's WhatsApp opt-in. ## What the message may say Every candidate fact about the recipient and the sender carries a tier. The message **asserts only facts of tier `verified`**. `reported` and `estimated` facts may influence which angle is chosen but are never stated as fact; `unknown` facts are never mentioned. The tier of each field is derived from the provenance the record already carries (field by field, from its source and verification evidence), not chosen by the model. Personal data - contacts, officers, phone numbers, e-mail addresses, social handles, and, for a sole trader, the person's own name and address - is **never** asserted. After generation, code re-checks that each claim in the text maps to `fact_ids` of `verified` facts; an unsupported claim is removed, or the request fails - it is never shipped. ## Language The message is written in the language of the **recipient company's website main page**. There is no caller override. The decision is reported on the result as `language` (ISO 639-1) and `language_source`. If the homepage language cannot be determined the request fails with error code `language_undetermined` and the credits are returned; the language is never guessed. ## Unknown companies If the recipient or sender company is not yet known, the status passes through `enriching`, which runs the existing discovery/validation pipeline for that single domain, then `composing`. ## Cost and balance There is exactly **one debit, at `POST`**, for the whole generation including any enrichment. Enrichment never debits again and never changes the balance mid-job; a generation that ends `failed` for any reason below, or `canceled` before composition starts, returns that one debit. `402 insufficient_credits` is therefore only ever returned by `POST`. ## Jurisdiction Checked at `POST` against what is already known: `422 jurisdiction_excluded`. A company whose jurisdiction only becomes known **after** enrichment is excluded late: the generation ends `failed` with `error.error` = `jurisdiction_excluded` and the credits are returned. The text is never composed for an excluded jurisdiction. ## Validation done before `202` Invalid body or hostname: `400 invalid_request`. `sender.company_domain` is the sender's own company domain: the service reads the sender's facts from the knowledge base by it and does not verify that the caller controls it. When `sender` or `sender.company_domain` is omitted, the caller's seller profile website is the sender; with no profile website either, the request is `400 invalid_request` (`sender.company_domain is required when no seller profile website is set`). Recipient or sender in a policy-excluded jurisdiction: `422 jurisdiction_excluded`. Insufficient credits: `402 insufficient_credits`. `constraints.max_characters` that no message can meet: `422 max_characters_unmeetable`; when this only shows during composition the generation ends `failed` with the same code and the credits are returned. `callback_url` must be an `https` URL on a public host: a URL resolving to a private, loopback, link-local, reserved, multicast or cloud-metadata address is rejected with `422 unsafe_url` (the same rule as `odoo_url` on the tenant Odoo endpoint). The service being temporarily unable to accept work: `503 service_unavailable` with `Retry-After`; nothing is debited. ## Error codes Every error uses the surface's single `Error` shape `{error, message, request_id}`. `error` is a snake_case code: `invalid_request`, `missing_idempotency_key`, `idempotency_key_reused`, `request_in_flight`, `jurisdiction_excluded`, `insufficient_credits`, `unsafe_url`, `max_characters_unmeetable`, `not_cancelable`, `generation_expired`, `service_unavailable`, and, on a `failed` generation only, the `MessageFailureCode` values: `insufficient_verified_facts` (too few verified facts exist to write anything true), `enrichment_failed`, `language_undetermined`, `language_failed`, `claim_verification_failed`, `jurisdiction_excluded`, `max_characters_unmeetable`, `compose_failed`, `compose_timeout` and `timed_out`. A `failed` generation always returns its credits. ## Idempotency (draft-ietf-httpapi-idempotency-key-header-07) `Idempotency-Key` is **required**. Missing: `400 missing_idempotency_key`. Same key with a different payload: `422 idempotency_key_reused`. Same key while the original request is still being processed: `409 request_in_flight`. Same key with the same payload: **`200`** (not `202`) with the EXISTING resource in its current state (same `id`, no second debit). A key is remembered for **24 hours** from its first use; after that the same key starts a new generation.
DiscoveredReturn your remaining credit balance and the per-job cost (100 credits).
DiscoveredShow your credit transaction history: every debit and refund behind the current balance, most recent first. Each entry has a `type` ('debit' or 'refund'), the `job_id` it belongs to, the `amount`, a `reason` and a `timestamp`. Use this to explain WHY the balance is what it is — e.g. a job that debited 100 credits and was then refunded on exhaustion/failure shows up as a matching debit + refund pair, so the balance returning to its prior value is a legitimate refund, not the debit having failed to apply. Does not run a new discovery and does not cost credits. Pass `limit` to bound how many recent transactions are returned (default 50, max 200).
DiscoveredShow your currently configured Odoo CRM connection (Odoo URL, database, user id and status). Never shows the API key. Returns a 'not connected' error if you have not called set_odoo_credentials yet.
DiscoveredFetch the result summary + discovered companies (with verified contacts) for a jobId. Call once get_discovery_status reports a terminal state.
DiscoveredPoll a discovery job by its jobId. Returns the lifecycle state (queued, processing, completed, failed, exhausted), `total_prospects` (the canonical count of validated prospects delivered so far — the SAME field name get_discovery_results carries, so you can group/count across both; `prospectsFound` is a deprecated alias of it) and `target` counts, and `found`: the prospect DOMAINS discovered so far — which accumulate PROGRESSIVELY while the job runs, so you see results before it finishes. For incremental polling, pass the previous response's `next_cursor` as `cursor` to receive only the domains added since your last poll (`has_more` stays true until the job reaches a terminal state; omit `cursor` to get the full list so far). Call get_prospect(domain) — or get_discovery_results once terminal — for full detail on any domain in `found`.
DiscoveredAlways `200` for a known id owned by the caller; a non-terminal state is a status, not an error. An unknown id, or one owned by another tenant, is `404`. While `status` is non-terminal the response carries `Retry-After`. When `succeeded`, `result` is embedded in this response (there is no redirect to a second resource). When `failed`, `error` is the surface's `Error` shape with a snake_case code. When `canceled`, `canceled_reason` says why. The resource is retained for **7 days after it reaches a terminal state**; `expires_at` says when, and the response carries a matching `Expires` header. After that the id is **`410 Gone`** (`generation_expired`), distinct from `404` for an id that never existed or is not yours.
DiscoveredFetch the FULL record for one already-discovered company by its `domain` — the detail behind a `search_prospects` summary or a `found[]` domain. Returns every field (contacts, personal + company emails, registry data, address, social profiles, scores, description), not the lean summary. Does not run a new discovery and does not cost credits. A domain you have not discovered comes back as a structured `not_found` status rather than an error.
DiscoveredThe one seller profile the caller keeps: the business description and website used to ground outreach messages. **No credit cost.** `derivation_status` says whether an offering was derived from the website (`derived`), is still being derived (`pending`), or there is no website (`none`). `404 not_found` when no profile is set.
DiscoveredList circular-economy opportunities inferred from the customer's OWN stored business profile: for each, the flow, asset, spare capacity or capability it rests on and the kind of company that completes it. Does not run a discovery and does not cost credits. The list is dated by `computed_at` — when it was DERIVED, not when you asked — and is never padded, so an empty list means nothing is well-grounded. READ `speech_act` BEFORE YOU USE A LABEL. Each of `resource` and `counterpart` carries one, graded independently. `ASSERT` means the customer told us this and you may state it back. `ASK` means WE INFERRED IT, so refer to it only as a question ('do you have spare kiln capacity?'), never as a fact ('your spare kiln capacity'). The two elements are NOT the same kind of claim. `resource` is about the customer's OWN business; `counterpart` is a hypothesis about which kind of company would want it, and it is `ASK` on nearly every entry — that is normal and does not make the entry unusable. `outreach_draft_eligible` answers ONE question: may this entry ground a draft at all. It turns on the `resource`, because that is what a message would be ABOUT. `false` means do not compose outreach from it in any form, not even as a question. `true` means you may write about the resource — it does NOT license asserting the `counterpart`; that element's own `speech_act` still governs it, so write the market as an open question, not as a need you have established. Do not re-order the list: the order is server-authoritative and shared with every other surface these opportunities appear on. Pass an entry's `handle` to run_circular_opportunity to search for its counterparts.
DiscoveredList your saved ICPs (Ideal Customer Profiles) — reusable discovery criteria you can re-run by id. Each entry carries its `icpId`, optional `name`, and stored `criteria`. Pass an `icpId` to run_icp to start a discovery from it. Does not cost credits.
DiscoveredStart a counterpart search for one circular opportunity, by the `handle` from list_circular_opportunities. Debits credits and returns a jobId immediately; poll get_discovery_status then get_discovery_results exactly as for find_prospects. What is searched for is derived server-side from the graded opportunity — you pass a handle, not criteria. When the entry has `requires_resource_confirmation: true`, its resource is something WE INFERRED rather than something the customer stated, and this call is REFUSED (404 `resource_confirmation_required`, no charge) unless you pass `confirmed_resource`. ASK THE CUSTOMER FIRST and send THEIR WORDING — do not echo our label back and do not invent one. Their answer is retained as a stated fact about their business and informs every later inference, so a guess becomes a durable error. An unknown handle is refused with a refund.
DiscoveredStart a discovery from a saved ICP by its `icpId` (get one from list_icps or save_icp). Debits 100 credits and returns a jobId immediately; the job runs asynchronously (~5-25 min) — poll get_discovery_status, then get_discovery_results, exactly as for find_prospects. An unknown icpId is rejected and the debit is refunded.
DiscoveredSave a reusable ICP (Ideal Customer Profile) from an optional display `name` plus discovery `criteria` (same shape as find_prospects). Returns the stored ICP with a server-assigned `icpId` you can later pass to run_icp. Saving does NOT run a discovery and does not cost credits.
DiscoveredSemantic free-text search over the companies you have already discovered. Does not run a new discovery and does not cost credits. Returns LEAN prospect SUMMARIES (domain, name, industry, size, location, employee_count, logo, a short description and a semantic_score) — not the full record. To get every field for one company (contacts, emails, registry data, social profiles, ...), call get_prospect(domain) with the summary's `domain`. Pagination is progressive: the response carries `has_more` and an opaque `next_cursor`; pass that cursor back to fetch the next page. When `has_more` is false / `next_cursor` is null you have seen everything above the relevance floor — stop paging.
DiscoveredConnect your own Odoo CRM so your discovered prospects sync into it. Provide your Odoo URL, database name, API-user id and API key (generate one under Preferences -> Account Security -> New API Key). The connection is validated live against your Odoo before it is saved; your API key is stored encrypted and is NEVER shown back — present a masked confirmation (e.g. odoo_api_key: ****) to the user. Calling this again updates the existing connection.
DiscoveredReplaces the whole profile with the body. **No credit cost.** Send at least one of `description` or `website`. A `description` longer than 1500 characters is truncated to 1500 characters, the same cap the `/profile` bot command applies, so both surfaces store the same record. A `website` is a URL or a bare domain; the site is crawled into the shared knowledge base in the background, and `derived_offering` fills in later (`derivation_status` is `pending` until then). The offering is kept while the website is unchanged and cleared when the website changes.
DiscoveredRecent measurements
| Checked | Result | Response | Tools |
|---|---|---|---|
| Connected | 852 ms | 23 |