Integration details
Description
Bring Vincent’s legal intelligence into Codex. Research the law, analyze dockets and develop case strategy with access to Clio Library and Clio Docket, with citations back to the underlying sources. Your matters and firm data stay securely governed in Clio.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Legal Research Engines
- Secondary Subcategories
- None listed
- Brand
- Clio
- Access
- Account required
- First tracked
- 2026-09-19
- Tool count
- 25
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Get alerts for Clio
Get updates when Clio’s Discoverability Score or category rank changes.
ChatGPT Plugin Discovery Score
ChatGPT Plugin discovery is coming soon
ChatGPT can surface a Plugin when it matches a user's request.Your Plugin Discovery Score measures how often yours appears.
No spam. Unsubscribe any time.
What discovery looks like

Competing in ChatGPT Legal Research Engines
View Category25 tools agents can invoke
Submit a previously-uploaded file for authority-match (citation detection). Prerequisite: the `file_id` must already exist in Vincent — ask the user to send the file with `attach_document`, then confirm with `get_file_status` that Vincent has verified it. Returns the job acceptance envelope: `{"job_id", "status": "queued", "poll_url"}`. Pass the `job_id` to `get_authority_match` to poll for results. Common errors: - 404: the file does not exist or doesn't belong to the user. - 400: malformed file_id.
match_authority
Poll a file's status until terminal (available, completed, or error). Use this after ``attach_document`` has returned a ``file_id``, to confirm Vincent has the bytes before passing that id to ``start_research(file_ids=[...])`` or ``match_authority(file_id=...)``. A result with a ``conversation_id`` instead has nothing to poll. Polling tuning: exponential backoff 0.5s → 5s, 30s total budget. If the file is still in flight after 30s the tool returns the current state and you should tell the user the upload is still being verified, then offer to check again. A file stuck at ``pending`` never had its bytes uploaded — ask the user to drop it again. Returns a structured ``FileStatusResult`` so capable hosts can render it as a widget rather than just prose. Common errors: - 403 naming a feature flag: the account lacks the staged-upload flag. - 403 "Access denied": the file belongs to a different user — re-upload or pick a file_id from this session. - 404: the file_id does not exist.
get_file_status
Read a conversation's record: which workflow, which scope, how far along. This carries no message text and no answer. Use it when the user asks about the conversation itself — what workflow or jurisdiction it used, when it started, whether it is still going, how much it has produced. To read what Vincent actually said, use get_conversation_messages. `document_count` is a count only; list the documents with list_output_documents. Common errors: - 404: the conversation does not exist or does not belong to this user.
get_conversation_metadata
Export a drafted document as Word (docx) or PDF and return its download link. Arguments: - `conversation_id` / `file_key`: as returned by list_output_documents. - `format`: "docx" or "pdf". - `version`: omit for the latest version. Vincent renders the file in the background; this tool waits a short while and then reports where the run got to. Read `status`: - "completed" with a `download_url` → give the user that link. It is pre-signed and valid for seven days, so it works in a plain browser and needs no Vincent credentials. - "failed" → tell the user the export failed and report `error`. Vincent retries a failed render in the background, so offer to call this tool again in a few minutes rather than declaring the document unavailable. - anything else → the render is still going. Tell the user it is being prepared and offer to call this tool again; a fresh call picks up an already-finished render rather than starting a second one. Never the file's bytes: exports run to megabytes and an MCP host truncates a payload that size, so an inlined document would reach the user corrupted. Do not fetch the URL yourself. Common errors: - 404: the conversation, file_key, or version does not exist for this user. - 400: this document cannot be exported in that format.
export_document
List a jurisdiction's courts and the codes search filters on. Call this when the user names a court and you need the code to narrow a search with `court=`. Pass only a `param` this returned; guessing a code silently returns nothing rather than erroring.
search_courts
Long-poll one native SSE event for the live MCP App. Vincent emits writing parts on its private SSE stream before they appear in the formatted conversation snapshot. The MCP server reads that stream with the caller's server-side authorization, so the iframe never sees a token.
get_live_conversation_event
List the documents Vincent drafted in a conversation. Use this before get_output_document or export_document: `file_key` is not guessable, and this is the only place it is published. Each entry has: - `file_key`: pass this to get_output_document / export_document. - `name`: the document's title. - `version`: the latest version number; earlier versions are still readable. - `kind`: the stored content type when known, e.g. text/markdown. An empty list means Vincent has drafted nothing in this conversation yet — say so rather than inventing a document. If a run is still going, the list grows as Vincent writes, so it is worth calling again after the turn ends.
list_output_documents
List the collections (research databases) accessible to the current user. Use this to discover available collections before invoking start_research with a `collection_id` parameter. Each entry in `collections` has: - `collection_id`: opaque identifier — pass this as the `collection_id` argument to start_research. - `name`: human-readable name. - `description`: what the collection contains. - `collection_type`: "matter" | "knowledge" | "project". - `visibility`: "organization" | "private". - `files_count`: documents in the collection, when reported. - `created_at` / `archived_at`: timestamps; `archived_at` is set only when the collection has been archived. Arguments: - `page`: which page to fetch, starting at 1. - `per_page`: collections per page, 1 to 100, defaulting to 100. Leave it alone unless you have a reason to fetch fewer. - `collection_type`: optional filter. Omit to get matter and knowledge collections; project collections are returned only when requested explicitly. Prefer this over paging when the user has named a type. This returns ONE page. `has_more` is true when further pages exist. - If you are looking for a specific collection and have not found it, call again with page + 1 until has_more is false or you find it. Do not lower `per_page` while doing this — every page is another round trip and another full scan. - If the user asked to see or browse their collections, show this page, tell them the `total`, and ask before fetching more. Never state a collection does not exist until has_more is false. Never report `total` as the number you displayed.
list_collections
List the approvals that can be pre-granted when starting research. Each `approval_key` is a string accepted by `start_research(initial_approval_keys=[...])`; pre-granting one means Vincent will not stop to ask before using that capability in the run. Pre-grant only what the user has actually asked to allow, and read the `label` back to them when you do. Passing the whole list to avoid interruptions removes the user's control over what Vincent does on their behalf, which is the point of the approval gate. The set is user-specific — it depends on their organization's configuration and feature flags — so call this rather than reusing keys from elsewhere. An empty list means nothing can be pre-granted for this account.
list_approval_keys
Read one vLex document by its `vid`, one window of its text at a time. Use it on a `vid` from search_legal_documents when the user wants what a document actually says. `body_text` is empty when no format yielded text — report that rather than inferring content from the title or headnotes. A consolidated statute runs to megabytes, so the text arrives windowed: `body_total_chars` is the whole length and `body_has_more` says whether more follows. Read on with `body_offset=body_offset + len(body_text)`, and only when the answer actually needs the rest.
get_legal_document
Read the text of a document Vincent drafted. Arguments: - `conversation_id` / `file_key`: as returned by list_output_documents. - `version`: omit for the latest version, which is what the user means unless they asked for an earlier draft. `available_versions` in the result lists what else can be read. - `max_chars`: how much of the body to return, default 50000 and capped at 200000. A drafted document can be far longer than a tool result may carry. - `start`: character offset to read from, for paging a long document. Paging: read `truncated`. While it is true there is more text, so call again with `start` advanced by the length of the `content` you were given; `total_chars` says how long the whole document is. Do not tell the user you read a document you only read the first page of. Returns the document text plus the conversation's cited authorities. Those citations are conversation-scoped: report them as "authorities Vincent used in this conversation", never as the source of a particular sentence. Never paraphrase this content as Vincent's answer to the user's question — it is a document Vincent wrote; quote or summarize it as such. Common errors: - 404: the conversation, file_key, or version does not exist for this user.
get_output_document
Poll an authority-match job until terminal status (completed/failed). Polls the job with exponential backoff (1s → 15s, 90s cap). When the job reaches a terminal state, returns the structured result including the full authorities[] list (citation detections + verified vLex links). If the poll times out (job still queued/running after 90s), returns the current in-progress state so the LLM can tell the user the job is still processing and offer to check again. Returns: an `AuthorityMatchResult` with `authorities[]` populated on completion, or `error` populated on failure. Common errors: - 404: the job_id is malformed, expired (jobs TTL after 4 hours), or doesn't belong to the user's organization.
get_authority_match
Read Vincent's formatted conversation in its native message order. This is the data source for the live MCP App. Unlike ``get_conversation_messages``, it does not project, filter, or reverse the formatted conversation payload. ``status`` rides alongside it because the raw ``conversationStatus`` cannot be read as one: it is absent unless the org holds the status-indicator flag, and when present it is stored, so a ``working`` outlives the run that set it. Either way the panel would say "working" forever.
get_live_conversation
Read back the document review table a conversation built. Use it to check what a review actually produced: which documents became rows, which questions became columns, and what each cell says. Building a table reports success as prose, so this is the only way to confirm the rows are the ones expected — a collection search that matched two documents of nineteen still reads as a table that was built. Cells fill in after the rows appear, so an empty cell means that question is still being answered for that document, not that the answer is empty. Read again rather than reporting a blank as a finding. Raises when the conversation has no table, which is itself the answer: the build did not happen.
read_review_table
Search vLex for legal documents and get the hits back directly. Use this for a lookup: finding a case or statute, checking what exists on a point, gathering candidates to read. It answers in one round trip. Prefer it over start_research whenever the user wants *documents* rather than analysis — starting a conversation for a lookup costs minutes of agent work. Use start_research instead when the user wants Vincent to reason: a legal question answered, a document drafted or reviewed, an argument tested. Those need the agent, and it does its own searching. `total_count` is how many matched, not how many came back: say so rather than implying the results are exhaustive. Each hit's `vid` reads the full text via get_legal_document. Report `snippet` and `summary` as extracts, never as the document's holding — and never present a hit as good law on this evidence. Write the hits into your visible reply, each with its link. A host may also render them as a card, but that card can end up folded inside a collapsed step, so a reply that only says "I found some cases" leaves the user with nothing. `formatted` is the hits already built into a numbered, linked list: use it directly when the user wanted a list, and as the source of the links when your answer is prose.
search_legal_documents
Attach a document to Vincent. Read the result: there are two outcomes. Read the bytes yourself and pass them base64-encoded. Which upload path is open depends on the account, so **branch on what comes back** rather than assuming: - `file_id` set → the document stands alone. Pass it to `start_research(file_ids=[...])`, `continue_conversation(file_ids=[...])` or `match_authority(file_id=...)`. `status` is `pending`, because ingest runs on after the upload; confirm with get_file_status that it reads `available` first, or the run gets a record with no text behind it. - `conversation_id` set → the account is on the legacy path, where a document can only arrive *inside* a conversation. There is no `file_id` and `match_authority` cannot be used. Continue THAT conversation with `continue_conversation`; do not start a new one, or the document is not in it. On that legacy path the request itself takes one of two shapes, and you choose which by whether you pass `conversation_id`: leave it blank and the document opens a conversation of its own, which is where a fresh "here is my contract" goes; pass the id of a run already going and the document joins that one, with no turn spent. Either way the next call is `continue_conversation` — that is what asks the question, since attaching alone runs nothing. Always pass `size_bytes`. Bytes ride inside this call, and a host that truncates a long tool argument does it silently — that is how an earlier version of this tool uploaded a 306-byte fragment of a 220 KB PDF to S3 as a working file. The size you declare is checked against what arrived, so a truncated argument fails here instead of corrupting a document. Send only what the user asked you to send, and for a file too large to survive a tool argument, ask them to upload through Vincent and give you the id.
attach_document
Show the documents Vincent generated in a conversation. Call this whenever the user asks what Vincent produced or wants a document, rather than retyping the list into chat. The card lets the user pick a document and download it as DOCX or PDF. For which cases or statutes an answer relied on, call show_cited_authorities instead: authorities have their own card.
show_documents
Show every authority a conversation cited, as a card. Call it when the user asks which cases or statutes an answer relied on, and at the end of a run that did any research: the authorities are what a lawyer checks first. It reads the conversation's own authority panels, so it reports what Vincent actually cited rather than what you remember it citing — never assemble this list yourself. One call covers the whole conversation, however many turns it took, so call it once at the end rather than per turn. Write the list into your visible reply too. `formatted` is it already built, because the card can end up folded inside a collapsed step and a reply that only says "here are the authorities" then leaves the user with nothing. Common errors: - 404: the conversation does not exist or does not belong to this user.
show_cited_authorities
Send the next turn in a Vincent conversation and drive it to a decision. Two uses: 1. A follow-up question on an existing conversation. 2. Answering a `"clarification"` interruption in chat: put the questions to the user and send their answer as the message, which is what resumes the run. There is no message_id to pass — this tool mints its own. NOT for a `"task_submission"`: naming the proposed tasks in a message starts a new, unrelated piece of work and abandons the proposal. Use submit_tasks, which selects by index. Returns the same `TurnResult` as start_research — read `state` and handle `interruptions` exactly the same way; see that tool for the full protocol. Arguments: - `conversation_id` (required): the conversation to continue. - `message` (required): the user's text. Cannot be empty. - `file_ids`: files to attach to this turn, from `attach_document`. Do not send a turn while one is already running — if a previous call returned `"still_running"`, call watch_conversation until it settles. A second turn on a busy conversation is refused with 409. A 409 right after `attach_document` means something else: a document Vincent could not read leaves its conversation parked, and no amount of waiting opens it. Tell the user the file could not be read — a scan needs OCR first — rather than watching or retrying.
Read where a Vincent conversation currently stands, without driving a turn. Use it when: - a turn returned `"still_running"` and you want one cheap look at where it got to — watch_conversation is the better answer when you mean to wait, and the only one that can show an external-tool request; - the user asks what happened in a conversation from earlier. Returns the same `TurnResult` as start_research, so read `state` the same way. `"still_running"` means Vincent is genuinely still working. Pacing, if you do poll: wait about 5 seconds before the first re-check, then roughly double the wait each time up to about 30 seconds. If it is still running after a few minutes, tell the user it is taking longer than usual and offer to check again — do not spin silently. Prefer a driven turn where you can have one: watch_conversation and the turn-running tools stream progress and return on settlement, which is both faster and cheaper than this loop. Never invent or summarize an answer while `state` is `"still_running"`. Common errors: - 404: the conversation does not exist or does not belong to this user.
Resolve an interruption Vincent is parked on and drive the resumed turn. Use this for the two interruption kinds that carry an `interruption_id`: - `"tool_approval"` → send `decision="approve"` or `decision="reject"`. Only carrying the decision and `scope` the USER gave you. Ask them first: there is no card, so nothing else records that they were offered the choice. A second submission is a duplicate — handled gracefully, but the earlier decision is the one that stands. - `"external_tool"` → Vincent asked *you* to run the tool named in the interruption. Run it, then send its output as `result`. `result` may be any JSON value except a bare `null`, which Vincent treats as unanswered — if the tool genuinely returned null, say so in `message` instead. Send what the tool returned, not a summary of it. If you cannot run it, send `decision="reject"` with a `message` saying why. Clarifications have no `interruption_id`: answer those with continue_conversation instead. Returns the same `TurnResult` as start_research — read `state` and handle any further `interruptions` the same way; see that tool for the full protocol. Arguments: - `conversation_id` / `interruption_id` (required): straight from the interruption. - `decision`: "approve" or "reject", for a tool approval. - `scope`: "this_call" approves only this call; "conversation" approves the same tool for the rest of the conversation. Use "conversation" only when the user said so, and only when the interruption's `allowed_scopes` contains it — Vincent downgrades anything it does not allow. - `message`: a note to Vincent, most useful when rejecting. - `result`: the external tool's output.
Start a Vincent research conversation and return its live conversation. This call returns promptly with the conversation id so the live MCP App can mount and follow Vincent while it works. Read `state`: - `"completed"` → `answer` is Vincent's answer. Show it. Any documents it drafted are listed in `files`; read one with get_output_document. - `"needs_user"` → Vincent is parked. For each entry in `interruptions`, act on its `kind`: - `"tool_approval"` → tell the user what is being approved, using the interruption's `tool_name`, `tool_summary`, `arguments_preview` and `allowed_scopes`, and get their answer. Then respond_to_interruption with the decision and scope THEY chose. Do not decide for them. - `"clarification"` → put the `questions` to the user, then continue_conversation with their answers in prose. - `"external_tool"` → you are being asked to run the tool. Do it, then return the output with respond_to_interruption(result=...). - `"task_submission"` → Vincent has proposed follow-up work. Put the proposal to the user, then submit_tasks with the indices they chose. Never continue_conversation: that starts unrelated work and abandons the proposal. Whichever path resolves it, the run picks up from there. - `"still_running"` → the turn outlived this call's budget. The live MCP App continues updating in the parent conversation, so do not automatically call watch_conversation and block that turn. Use it only to collect the final answer in chat or when the host cannot render the app. Do not start another conversation. - `"error"` → report `error` as a failure, never as Vincent's answer. Arguments: - `question` (required): what the user wants researched, drafted or reviewed, in their own terms. Every conversation runs on Vincent's agentic agent, which picks its own tools — there is no workflow to choose. - `collection_id`: scope the research to one collection; see list_collections. - `jurisdiction`: the governing jurisdiction as a country code ("US", "GB", "CA", ...). Pass it whenever the user names one; Vincent otherwise researches unscoped or asks. - `matter_id`: associate the conversation with a matter. - `file_ids`: files to attach, from `attach_document`. Confirm each is `available` with get_file_status first. - `initial_approval_keys`: approvals to pre-grant so the run does not stop for them; discover the valid keys with list_approval_keys. Pre-grant only what the user actually asked to be allowed — never a blanket list to save turns. - `unattended`: set True only when no human is watching, e.g. a scheduled job. - `locale`: response language, default "en".
Cancel the turn Vincent is currently running in a conversation. Call this only when the user asks to stop, cancel, or abandon a run — never because a turn is taking a while. The conversation survives; a stopped run just ends where it got to, and the user can send another turn afterwards. `stopped` is False when there was nothing running. That is a benign outcome, not an error: say the run had already finished rather than reporting a failure. Read get_conversation_messages afterwards to see what Vincent kept. Common errors: - 404: the conversation does not exist or does not belong to this user.
Submit the proposed tasks the user picked, and drive the run that follows. This is how a `"task_submission"` interruption is resolved. Vincent proposes follow-up work as a list of tasks; the user chooses which of it to run, and this call sends that choice back and returns the resulting turn. Selection is by INDEX: a proposed task has no id until it is submitted, so pass the `index` values from the interruption's `tasks`. Never answer a task proposal with continue_conversation. That posts a new question instead, which starts a fresh piece of work and abandons the proposal — the tasks the user chose are then never run. There is no card for this: list the proposed work, ask which of it they want, and submit their answer here. Returns the same `TurnResult` as start_research — read `state` and handle any further `interruptions` the same way; see that tool for the full protocol. Arguments: - `conversation_id` (required): the conversation holding the proposal. - `message_id` (required): the interruption's `message_id`, which is the proposal message's own id. Submitting replaces that message in place. - `selected_task_indices` (required): the `index` of every task to run. Must name at least one; tasks left out are recorded as not selected.
Resume waiting on a turn Vincent is already running, without sending anything. This is what to call after a turn returned `"still_running"`, in place of polling: it re-attaches to the live run and returns when the turn actually gets somewhere, streaming progress the same way start_research does. Nothing is posted, so it cannot start a second turn or double-charge the user, and it is safe on a busy conversation. Prefer it to repeated get_conversation_messages calls. An `"external_tool"` interruption — Vincent asking YOU to run a tool — reaches us only on the live stream, so a poll can never show one: a run parked on one looks simply busy forever. Reconnecting is the only way to see it. Returns the same `TurnResult` as start_research, `interruptions` included, so read `state` and resolve them exactly the same way. `"still_running"` again means the run outlived this call's budget too — call this once more. Use get_conversation_messages instead when you only want a cheap glance at where a conversation stands and do not intend to wait. Common errors: - 404: the conversation does not exist or does not belong to this user.
How do I improve a ChatGPT Plugin's discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Clio alternatives on ChatGPT?
As of 2026-09-21, Clio competes with AI Attorney, AL WAKEELO, Alizé, Appealbase, Açık Silivri Havadis, BIA Edge, Bizora Tax Research, CiteCheck, CiteLaw, CourtListener, Craime, Descrybe Legal Engine, DirectCase Legal Research, eCFR MCP, ElevenFlo, F-AI Contract Template Finder, Folium Jurisprudencia Chilena, Fontis, GovQuery, GovScanner, Harvey, IAJUS, IFG, Juridata, JurisAI-ICIDA, Lawstronaut, Legal Data Hunter, Legalcode, LegisGraph, LegisRatio, Letra da Lei, Lexplorer Swiss Tax Research, LeyNova, LibreJustice, MAK Immigration Source Guide, Midpage Legal Research, Nylon, OpenRegs: Regulatory Research, Policy Doctor, realLaw AI, Red Judicial, Remedy Legal, Simpliciter AI, Special Education Law, TaxGraph, TaxMCP, Tesea, Trellis Law, Trifolia, UniCourt, Vasara, Vitark in ChatGPT Legal Research Engines, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.