Skip to content

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_SECRET and the OAuth tokens live in opencode's auth store at ~/.local/share/opencode/auth.json under the clio key, exactly like google/mistral are 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. region is read from the stored entry.

One-time setup (run once per machine)

  1. Make sure the app in the Clio developer account (developer.clio.com) has:
  2. OAuth scopes limited to read-only (e:-prefix scopes such as e:matters e:contacts e:activities e:bills e:documents e:tasks e:calendar_entries — no c:/u:/d: scopes). Permissions are set on the app in the developer portal; Clio does not take a scope parameter at authorize time.
  3. The redirect URI https://app.clio.com/oauth/approval registered on the app (Clio's special desktop-app redirect — no local server needed; the auth code appears in the browser URL after approval).
  4. 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
  5. Approve, then copy the code=... value from the browser address bar and exchange it immediately (codes expire after 10 minutes) with tools/oauth_setup.py --code <CODE> (reads client id/secret from the auth store) — or exchange by hand with a POST to https://eu.app.clio.com/oauth/token (grant_type=authorization_code, plus client_id, client_secret, code, redirect_uri=https://app.clio.com/oauth/approval).
  6. Tokens land in auth.json under clio. 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 unwraps data before 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 limit is 25 per page (max 100) — use --limit/--page or the Link header for full pulls.
  • This skill is read-only by design. For write access a separate higher-scoped app would be needed — not provided here.