rimo-cli
Use the `rimo` CLI to interact with the Rimo platform — list/read/search meeting notes, transcripts, and documents, ask AI questions across them, and create notes or append markdown sections to them. Trigger when the user mentions Rimo, asks about meeting notes/minutes/transcripts/documents stored in Rimo, or invokes `rimo` directly.
インストール方法を見る含まれるファイル(1)
- SKILL.md22.7 KB
SKILL.md(原文)
インストールする前に、エージェントに与えられる指示の中身を確認できます。
rimo CLI Skill
This skill teaches AI coding agents (Claude Code, Codex, and others) how to use the rimo command-line tool to access Rimo meeting notes, transcripts, documents, and AI-powered Q&A — all from the terminal.
rimo is purpose-built for both humans and AI agents:
- JSON-first on stdout (a few narrow plain-text exceptions, see §3 below).
- Errors are JSON too, on stdout — exit code distinguishes success from failure.
- Field filtering (
--fields,--excludes) is a first-class feature so responses stay small. --dry-runsimulates writes without side effects.
If anything below is out of date with the installed binary, prefer rimo <command> --help.
Using this skill
This skill works with any AI agent that can read markdown documentation and execute shell commands.
With Claude Code
Recommended — install the rimo plugin. It ships this skill in one step:
/plugin marketplace add rimo/cli
/plugin install rimo@rimo
Or drop the skill file in manually — Claude Code auto-discovers skills placed in either of these locations:
# Project-local (recommended for team-shared usage — commit to your repo)
mkdir -p .claude/skills/rimo-cli
curl -fsSL https://raw.githubusercontent.com/rimo/cli/main/skills/rimo-cli/SKILL.md \
-o .claude/skills/rimo-cli/SKILL.md
# Or user-global (available across all your projects)
mkdir -p ~/.claude/skills/rimo-cli
curl -fsSL https://raw.githubusercontent.com/rimo/cli/main/skills/rimo-cli/SKILL.md \
-o ~/.claude/skills/rimo-cli/SKILL.md
Then just ask naturally in Claude Code:
"Summarize my Rimo notes from this week" "Find my Rimo notes about the Q3 release plan"
Claude Code loads the skill automatically when it detects a Rimo-related request.
With Codex (or other AI agents)
For agents that don't auto-load skills, point them at this file at the start of a session:
# Hand the skill to the agent as context
cat ~/.claude/skills/rimo-cli/SKILL.md
Or include the contents of this file in the agent's system/initial prompt. Any agent that can run shell commands and read documentation can follow the operating manual below.
Prerequisites
Make sure rimo is installed and you have an authenticated session:
# Install
curl -fsSL https://rimo.app/cli/install.sh | sh
# Authenticate — opens your browser, token is saved securely in the OS keyring
rimo auth login
# Verify
rimo auth status
Agent operating manual
Everything below is intended for the AI agent driving the CLI.
1. Check before doing anything
rimo version # confirm the binary exists, see the installed version
rimo auth status # confirm there is an authenticated account
If rimo is not on PATH, stop and tell the user to install it:
curl -fsSL https://rimo.app/cli/install.sh | sh
(Or download the archive for their OS/arch from https://github.com/rimo/cli/releases, verify it against the published checksums.txt, and put rimo on their PATH.) Do not try to install it silently.
2. Authentication
The recommended way to authenticate is rimo auth login. It opens the browser, completes a secure consent flow, and stores the token in the OS keyring. Tokens auto-refresh transparently on every call, so the agent does not need to manage refresh.
Recommended: rimo auth login (browser-based)
In an interactive session with a user present, it is fine to run rimo auth login yourself — just walk the user through it. The flow:
- You run
rimo auth login. - The CLI opens the user's default browser to authorize this CLI.
- The user signs in if needed and approves the request.
- On success the CLI prints a JSON line to stdout (
{"status":"logged_in", ...}), stores the token in the OS keyring, and sets the new account as active. You can proceed with the original task.
If the user is on a machine without a usable browser (SSH, container, headless CI), run rimo auth login --no-browser instead: the CLI prints a URL, the user opens it on any other device, approves, and pastes the short code from the page back into the terminal.
If rimo auth login takes more than ~10 minutes the code expires — re-run if the user is still with you.
When to instead ask the user to run it themselves:
- Non-interactive agent run (no human attached to relay the stderr code) —
rimo auth loginwill hang. Bail out and tell the user. - User declines — never push.
Token resolution order (first hit wins)
--account <alias>flag → keyringactive_accountin~/.config/rimo/config.yaml→ keyring- Otherwise the command exits 1 with a JSON error to stdout — run
rimo auth login(or ask the user to)
If already authenticated
Just use it. rimo auth status confirms which account is active and its token_status (valid / expiring_soon / expired / unknown). Tokens auto-refresh transparently on each call.
Other account ops (only when the user asks)
rimo auth status # JSON list of accounts + token_status
rimo auth switch <alias|email|org> # change active account
rimo auth logout [--account <id>] # revoke + remove
3. Output contract
| Surface | Format |
|---|---|
| Success (default) | JSON on stdout |
| Errors | JSON on stdout (always, regardless of mode) |
rimo version | Plain text on stdout |
rimo upgrade | Plain text on stdout; progress on stderr |
rimo note get --transcript / --document / --full / --meeting-chat / --document-id | Plain text on stdout |
rimo note ask <question> | Plain text on stdout (streamed); Sources: / Fetch a note: blocks follow |
Everything you pipe to jq is safe except the plain-text exceptions above. For plain-text modes, treat stdout as opaque markdown/text.
4. Error format
Any failure writes a JSON error to stdout and exits with code 1:
{ "code": "error", "message": "unknown flag: --bogus" }
code is currently always error. Inspect message for the cause
(validation text, API status, etc.) and surface it to the user. Treat the
exit code (0 vs non-zero) as the reliable success/failure signal — do not
parse message for control flow.
5. Commands you can use today
rimo note list
rimo note list # notes owned by the authenticated user
rimo note list --attended # notes the user attended
rimo note list --team <id> # a team's notes across all members
rimo note list --today # notes held today (JST)
rimo note list --week # notes held in the trailing 7 days (JST)
rimo note list --team <id> --since 2026-06-01 --until 2026-07-01 # held_at range
rimo note list --updated-since 2026-06-08 # changed since last sync (incremental)
rimo note list --page-size 50
rimo note list --attended --page-size 50 --page-token "<cursor>"
rimo note list --fields id,title,created_at # smaller payload
--team <id>lists a team's notes across all members (you must be a member). Get IDs fromrimo team list.--since/--untilfilter by meeting time (held_at, falling back to creation time);--updated-sincefilters by update time. Dates areYYYY-MM-DD(JST) or RFC3339;--untilis exclusive.--attendedcannot combine with--teamor the date filters.--today/--weekare JST shortcuts that expand into--since/--until(today, or the trailing 7 days). They cannot be combined with--since/--until, with each other, or with--attended.- All modes are cursor-paginated via
--page-size/--page-token. - Response shape:
{ "notes": [...], "next_page_token": "..." }. Loop untilnext_page_tokenis empty when you need everything.
rimo note get
Default mode = metadata JSON (backend gets meta=true, so it's cheap).
Note ID, not URL. This command (and every other rimo note ... command that takes an ID) accepts only the raw note ID, never a URL. If the user pastes a link like https://rimo.app/notes/iYEMKt5JzQATX6pozGvF, the ID is the path segment after /notes/ — here iYEMKt5JzQATX6pozGvF. Strip the prefix yourself before calling the CLI; do not pass the URL.
rimo note get <note_id> # metadata JSON
rimo note get <note_id> --fields id,title # filter the metadata JSON
rimo note get <note_id> --transcript # plain text: "Speaker: content" lines
rimo note get <note_id> --transcript --timestamps # same, prefixed "[HH:MM:SS] " (elapsed from recording start)
rimo note get <note_id> --document # plain text: primary document markdown
rimo note get <note_id> --full # plain text: transcript + document
rimo note get <note_id> --meeting-chat # plain text: "[HH:MM] sender: text" Zoom/Meet chat
rimo note get <note_id> --list-documents # JSON list of attached documents
rimo note get <note_id> --document-id <doc_id> # plain text: specific document markdown
Mutually exclusive groups (combining them is rejected with an error):
--list-documents/--document-id⛔--transcript/--document/--full--list-documents⛔--document-id--meeting-chat⛔--transcript/--document/--full/--list-documents/--document-id--timestampsrequires--transcriptor--full(it decorates transcript lines only, and applies to the transcript half of--full)
When the user asks "summarize this Rimo note", the cheapest correct flow is usually:
rimo note get <note_id> --full # one call, transcript + document as text
rimo note search
Find notes by semantic similarity (default), or by keyword and attribute filter. Returns JSON in the same {notes, total_count} shape as rimo note list — use this when you want a list of candidate notes. Use rimo note ask when you want a synthesised answer instead.
rimo note search "release plan" # semantic (default)
rimo note search "release plan" --limit 5 # cap semantic results
rimo note search "release" --mode=filter --per 5 --content-type transcripts
rimo note search "release" --mode=filter --team T_abc123 # keyword, scoped to a team
rimo note search --mode=filter --team T_abc --since 2026-04-01 # filter-only browse (query omitted)
rimo note search "release" --fields id,title | jq '.notes'
Flags:
| Flag | Mode | Meaning |
|---|---|---|
--mode | both | semantic (default, meaning-based) or filter (keyword and/or attribute search + pagination). |
--limit | semantic | Max results (defaults to server-side). |
--page | filter | 1-based page number (defaults to 1). |
--per | filter | Page size (defaults to 10, max 100). |
--content-type | filter | Restrict to all/transcripts/headings/annotations/title/document. |
--team | filter | Restrict to one or more teams (repeatable / comma-separated; IDs from rimo team list). |
--participant | filter | Restrict to notes with these participant user IDs (repeatable / comma-separated). |
--note-tag | filter | Restrict to notes with these tag IDs (repeatable / comma-separated). |
--since | filter | Only notes held on or after this date (YYYY-MM-DD as JST, or RFC3339). |
--until | filter | Only notes held before this date (same formats as --since). |
In --mode=filter the query argument is optional — omit it to browse by filters alone. Passing a filter-only flag with --mode=semantic is rejected with an error. A hit carries id plus whatever the search index returned: both modes populate title, held_at, created_at, and filter mode adds owner_name and snippet. In --mode=filter total_count counts the whole result set, not just this page; in --mode=semantic it is the number of notes returned. A Fetch a note: hint is written to stderr so stdout stays pipe-clean for | jq.
rimo note ask
The only command that calls the LLM. Streams a synthesised plain-text answer drawn from the user's notes.
rimo note ask "what did we decide about Q3 pricing?"
rimo note ask "今週の議事録を要約して"
No flags — the model is fixed server-side. Output structure:
<streamed plain-text answer, multiple lines>
Sources:
- <note_id> <title>
- <note_id> <title>
Fetch a note:
rimo note get <note_id> --document # markdown
rimo note get <note_id> --transcript # speaker: text
rimo note get <note_id> # metadata JSON
other IDs in this result: <id> <id> ...
Inline [xxxxx] chunk-ref citations the model emits are stripped from the visible answer — treat the Sources: block as the canonical citation surface. Pipe the IDs from there into rimo note get when the user wants to drill in.
Choose between search and ask:
rimo note search— when the user would open the returned notes one by one and read them.rimo note ask— when the user wants a single answer extracted from across notes.
rimo note create — writes
Creates a note with no recording attached, plus a primary document for editing. Only run this when the user explicitly asks to create a note. Requires a token with the notes:write scope.
rimo note create # empty, auto-titled note
rimo note create --title "Blog draft" "# Intro" # seeded with markdown
rimo note create --markdown-file draft.md --team team_abc # from a file, in a team
cat draft.md | rimo note create --markdown-file - # from stdin
rimo note create --title "Blog draft" --dry-run # preview, creates nothing
- Markdown comes from the positional argument or
--markdown-file(-= stdin), never both. Omit it for an empty note. - Other flags:
--title(defaults to a timestamp),--team(ID fromrimo team list; omit for a personal note),--locale(e.g.ja-JP). - Response shape:
{ "note": {...}, "document": {...} }. Keep both IDs —rimo note appendneeds the note ID and the document ID. - Errors:
400(bad body, unsupportedlocale, disabled channel),403(not a member of that team).
rimo note append — writes
Merges markdown into an existing note's document as a new section, preserving heading and list structure. Only run this when the user explicitly asks to add content to a note. Requires edit access to the note and the notes:write scope.
rimo note append <note_id> <document_id> $'## Action items\n- Ship the release notes'
rimo note append <note_id> <document_id> --markdown-file section.md
rimo note append <note_id> <document_id> --position start "## Summary" # prepend
rimo note append <note_id> <document_id> "## Notes" --dry-run # preview
- The markdown is required — positional argument or
--markdown-file(-= stdin), not both. - Get the document ID from
rimo note get <note_id> --list-documents(or fromnote create's output). --positionisend(append, the default) orstart(prepend).- Response shape:
{ "document": {...} }— checkexport_markdownto confirm what landed. - Errors:
400(empty markdown, bad--position),403(no edit access),404(unknown note/document),409(note or document locked).
Both write commands support --dry-run, which returns a mocked response and sends no request. Use it to show the user what would happen when you're unsure.
rimo version / rimo upgrade
Plain text. rimo upgrade downloads the latest release over HTTPS and verifies its checksum before replacing the binary — no GitHub login or extra tooling is required, and there is no flag to pin or downgrade. Do not run rimo upgrade autonomously — let the user trigger it.
rimo team list
rimo team list # all teams in your org
rimo team list --page-size 20 --page-token "<cursor>"
rimo team list --fields id,name # smaller payload
rimo team list --include-organization # also the org's own folder
- Cursor-paginated via
--page-size/--page-token. - Response shape:
{ "teams": [...], "next_page_token": "..." }. Loop untilnext_page_tokenis empty when you need all teams. --include-organizationalso returns the organization's own folder — a real folder whoseidis the organization's id. It is left out by default, andcategory(teamororganization) tells the two apart. It is added to the first page only, so that page carries one row more than--page-size.- Requires an org account — returns an empty list or 403 for personal workspace tokens.
Support under development
The following commands are planned but not yet available — support is under active development. If the user asks for one of these, let them know it is coming soon and avoid calling them:
rimo note delete,rimo note sharerimo team create,rimo team delete(and other team write operations)rimo user *rimo transcribe *rimo commands(introspection)
6. Global flags — use these to keep responses small
| Flag | Use |
|---|---|
--fields | "" (all), "compact" (long strings → "[omitted]"), or "f1,f2,..." |
--excludes | Drop noisy fields (e.g. transcript,document_markdown) — applied after --fields |
--dry-run | Simulate a write (note create, note append) — returns a mocked response, sends no request |
--account | Override default account |
--pretty | Human-readable tables instead of JSON — for people, not for you; see below |
rimo note list --fields compact
rimo note list --fields id,title,created_at
rimo note list --excludes transcript,document_markdown
Do not pass --pretty when you are the one reading the output. It renders a
terminal table sized to the current window, which means values get truncated to
fit and the layout is not a stable contract. Parse the JSON instead, and narrow
it with --fields. Suggest --pretty only when the user says they want to read
the result themselves — e.g. "just show me my meetings this week" — and then
give them the command to run rather than running it and relaying the table.
7. Recipes
"List my recent notes":
rimo note list --fields id,title,created_at | jq '.notes[:10]'
"Show the transcript of note X":
rimo note get <note_id> --transcript
"Summarize note X": fetch transcript + document, then summarize from the text yourself.
rimo note get <note_id> --full
"What meetings did I attend last week?": the CLI does not interpret relative dates — you must convert "last week", "yesterday", etc. into absolute YYYY-MM-DD values yourself (using today's date from your context), then filter with jq.
# Step 1: compute the absolute date range from today.
# Example — if today is 2026-05-28 (Thu), "last week" spans 2026-05-18 (Mon) → 2026-05-24 (Sun).
# Step 2: pull the attended notes and filter on created_at.
rimo note list --attended --page-size 50 --fields id,title,created_at \
| jq '.notes[] | select(.created_at >= "2026-05-18" and .created_at < "2026-05-25")'
The same pattern works for any time range — always substitute the absolute start/end dates, never pass relative phrases to jq or the CLI.
"Find me notes about X": prefer search (cheap, list back) over ask (LLM, single answer).
rimo note search "<topic>" --fields id,title
"Find notes from the <team-folder name> folder": a team-folder name shown in the app
(e.g. "Voicy_Public_Recordings"; users may also say "room" or "channel") is a team name,
not searchable text — passing it to note search's free-text query silently returns
unrelated notes, not an error. Resolve the name to a team id via rimo team list, then
filter by --team.
rimo team list --fields id,name | jq '.teams[] | select(.name | test("<room name>"; "i"))'
rimo note search --mode=filter --team <team_id> --fields id,title,held_at # browse, newest first
rimo note search "<topic>" --mode=filter --team <team_id> --fields id,title,held_at # keyword search within the room
If the user instead pastes a https://rimo.app/channels/<id>_team URL, the team id is the
<id> segment directly — no need to call rimo team list.
"What did we decide about X across all our meetings?": this is the ask case.
rimo note ask "<question>"
8. Things NOT to do
- ❌ Don't run
rimo auth loginin a non-interactive context (CI, headless, no human attached) — it blocks on Enter and a browser flow. In an interactive session it's fine; see §2. - ❌ Don't hit the Rimo backend with raw
curl— userimo. The CLI handles token resolution, refresh, and error normalization. - ❌ Don't assume
note delete/note share/team create/team delete/user */transcribe *work — support is still under development. (rimo team listis available.) - ❌ Don't ignore the exit code. JSON on stdout + nonzero exit = error, not data.
- ❌ Don't pipe
--transcript/--document/--full/--meeting-chat/--document-id/note ask/version/upgradeintojq— those are plain text on stdout. - ❌ Don't try
--yesor any confirmation-skip flag — they don't exist. Safety is enforced via token scopes. - ❌ Don't create or modify notes on your own.
rimo note createandrimo note appendwrite to the user's workspace — run them only on an explicit request, and prefer--dry-runfirst when the target is ambiguous. - ❌ Don't run
rimo upgradeon your own — let the user decide when to update. - ❌ Don't pass relative dates ("last week", "yesterday") to
jqfilters or CLI flags — convert to absoluteYYYY-MM-DDfirst.
9. When in doubt
rimo --help
rimo <command> --help
rimo <command> <subcommand> --help
Every command supports --help and follows the conventions above.
レビュー
まだレビューはありません。使ってみた感想をお寄せください。