Every change Wellknown observed on this MCP server, newest first, with what it was before and what it became. Tool-surface changes carry the definition diff. Nothing here is edited after the fact.
Recently observed → Unavailable
Live → Recently observed
Authorization not required, issuer https://odilelabs.com
Changed the definition of "get_job", "prepare_upload" and "set_up_answering_line"
⟨108 unchanged words⟩ not on this account returns 'No such job'. It reports status only: the files come from get_downloads after unlock_job, and a price before uploading comes from estimate_media_job.
⟨81 unchanged words⟩ token; earlier tokens stay valid until their ownexpiry.expiry, so call it again only when a token has expired or for a new job. To price a job first use estimate_media_job; for the file limits use get_catalog.
{"destructiveHint":false,"idempotentHint":truefalse,"openWorldHint":false,"readOnlyHint":false}
Changed the definition of "buy_pack", "get_balance" and "set_up_answering_line"
GetCheckout link for acheckoutpack:linkFormatstocredits,buymeetingaminutespackor answered calls
Added "buy_pack", "get_answering_line", "get_answering_line_offer" and 1 more; changed the definition of "get_balance", "get_catalog" and "get_receptionist_benchmark" (9 tools before, 13 now)
⟨53 unchanged words⟩ to lapse, or null), buy_credits_at }.ThisToconnectionbuycannotmore:buybuy_packcredits(needs the billing:checkout permission) returns a checkout link the customer pays on Stripe's own page, or send the customer to buy_credits_at.
Certificate recorded, valid to 2026-12-04
Authorization not required, issuer https://odilelabs.com
Changed the definition of "create_media_job", "estimate_media_job", "get_balance" and 3 more
QueueaanMakeOdile Formats job from sources uploaded with prepare_upload's helper. Costs ⟨75 unchanged words⟩
PriceaanMakeOdile Formats job in credits before anything is uploaded or ⟨83 unchanged words⟩
Changed the definition of "create_media_job", "estimate_media_job", "get_balance" and 6 more
Queue a Make job from sources uploadedsources.with prepare_upload's helper. Costs nothing: credits are only spent byunlock_job.unlock_job,Callingafter the customer approves. One set of uploads makes exactly one job: calling it againforwith the sameuploadssources returns the existing jobthat(replayed:
First tool surface recorded: 9 tools (server version 0.3.0)
Unknown → Live
https://odilelabs.com/mcp (mcp_streamable_http) — from mcp_registry, with the record
Showing the latest 13 events. The API returns up to 500 and filters by kind: ?kind=tool_surface_changed
⟨130 unchanged words⟩ the owner https://odilelabs.com/terms and getting a yes. For prices first use get_answering_line_offer; for a line that already exists use get_answering_line, and add calls to it with buy_pack (product 'calls'), not a second set-up. United States only (the business line and the ⟨37 unchanged words⟩
CreditOdile Formats credit balance
⟨46 unchanged words⟩ ,"type":"string"},"city":{"description":"The town the business is in, e.g. \"Wellington, FL\". The receptionist says it when a caller asks where you are.","maxLength":80,"type":"string"},"country ⟨230 unchanged words⟩
⟨65 unchanged words⟩ }], free_credits_per_account, credits_valid_months, buy_credits_at, purchasable_through_this_connection:falsetrue, how_to_buy, units, presets{video[], photos[]} ⟨25 unchanged words⟩
⟨99 unchanged words⟩ which sells After Hours and Dusklin), notindependent;independent.itIt does not test the caller's own lineor(for that, see read_more.free_line_check); to set upaanreceptionistAfter(forHoursthatline billed per answered call, seeread_more.free_line_check).get_answering_line_offer.
Get a checkout link to buy a pack — Returns a one-time Stripe checkout link for a prepaid pack; the customer opens it and pays on Stripe's own page, and this connection never sees the card. Only call it when the customer asked to buy, and tell them the price first. Products: 'formats' (Odile Formats credits; packs from get_catalog), 'minutes' (meeting minutes, only where Meeting Notes is on), 'calls' (answered calls for one of the customer's own After Hours lines; line_id required: calls10: 10 calls for $15; calls50: 50 calls for $75). What was paid is added within a minute of payment, whatever device paid it. Nothing renews. N…
The owner's answering lines: status, number, balance, recent calls — The signed-in owner's own After Hours lines billed per answered call, and any set-up still awaiting payment. Use it after set_up_answering_line to see when the line is live, to give the owner the forwarding codes, or to answer 'how many calls do I have left?'. Needs a signed-in connection with the lines:manage permission and changes nothing. Returns { lines[{ line_id, business_name, status (setting up | live | queued), number, number_e164, forwarding[{carrier, codes[{what, dial, stop}], note}], balance (calls left; below zero means carried over to the next pack), calls_charged_this_month, cal…
After Hours answering line, billed per answered call: the offer — The offer for an After Hours AI phone receptionist on the owner's own business line, prepaid and billed per ANSWERED call: calls10: 10 calls for $15; calls50: 50 calls for $75 ($1.50 a call). A call is charged only when your line answers a real phone call and it lasts 20 seconds or more. Not charged: calls under that, robocalls the line recognises, calls from your own numbers or from ours, website and widget chats, text messages, and any call whose transcript cannot be read. At zero the line keeps answering. Up to 10 calls past zero are carried over and taken from your next pack. You are emai…
Set up an After Hours answering line (billed per answered call) — Starts an After Hours AI receptionist for the signed-in owner's business, prepaid and billed per answered call (calls10: 10 calls for $15; calls50: 50 calls for $75). A call is charged only when your line answers a real phone call and it lasts 20 seconds or more. Not charged: calls under that, robocalls the line recognises, calls from your own numbers or from ours, website and widget chats, text messages, and any call whose transcript cannot be read. Nothing is built or bought until the owner pays: this returns a Stripe checkout link for the first pack, and the line (agent and phone number) i…
The signed-in customer'sMakeOdile Formats credit balance. Use it before unlock_job to check ⟨56 unchanged words⟩
OdileMakeFormats: what it does and what it costs
The live price list and limits for OdileMakeFormats, which reformats an existing video or photos ⟨83 unchanged words⟩
OneMakeOdile Formats job by id, or the ten most ⟨106 unchanged words⟩
Step one ofaanMakeOdile Formats job: returns a 30-minute upload token and ⟨77 unchanged words⟩
{"$schema":"http://json-schema.org/draft-07/schema#","properties":{"outputs":{"description":"1 to 4 outputs; one finished file per entry.","items":{"properties":{"fit":{"description":"How the source is fitted to the new shape: 'crop', 'blur' (blurred fill) or 'auto' (default).","enum":["crop","blur","auto"],"type":"string"},"preset":{"description":"An output preset name from get_catalog.presets matching the source kind.","enum":["reel_9x16","feed_4x5","square_1x1", ⟨38 unchanged words⟩ "},"trim":{"description":"Video only,:inkeepsecondsjust this part of the source. Omit to use the whole video.","properties":{"end":{"description":"End, in seconds; at most 600","maximum":600,"type":"number"},"start":{"description":"Start, in seconds from the beginning","minimum":0,"type":"number"}}, ⟨10 unchanged words⟩
Price a Make job in credits before anything is uploaded orcharged.charged; use it to tell the customer the cost and get their approval before unlock_job. Needs no sign-in and changes nothing. Photos areexact.pricedVideoexactly.isReel,aFeed1-2and Square video outputs cost exactly 1 creditrangeeach;perYouTubeoutput16:9 costs 1 or 2 because the length isnotonly knownuntilonce the file is read. Returns { minimum_credits, maximum_credits, final_price_known, charge_now: 0, why }. An unknown preset or a photo count out of range returns an error naming the valid values (get_catalog lists them).
{"$schema":"http://json-schema.org/draft-07/schema#","properties":{"kind":{"description":"'video' for one video file, 'photos' for a set of still images.","enum":["video","photos"],"type":"string"},"outputs":{"description":"1 to 4 output preset names from get_catalog.presets (video presets for kind video, photo presets for kind photos); one finished file per preset.","items":{"enum":["reel_9x16","feed_4x5" ⟨10 unchanged words⟩ 1,"type":"array"},"photo_count":{"description":"Required when kind is 'photos' (the call fails without it): how many source photos, 1 to 10. Must be omitted when kind is 'video'.","maximum":10,"minimum":1,"type": ⟨6 unchanged words⟩
The signed-in customer's Make creditbalance,balance. Use it before unlock_job to check thenextjobexpiryis affordable, or when the customer asks what they have left. Needs a signed-in connection; takes no arguments andwherechanges nothing. Returns { account, credits (whole number, 0 when empty), next_expiry ({ at: epoch milliseconds, credits } for the next credits tobuylapse,more.or null), buy_credits_at }. This connection cannot buycredits;credits: send the customerdoes that on thetowebsite.buy_credits_at.
The live price list and limits for Odile Make,read from the same source the website charges from. Makewhich reformats an existing video or photos for socialplatforms;platforms (it does not pick clips, write captions oredit.edit). Call it first, before estimate_media_job or prepare_upload, to learn the preset and fit names, the file limits and the job flow. Needs no sign-in, takes no arguments and changes nothing. Returns { currency, packs[{id, credits, cents}], free_credits_per_account, credits_valid_months, buy_credits_at, purchasable_through_this_connection: false, units, presets{video[], photos[]} (preset name strings), fits[] (fit name strings), limits{video_source_bytes, photo_source_bytes, max_source_photos, max_trim_seconds}, flow[] }. Prices are read from the same source the website charges from.
Signed download linkstofor every finished file of a job,theoncecustomerunlock_job hasunlocked.succeeded for it. Use it as the last step of the flow, and again whenever links have expired. Needs a signed-in connection and changes nothing. Returns { job_id, files[{name, preset, bytes, width, height, duration, url, expires_at}], how }. Each link works for 15 minutes and needs no login, so: fetch the files with curl (see how) rather than reading them into theconversation.conversation,Askor,againwithout a shell, give the customer the links to open. Files are kept forfresh30links.days. A job that is not unlocked returns an error with its state and cost; call unlock_job first.
{"$schema":"http://json-schema.org/draft-07/schema#","properties":{"job_id":{"description":"The id (UUID) of a job on this account that unlock_job has already unlocked.","format":"uuid","pattern":"^([0-9a-fA-F ⟨23 unchanged words⟩
One Make job by id, or the ten most recent when no id is given. Use it to poll a job after create_media_job (every 10-20 seconds, up to 10 minutes) until state isqueuedready or failed; if it is still rendering after that, tell the customer and check again later (nothing is charged until unlock_job). Needs a signed-in connection and changes nothing. Returns one job { job_id, kind, state (queued | rendering | ready | failed), error, unlocked, credits_cost, credits_cost_known, credits_spent, outputs[{name, preset, ready, bytes, duration}], created_at, updated_at }, orfailed.{ jobs[] } of the same shape. credits_cost is final only once credits_cost_known is true. An id that is not on this account returns 'No such job'.
{"$schema":"http://json-schema.org/draft-07/schema#","properties":{"job_id":{"description":"The job id (UUID) returned by create_media_job. Omit to list the ten most recent jobs.","format":"uuid","pattern":"^([0-9a-fA-F ⟨21 unchanged words⟩
⟨11 unchanged words⟩ placed to public lines, scored against statedmeasuresmeasures. Use it when someone asks how AI receptionists actually handle calls, or to compare named products; call it withthenoevidenceargumentsquotedfirst,perthenmeasure.filter. Needs no sign-in and changes nothing. Returnsthe{ source, date,thecalls, minutes, run_by, limitations, fairness_note, scenarios[{id,name,brief}], lines[{id,testedvendor,theirbusiness, kind, answers_as, list_price, ranked, points,bypossible,scenarioby_scenario{<scenario_id>:{points,thepossible,fairnessanswered,notefirst_words_s,andai_disclosed_unprompted,thereply_language,limitations.price_quoted,Usemeasures}}}],itread_morewhen}.comparingAnhowunknownAIline_idreceptionistsoractuallyscenario_idanswer.returnsRunan error listing the valid ids. Vendor-run by Odile Labs,(which sells After Hours and Dusklin, so it is vendor-run), notindependent.independent;Itit does not test the caller's own lineand does notor set up areceptionist.receptionist (for that, see read_more.free_line_check).
{"$schema":"http://json-schema.org/draft-07/schema#","properties":{"include_evidence":{"default":false,"description":"Default false: each scenario's measures come back as strings like 'yes: <measure>'. true: measures come back as [{measure, score (0 or 1), evidence (quoted transcript)}] (much longer output).","type":"boolean"},"line_id":{"description":"Only this tested line, e.g. 'afterhours-plumbing', 'afterhours-vet', 'rosie', 'myaifrontdesk' or 'dialzara'. Omit for every line.","maxLength":40,"type":"string"},"scenario_id":{"description":"Only this scenario: 'emergency' (leak after hours), 'booking' (book a slot), 'price' (price probe), 'disclosure' (are you real?) or 'spanish' (caller in Spanish). Omit for all.","maxLength":40,"type":"string"}},"type":"object"}
ReturnsStep one of a Make job: returns a 30-minute upload token and the helper command. Run the helper in a shell on the customer's machine: file bytes go straight to Odile and never enter this conversation.ItThe helper prints the source keys to pass to create_media_job. Needs a signed-in connection with write access; nothing is charged. Returns { kind, upload_token, expires_at, helper_url, run[], accepts, part_size, note }. One video OR up to ten photos per job. Each call mints a new token; earlier tokens stay valid until their own expiry.
{"$schema":"http://json-schema.org/draft-07/schema#","properties":{"kind":{"description":"'video' to upload one MP4 or MOV (up to 500 MB, 10 minutes); 'photos' to upload 1 to 10 JPEG, PNG or WebP files.","enum":["video","photos"],"type" ⟨5 unchanged words⟩
Spends the customer'scredits.credits to unlock a finished job's files. Only callafteronce get_job says the job is ready and the customer has approved amaximum.maximum spend. Refuses, charging nothing, if the job costs more than max_credits, is not ready, or the balance isshort.shortUnlocking(the error says which, with thesameamount needed). A jobtwicethatchargesisonce.already unlocked comes back as it is, with no charge and no balance or max_credits check. Needs a signed-in connection with spend access. Returns the job (same shape as get_job, with unlocked: true) plus credits_left and next: 'get_downloads'.
{"$schema":"http://json-schema.org/draft-07/schema#","properties":{"job_id":{"description":"The id (UUID) of a ready job on this account.","format":"uuid","pattern":"^([0-9a-fA-F ⟨23 unchanged words⟩ the customer agreed to spend on this job, 1 to 100 credits. The unlock is refused, charging nothing, if the job costs more.","maximum":100,"minimum":1,"type ⟨6 unchanged words⟩