clio
Read-only access to the Clio Manage API (matters, contacts, activities/time entries, bills, documents, tasks, calendar, custom fields) for the firm's Clio account. Use when the user asks about Clio data, pulling matters/contacts/bills from Clio, clio.com, checking time entries, or anything needing Clio API access. Read-only by construction — this skill never writes.
Source: .opencode/skills/clio/SKILL.md — site rebuilt 2026-09-05.
Clio (read-only)¶
Credentials¶
- Source of truth:
CLIO_CLIENT_ID,CLIO_CLIENT_SECRETand the OAuth tokens live in opencode's auth store at~/.local/share/opencode/auth.jsonunder thecliokey, exactly likegoogle/mistralare stored there for the OCR skills. - Never print, log or paste the client secret, access token or refresh token. Use the store.
- If the entry is missing, run the one-time setup below. Do not improvise credentials.
- Region matters: the firm uses the EU endpoint (
eu.app.clio.com) unless the account is elsewhere.regionis read from the stored entry.
One-time setup (run once per machine)¶
- Make sure the app in the Clio developer account (developer.clio.com) has:
- OAuth scopes limited to read-only (
e:-prefix scopes such ase:matters e:contacts e:activities e:bills e:documents e:tasks e:calendar_entries— noc:/u:/d:scopes). Permissions are set on the app in the developer portal; Clio does not take a scope parameter at authorize time. - The redirect URI
https://app.clio.com/oauth/approvalregistered on the app (Clio's special desktop-app redirect — no local server needed; the auth code appears in the browser URL after approval). - Open in a browser:
https://eu.app.clio.com/oauth/authorize?response_type=code&client_id=<CLIENT_ID>&redirect_uri=https%3A%2F%2Fapp.clio.com%2Foauth%2Fapproval - Approve, then copy the
code=...value from the browser address bar and exchange it immediately (codes expire after 10 minutes) withtools/oauth_setup.py --code <CODE>(reads client id/secret from the auth store) — or exchange by hand with a POST tohttps://eu.app.clio.com/oauth/token(grant_type=authorization_code, plus client_id, client_secret, code, redirect_uri=https://app.clio.com/oauth/approval). - Tokens land in
auth.jsonunderclio. Access tokens last ~30 days; the client auto-refreshes with the (never-expiring) refresh token — one-time handshake.
Usage (read-only)¶
Query via tools/clio_client.py (auto-refreshes the access token, only ever issues GETs):
python .opencode/skills/clio/tools/clio_client.py whoami
python .opencode/skills/clio/tools/clio_client.py matters [--id 123] [--query "name like \"smith\""] [--fields id,name] [--limit 25] [--page 1]
python .opencode/skills/clio/tools/clio_client.py contacts [--type client|vendor,..] [--query ...]
python .opencode/skills/clio/tools/clio_client.py activities [--matter-id 123] [--from 2025-01-01] [--to 2025-12-31]
python .opencode/skills/clio/tools/clio_client.py bills [--id 456] [--state draft|pending|approved,..] [--date-from ...]
python .opencode/skills/clio/tools/clio_client.py documents [--limit ...]
python .opencode/skills/clio/tools/clio_client.py tasks / calendar_entries / users / custom_fields
python .opencode/skills/clio/tools/clio_client.py get /v4/matters/<id> # any read path
- Clio wraps responses in
{"data": [...], "meta": {...}}; the client unwrapsdatabefore printing. - The API is region-scoped: EU tenant data comes from
https://eu.app.clio.com/api/v4/. - Permissions are read-only at the client level too: the tool rejects anything that is not a GET.
- Remember Clio's own rule: a user can only see what their Clio role permits — if the authorising user cannot see bills in Clio, the API won't return them either.
Limitations¶
- Clio's default
limitis 25 per page (max 100) — use--limit/--pageor theLinkheader for full pulls. - This skill is read-only by design. For write access a separate higher-scoped app would be needed — not provided here.