Odile Labs
Official publisherREMOTE · ODILELABS.COM
Odile Labs: AI agents reach businesses by phone number (Direct); Gate keys, audit. Agentforce-ready.
Available components
Last scanned (2 hours ago)
Scores higher than 84% of remote servers
Reachable. Last reached 5 Nov 2026.
Category Communication
How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →
Endpoint Security97
- The endpoint's TLS certificate is valid, in date, and uses a strong key. View diagnostics → Pass
- Authorisation is enforced on tool calls, advertised via RFC 9728 protected-resource metadata. Discovery is public, which costs nothing: no tool can be invoked without a token. View diagnostics → Pass
- HTTPS is enforced; there's no plaintext access path. View diagnostics → Pass
- The HSTS (Strict-Transport-Security) header is present. View diagnostics → Pass
- DNSSEC is configured correctly; the domain's records validate against the full chain to the root. View diagnostics → Pass
- The authorisation server offers only Dynamic Client Registration (RFC 7591), which MCP 2026-07-28 deprecated in favour of Client ID Metadata Documents. View diagnostics → Partial
Transport & Reachability100
- Verified streamable-http transport via a live MCP handshake. View diagnostics → Pass
Schema Quality & AI Usability65
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 4091 tokens (~292/item across 14 items; 14 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management17
- Stability observed for 5 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage100
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 100% of tool parameters carry a description.Pass
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- All 2 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
- An AI judge read all 15 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 5 Nov 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 13 to 17. That category is still filling its 30-day observation window: 4 days of observed history at the previous scan, 5 at this one. The score rises as the window fills, whether or not the server changes.
- 3 Nov 26 +1
- New tool “cancel_request”, which the server declares destructive security
- Schema quality: 341 → 292 ▲ functional
- New tool “claim_request” functional
- New tool “get_request” functional
- New tool “open_request” functional
- “send_to_business” added an optional parameter “request_id” cosmetic
- 2 Nov 26 +3
- DNSSEC: fail → pass ▲ security
- HSTS header: fail → pass ▲ security
- Tool “answer_call_question” rewrote its description, which is the text the model reads security
- Tool “call_business” rewrote its description, which is the text the model reads security
- Tool “find_business_agent” rewrote its description, which is the text the model reads security
- Tool “get_call_result” rewrote its description, which is the text the model reads security
- Tool “get_direct_payment” rewrote its description, which is the text the model reads security
- Tool “get_direct_usage” rewrote its description, which is the text the model reads security
- Tool “get_m2m_network” rewrote its description, which is the text the model reads security
- Tool “get_replies” rewrote its description, which is the text the model reads security
- Tool “reply_to_business” rewrote its description, which is the text the model reads security
- Tool “send_to_business” rewrote its description, which is the text the model reads security
- Schema quality: 310 → 341 ▼ functional
- 1 Nov 26 +1
- Stability: unverified → 0.03 ▲ functional
- 31 Oct 26 75
First indexed and scored.
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 5 Nov 2026 · Probed https://odilelabs.com/mcp/direct
TLS valid
Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .
| Subject | Issuer | Valid from | Valid until | Key | Signature | Serial |
|---|---|---|---|---|---|---|
| CN=odilelabs.com | CN=WE1,O=Google Trust Services,C=US | 3 Nov 2026 | 1 Feb 2027 | ECDSA 256 | ECDSA-SHA256 | 29c9c12e2b5dbd2e0e8e09189f0d56f5 |
| SANs: odilelabs.com, api.odilelabs.com, *.api.odilelabs.com | ||||||
| CN=WE1,O=Google Trust Services,C=US (CA) | CN=GTS Root R4,O=Google Trust Services LLC,C=US | 13 Dec 2023 | 20 Feb 2029 | ECDSA 256 | ECDSA-SHA384 | 7ff31977972c224a76155d13b6d685e3 |
| CN=GTS Root R4,O=Google Trust Services LLC,C=US (CA) | CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE | 15 Nov 2023 | 28 Jan 2028 | ECDSA 384 | SHA256-RSA | 7fe530bf331343bedd821610493d8a1b |
Background: What to check on a remote MCP endpoint →
DNSSEC secure
Validation of odilelabs.com. — Secure
| Zone | DS | Keys | Algorithms | Outcome |
|---|---|---|---|---|
| . | trust_anchor | 20326, 38696 | 8, 8 | Verified |
| com. | present | 19718 | 13 | Verified |
| odilelabs.com. | present | 2371 | 13 | Verified |
| odilelabs.com. | Verified address RRset verified with the apex keys |
Authentication Enforced and verified
The endpoint asked for a token and published valid RFC 9728 metadata describing how to get one.
| Result | Enforced and verified |
|---|---|
| Enforced | On tool calls |
| HTTP status | 200 |
WWW-Authenticate challenge Bearer realm="OAuth", resource_metadata="https://odilelabs.com/.well-known/oauth-protected-resource/mcp/direct"
Bearer realm="OAuth", resource_metadata="https://odilelabs.com/.well-known/oauth-protected-resource/mcp/direct" | Header | Value |
|---|---|
| strict-transport-security | max-age=15552000 |
Protected resource metadata
| Document | https://odilelabs.com/.well-known/oauth-protected-resource/mcp/direct |
|---|---|
| Retrieved | Yes |
| Resource | https://odilelabs.com/mcp/direct |
| Authorisation server | https://odilelabs.com |
Background: How OAuth 2.1 works in the 2026 MCP spec →
Transports 2 probes
| Transport | URL | Outcome | Status | Location |
|---|---|---|---|---|
| streamable-http | https://odilelabs.com/mcp/direct | Verified | 200 | |
| http (plaintext) | http://odilelabs.com/mcp/direct | HTTPS enforced | 301 | https://odilelabs.com/mcp/direct |
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
answer_call_question Answer a question during your business call ~244
Give the calling assistant your answer to a question the business asked during a call placed with call_business, so the call can continue. Use it only when get_call_result shows state input_required (its pending_question holds the question); reply within 45 seconds or the assistant tells the business the person will follow up and carries on. The assistant uses the answer on the live call and it cannot be taken back, so keep it short and factual (up to 300 characters). It is refused if it contains a number of four to eight digits, a card-length number, or words such as password, PIN or code; never include payment card numbers, passwords or one-time codes. Requires direct:tasks and ownership of the call. Returns the call state; read get_call_result for the outcome. Example: task_id='dv_9a3', answer='A 40-gallon gas heater, installed in 2016.'
| Name | Type | Req | Description |
|---|---|---|---|
| answer | string | yes | The answer to the pending question, in plain words, without card numbers, passwords, one-time codes or any number of four to eight digits. |
| task_id | string | yes | The task_id returned by call_business. |
No output schema declared.
No examples provided.
call_business Call a business without a Direct card ~474
Place an outbound phone call to a business to ask for information on a named person’s behalf. Use it when find_business_agent returned not_found for a US or Canadian number; when a Direct card exists use send_to_business. It dials a real number and a call cannot be recalled once placed. Requires direct:tasks, human opt-in at https://odilelabs.com/developers#voice and the person’s permission for this call (on_behalf_consent true). Informational calls only: no sales, payments or account access. Calls run Monday to Friday, 9:00 to 17:00 in the business’s local time; outside that window the request is refused and the error includes next_window. A number is not called twice within 24 hours, and each account has a daily call cap. number and callback_number must be callable US or Canadian E.164 numbers, callback_number being the person’s own, never the business’s. message_id is required: reuse it unchanged on every retry so only one call is placed. Returns {task_id, state (queued, completed or failed), status}; read get_call_result for progress and answers. Voice credit costs: get_m2m_network. Example: number='+15615550123', business_name='Harbor Plumbing', caller_name='Ana Diaz', callback_number='+15615550199', need='Do you replace water heaters?', on_behalf_consent=true, message_id='call-8f2'.
| Name | Type | Req | Description |
|---|---|---|---|
| business_name | string | yes | The business to call. |
| callback_number | string | yes | That person’s own callback number in E.164, never the business’s. |
| caller_name | string | yes | The named person who requested this call. |
| max_seconds | integer | – | Maximum call duration, from 60 to 600 seconds, subject to available credits. |
| message_id | string | yes | A stable request id; reuse it unchanged on every retry. |
| need | string | yes | The information the person wants from the business. |
| number | string | yes | The business’s E.164 phone number, e.g. +15615550123. |
| on_behalf_consent | boolean | yes | True only after that person asked for this call. |
| questions | array | – | Up to five questions to ask the business. |
No output schema declared.
No examples provided.
cancel_request Cancel a request booking ~143
Cancel the confirmed booking held on a request, removing it from the business calendar. It cannot be undone; only do it when the customer asked. Use this for a booking made under a request; for one made without a request, use send_to_business with the cancel_booking skill. Needs a live grant with scope read_cancel or book. Calling it again returns the same result. Returns cancelled, booking_id and when. Refused with outcome_uncertain when the calendar cannot confirm the booking (read get_request), and grant_required without access. Requires direct:tasks.
| Name | Type | Req | Description |
|---|---|---|---|
| request_id | string | yes | The request_id returned by open_request or shared by the assistant that opened it. |
No output schema declared.
No examples provided.
claim_request Claim a handoff ~152
Take over a request another assistant opened, using the single-use handoff code the customer issued from their customer link. Use it only when the customer gave you a code; to start a new job use open_request. The code is used up by a successful claim and expires after 15 minutes. Your access is the scope the customer chose: read, read_cancel or book. Returns request_id and your grant; a bad, used or expired code is refused. Call get_request next. Requires direct:tasks.
| Name | Type | Req | Description |
|---|---|---|---|
| code | string | yes | The handoff code the customer gave you, exactly as issued. |
| request_id | string | yes | The request_id returned by open_request or shared by the assistant that opened it. |
No output schema declared.
No examples provided.
find_business_agent Find a business agent ~254
Look up a business by its phone number in the Odile Direct directory and get its Direct card. Start here: send_to_business needs the business id (<biz>) from this card. Pass the number as customers dial it, in E.164 with the country code and no spaces or dashes (+15615550123); any other format is rejected. Returns {agent_card, business, trade, town}: agent_card is the A2A card URL (/b/<biz>/ for a business line, /c/<biz>/ for a claimed listing; pass that <biz> to send_to_business), and the card lists the skills the business accepts. A number that is not on Direct returns not_found with claim_url and listings_url; for a US or Canadian number, voice_fallback says whether call_business is available. Capped at 30 lookups per IP per hour without sign-in and 10000 per key per day signed in. Read-only; contacts no business. Example: number='+15615550123' returns the card whose id you pass to send_to_business as biz.
| Name | Type | Req | Description |
|---|---|---|---|
| number | string | yes | The business's phone number in E.164, e.g. +15615550123. |
No output schema declared.
No examples provided.
get_call_result Read your business call result ~207
Read the state and outcome of a business call you placed with call_business (an outbound call; the calls your own answering line took are in get_line_calls), using its task_id. Call it again until the state is final: queued, dialing and in_call are still in progress; completed, no_answer, voicemail, refused and failed are final; input_required means the business asked a question that answer_call_question can answer within 45 seconds. Requires direct:tasks and ownership of the call (another account’s task_id returns Not found). Returns {task_id, state, outcome, duration_seconds, transcript, answers, summary, cost {credits}}, plus pending_question {question, expires_at} while a question waits. Changes nothing, starts no call and is safe to repeat. Example: task_id='dv_9a3' from call_business; stop polling once state is completed, failed or no_answer.
| Name | Type | Req | Description |
|---|---|---|---|
| task_id | string | yes | The task_id returned by call_business. |
No output schema declared.
No examples provided.
get_direct_payment Check your merchant checkout and booking ~223
Check an existing deposit booking on your signed-in Direct account: reconcile its Stripe Checkout payment and return its receipt and the separate booking state. Use it after send_to_business returned a payment_url for a deposit booking, to see whether the person has paid; it cannot start a payment, which the person makes on Stripe’s hosted page. Pass biz (the business id from its card) and task_id (the task id send_to_business returned for that booking). Requires direct:tasks. Uses only the stored merchant account and amount and creates no new charge or booking identity; a verified paid checkout may finish its already-authorized held booking. Payout status remains unknown: paid does not mean a bank payout. Safe to repeat. Example: biz='harbor-plumbing', task_id='tk_5d0' after send_to_business returned a payment_url for a deposit booking.
| Name | Type | Req | Description |
|---|---|---|---|
| biz | string | yes | The business id (from its card) the deposit booking was made with. |
| task_id | string | yes | The task id send_to_business returned for that booking. |
No output schema declared.
No examples provided.
get_direct_usage Your Direct allowance and credits ~130
Read your own Direct account ledger: the signed-in account’s UTC free-send allowance, prepaid balance in cents, reserved cents and last 20 charges. It never buys credit and does not list costs (see get_m2m_network). Use it before sending tasks that may cost credit; a payment_required reply from send_to_business carries the top-up link. Uses the same ledger as REST and your developer page. Requires direct:tasks and sign-in. Changes nothing; phone minutes and legacy credits are tracked separately. Example: call it with no arguments before a booking to confirm the allowance or balance covers it.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
get_m2m_network OdileM2M network ~179
Read the OdileM2M network card for Direct: the live skills a business can accept, what each costs in credits, the credit packs, the limits that apply, and the Gate MCP address and quickstart. Use it to cost Direct tasks before sending any. It does not choose between products (get_agent_services) and does not show your own balance (get_direct_usage). Returns the pricing card (currency, credit_cents, packs, lookups) plus live_skills[{id, name, description, credits}], receipts, mcp_url, gate_mcp_url, quickstart_url, docs_url and connect_steps[]. Reference data, nothing account-specific: takes no arguments, needs no sign-in, contacts no business and changes nothing. Example: call it once with no arguments before the first send_to_business of a session.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
get_replies Read replies from a business ~264
Read the replies in a Direct conversation you started with send_to_business: its status and messages, newest last. Use it to find out whether the business has answered; it only reads and does not wait, so call it again later if there is no reply yet. Not for messages callers left on your own answering line (get_line_messages) or the outcome of a phone call (get_call_result). Pass the thread_id that send_to_business returned; sign in as the original requester with direct:tasks, or supply the private thread_token instead. Returns {thread_id, status (received, business_notified, business_replied, booked, waiting_for_you or closed), caller_name, callback_number, messages[{from: customer or business, text, at}]}. An unknown thread or a wrong token returns not_found, and a thread expires 90 days after its last message. Changes nothing and uses no credits. Example: thread_id='th_7c1' (with thread_token unless you started the thread while signed in) returns the status and messages so far.
| Name | Type | Req | Description |
|---|---|---|---|
| thread_id | string | yes | The thread_id returned by send_to_business. |
| thread_token | string | – | The private thread_token; required unless signed in as the requester who started the thread. |
No output schema declared.
No examples provided.
get_request Read a request ~162
Read a request you hold a grant on: objective, attempts, facts, booking, your_scope and next_allowed. It checks any booking against the business calendar and updates the stored record and billing to match, but never books, moves or cancels anything and contacts nobody; repeat it freely. Use it after a booking, and after claim_request, before acting. Not for a conversation started without a request (get_replies). next_allowed is book, cancel, read or needs_human; a fact marked uncertain means the calendar could not confirm it. Refused with grant_required or grant_revoked when you have no live grant. Requires direct:tasks.
| Name | Type | Req | Description |
|---|---|---|---|
| request_id | string | yes | The request_id returned by open_request or shared by the assistant that opened it. |
No output schema declared.
No examples provided.
open_request Open a request ~198
Open a request for one customer's job at one business, so assistants can hand it to each other with the customer's say-so. Use it first when another assistant may need to continue the job; for a one-off message or booking, use send_to_business alone. It contacts nobody and books nothing. Returns request_id, customer_link and your grant (scope book). Show the customer link (customer_link) to the person before acting: it is how they see the request, revoke an assistant and issue a handoff code. Treat it as private. Then book with send_to_business, passing request_id. Requires direct:tasks.
| Name | Type | Req | Description |
|---|---|---|---|
| biz | string | yes | Business id from the card that find_business_agent returned. |
| callback_number | string | yes | The customer's number in E.164, for example +15615550123. |
| customer_name | string | yes | The customer's name. |
| objective | object | yes | What the customer wants done and when. |
No output schema declared.
No examples provided.
reply_to_business Reply in a business conversation ~264
Send a customer reply in an open Direct conversation and notify the business. Use it after get_replies shows the business answered or asked something; to start a new conversation use send_to_business, and to answer a question during a live phone call use answer_call_question. Pass the thread_id that send_to_business returned and the reply text (1 to 500 characters); sign in as the original requester with direct:tasks, or supply the private thread_token instead. message_id is the retry key: reuse it unchanged when retrying. Returns the A2A {task} for the reply: read its state before telling anyone it was delivered. A delivered reply cannot be recalled and is billed the same way as a take_message task; closed conversations refuse replies. Example: thread_id='th_7c1', text='Thursday after 2pm works, thank you.', message_id='rep-1'.
| Name | Type | Req | Description |
|---|---|---|---|
| message_id | string | – | Your id for this reply; reuse it unchanged when retrying. |
| text | string | yes | The customer’s reply to the business. |
| thread_id | string | yes | The thread_id returned by send_to_business. |
| thread_token | string | – | The private thread_token; required unless signed in as the requester who started the thread. |
No output schema declared.
No examples provided.
send_to_business Send a business a message or booking ~717
Send one request to a business found with find_business_agent, using a skill its card lists: take_message (leave a message), check_availability (read open times), book (book a slot check_availability returned), book_first_available (book the first open slot in up to 5 preferred windows) or cancel_booking (cancel a booking you made). Call find_business_agent first; for a business without a card, use call_business. Say an automated assistant is acting, and get the person's permission before booking. A delivered message cannot be recalled; a booking is undone only with cancel_booking. message_id is the retry key: reuse it unchanged on every retry so the request runs once. If you omit it, an identical request from you counts as a retry only within the same UTC day. Returns the A2A v1.0 {task}: read its state before telling anyone a message was delivered or a booking confirmed. A deposit booking returns INPUT_REQUIRED with a payment_url for the person; it is held 30 minutes and confirmed only after payment, which get_direct_payment checks. Failed, refused and unconfirmed tasks are not charged; costs are in get_m2m_network and your balance in get_direct_usage. Messages and confirmed bookings return thread_id and thread_token: use get_replies to read the business’s replies and reply_to_business to answer in the same conversation. Signed-in requesters may omit callback_number for take_message; anonymous requesters still need their own valid number. Example: biz='harbor-plumbing', skill='take_message', message_id='req-8f2', data={caller_name:'Ana Diaz', callback_number:'+15615550199', need:'Leaking water heater, today if possible'}.
| Name | Type | Req | Description |
|---|---|---|---|
| approval_id | string | – | Only when the business approves bookings itself: the action_id (da_...) from its approval_required reply, sent with the same message_id and data once the owner approves. |
| biz | string | yes | The business id from its card: the <biz> in /b/<biz>/ or /c/<biz>/. |
| data | object | yes | The skill's fields; put skill beside data, never inside it. take_message: caller_name, callback_number (the person's own E.164 number, never the business's), need, optional on_behalf_of and urgency (… |
| message_id | string | – | Your id for this request; reuse it unchanged on every retry so the request runs once. |
| request_id | string | – | Request opened with open_request; use only for book. |
| skill | string | yes | One skill the business card lists. |
| target | string | – | line (default) for a business line (/b/ card); claim for a claimed listing (/c/ card), which takes messages only. |
No output schema declared.
No examples provided.
How do I install the Odile Labs MCP server?
Odile Labs is a hosted endpoint at https://odilelabs.com/mcp/direct, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
remote · odilelabs.com
claude mcp add --transport http com-odilelabs-odile 'https://odilelabs.com/mcp/direct'
What is the Odile Labs MCP server?
Odile Labs is an MCP server listed in the public MCP registry as com.odilelabs/odile. Odile Labs: AI agents reach businesses by phone number (Direct); Gate keys, audit. Agentforce-ready. This page covers its hosted endpoint (https://odilelabs.com/mcp/direct). Its publisher has verified ownership with us.
Is the Odile Labs MCP server safe to use?
Odile Labs scores 81 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the Odile Labs MCP server expose?
Odile Labs exposes 14 tools: get_m2m_network, find_business_agent, send_to_business, open_request, get_request, and 9 more. Their descriptions and schemas cost roughly 3,611 tokens of context every time the server is loaded.
Does the Odile Labs MCP server require authentication?
Yes. Odile Labs asked us for credentials when we connected, so you will need to authorise it in your MCP client before it can do anything.
Is the Odile Labs MCP server still maintained?
Odile Labs is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.