Use Sensei from your agent / Sensei CLI

Sensei CLI.

Install the Sensei CLI to start chat sessions, follow turns and manage projects from your terminal or a script. You need Node.js 22.18 or later. Install it with npm, sign in with an API key, and every API command that returns a body prints JSON you can pipe into jq.

Integrate Kosuke puts the CLI, the MCP server and one prompt to paste into your agent on one page.

Install

npm install -g @kosuke-ai/kosuke
kosuke --version

Sign in

  1. Create an API key in Settings > You > API keys. See Authentication.
  2. Run kosuke auth login and paste the key when it asks. What you type stays hidden.
  3. Sensei checks the key and saves it. It prints a line such as Logged in to https://app.kosuke.ai; member of 2 workspaces. API key saved to /home/you/.config/kosuke/credentials.json.

kosuke auth status get shows where the key comes from and whether Sensei accepts it. kosuke auth logout deletes the stored key.

In CI or any script that runs without a person, skip the login. Set the KOSUKE_API_KEY environment variable to the key, or pass --api-key <token> to any command. A key from a flag or the environment wins over the stored one.

Inside a chat sandbox, where the credential is a sandbox agent token, the tree narrows to the operations that token may call. The same holds in a Cron Run, where the credential is the run's own key. The tools of the connected integrations, the workspace's and, in your own turns, yours, are there too: see Run integration tools.

The MCP server does not need this key: your agent's client signs you in through the browser instead, though it also accepts an API key as a bearer token.

Your first commands

# 1. Find the project's id.
kosuke projects list --json | jq '.data[] | {id, name}'

# 2. File a task, note its task id, then start it.
kosuke tasks create <orgId> --hint-project <projectId> \
  --title "Fix footer typo" --description "Fix the typo in the pricing page footer"
kosuke tasks start <orgId> <taskId> --project-id <projectId> --skill ship

# 3. Follow the turn until it ends, printing what the agent says.
kosuke sessions jobs watch <projectId> <sessionId> <jobId> \
  | jq -r 'select(.type == "message") | .data.text'

tasks create saves Todo work. tasks start starts its execution. The older sessions create --status backlog remains supported.

How commands work

  • Ids are positional arguments, in the order the help shows, such as kosuke sessions get <projectId> <sessionId>. A command that takes a project id and then a session id also runs with the session id alone, or with --session-id <id>: kosuke sessions get <sessionId> looks the project up first. A command whose session id is a flag, such as kosuke sensei sessions facts get, also takes it as its first positional argument.
  • Request fields are flags, such as --title, --content or --exclude-archived.
  • --body '<json>' sends a whole request as JSON. --body-file <path> reads it from a file, and --body-file - reads it from stdin. A few commands, such as projects env-vars create, take only a whole body.
  • --attach <path> attaches a file. Repeat it for several files. sessions create, sessions send, sessions prompt update, sessions queue update, deploys start, deploys queue update and files set take files. files set takes one file of up to 25 MB, the others up to 10 MB each.
  • Every API command that returns a body prints JSON to stdout, with the result under data; one whose request answers 204 prints nothing. In a terminal the JSON is indented. Piped into another program or a file, it is compact: one line, with each row of a data list on its own line. --pretty prints it indented anyway. Errors go to stderr, and the command exits with 1.
  • --json, or KOSUKE_OUTPUT=json in the environment, asks for the platform's whole JSON. Pass it in any script that reads the output with jq.
  • The lists are short without it: projects list, sessions list, tasks list, crons list, activity list, sensei threads list, sensei cards list and files list print at most 20 rows, each with the fields you pick a row by, and a last line on stderr such as 20 of 3122. More: --cursor <c>. --all reads every page, --full keeps every field, and --fields picks from whole rows.
  • --fields id,title,chatSession.id prints only those fields, per row of a list, or of the list the answer holds (such as the crons of crons list), else of the object. A dot reaches into a nested object. A field no row has exits with 1 and names the closest fields. --format compact prints a header line, then one tab-separated line per row, with nulls empty and times to the second; what sits beside the rows, such as the next cursor, goes to stderr. --fields also works with --json.
  • Times in the JSON are ISO 8601 in UTC, for scripts to parse. user usage get and workspaces usage breakdown get count calendar days in your own timezone unless you pass --tz. When your timezone cannot be read they count UTC days and say so on stderr.
  • --repository takes owner/repo, such as --repository acme/storefront, or the JSON {"owner":"acme","name":"storefront"}.
  • --help works at every level. kosuke sessions --help lists the group's commands, and kosuke sessions send --help lists that command's flags, one line each. --help --long prints each description in full.
  • kosuke help --compact lists every command you can run with its arguments, one line per group, in about 4,000 characters. An agent reads it once in place of many --help calls.
  • An unknown command or flag names the closest one: a mistyped lst after kosuke sessions qa runs answers Did you mean ...? with the commands of that group.

Find a session

kosuke find <query> finds sessions in one call. The query is a pull request number such as 3323 or #3323, a session id, a task id, or words of a title such as "compact view". It prints one line per match, with the workspace, project, session, your Sensei Thread that follows it, its task, its pull request number and the head commit Sensei last saw.

kosuke find 3323
kosuke find "compact view" --json | jq -r '.data[] | "\(.projectName) \(.sessionId) #\(.pullRequestNumber)"'

It searches what kosuke sessions list shows you: every workspace you belong to, or the token's own workspace inside an agent's turn.

Command reference

Tasks

CommandPositional argumentsPurpose
tasks list<orgId>Filter one workspace with --status, --owners, --priorities, --project, --q, and --labels '["bug","ui"]' (up to 20 names, matching any).
tasks listnoneAll caller workspaces, with --status, --q and --labels '["bug","ui"]'.
tasks labels list<workspaceId>List label names and colors across the workspace's repositories.
tasks create<orgId>--title, --description; optional --priority, --owner-id, --hint-project, --reason, --start-when-deployed, `--sandbox-size small
tasks get<orgId> <taskId>Read a task.
tasks update<orgId> <taskId>Edit --title, --description, --priority, --owner-id, `--status todo
tasks start<orgId> <taskId>--project-id; optional --skill ship, --sandbox-size, --app-stack.
tasks project set<orgId> <taskId>--project-id; optional --if-revision. Moves a Todo task and its Backlog session to another deployed repository of the workspace, in place. Nothing starts.

The tables list the main commands, not every one. kosuke help --compact lists every command, and kosuke <group> --help every command in a group.

auth

CommandArgumentsWhat it does
auth loginnoneStore an API key after checking it works
auth status getnoneShow where the key comes from and whether Sensei accepts it
auth logoutnoneDelete the stored key

projects

CommandArgumentsWhat it does
projects listnoneList the projects you can reach, across every workspace
projects get<projectId>Read one project
projects createnoneImport a GitHub repository with --repository-url and --name, or make a repository from kosuke-starter with --description. With an import, --prompt files its first task, which starts when the first deploy lands
projects update<projectId>Rename a project
projects delete<projectId>Delete a project and everything it owns. Admins only
projects merge-agent get<projectId>Read the Merge agent's mode, goAhead and waitForQa. Only mode off means it is off; the output has no enabled
projects merge-agent set<projectId>Change the Merge agent's --mode, --go-ahead (member or checks) or --wait-for-qa. The older --no-enabled still works and means train; --enabled is refused
projects versions list<projectId>List the Versions of a repository with the kosuke-starter layout
projects releases list<projectId>List its Releases
projects merge-agent model set<projectId>Pick the model the Merge agent's next run starts on, or default
projects branches list<projectId>List the repository's branches
projects skills list<projectId>List the skills the agent can run in the project, for one provider
projects labels list<projectId>List the project's Session Labels
projects settings get<projectId>Read setup commands, services, environment and sandbox size
projects settings update<projectId>Change the QA Guide with --qa-guide or the device folders with --device-write-paths. Setup commands, branches, working directory and sandbox size get 403, see below
projects settings set<projectId>Replace services and environment from a kosuke.config.json file. Gets 403, see below
projects settings changes list<projectId>Read the project's Change history, newest first. Environment values are never kept
projects qa-guide set<projectId>Save the project's QA Guide from --content
projects services list<projectId>List the services in the order they start
projects services create<projectId>Add a service. Gets 403, see below
projects services update<projectId> <serviceId>Change a service. Gets 403, see below
projects services delete<projectId> <serviceId>Remove a service. Gets 403, see below
projects env-vars create<projectId>Add environment variables. Gets 403, see below
projects env-vars delete<projectId>Remove environment variables. Gets 403, see below

Only a workspace admin changes a project's setup, services and environment, in the web or desktop app. The CLI signs in with an API key, so the commands marked 403 above, and deploys start, get 403 SETTINGS_ADMIN_ONLY for every member, admins included, until API keys get a project settings scope. Reads still work. See What only the web app can do.

An import with a first task looks like this. The task starts on /kosuke:ship when the first deploy lands.

kosuke projects create --org-id <workspaceId> --name storefront \
  --repository-url https://github.com/acme/storefront \
  --prompt "add a footer"

A repository from kosuke-starter starts from a sentence. See Preview and publish. While Start from kosuke-starter is off on the deployment, --description is refused with 403 KOSUKE_STARTER_OFF and makes no repository.

kosuke projects create --org-id <workspaceId> --description "A booking page for my yoga classes"

sessions

CommandArgumentsWhat it does
sessions list<projectId>List a project's chat sessions
sessions listnoneList sessions across every workspace. --labels '["bug","ui"]' matches any selected label.
sessions searchnoneSearch sessions by title
sessions get<projectId> <sessionId> or <sessionId>Read a session with its latest turn and pull request
sessions create<projectId>Start a session, or add one to the Backlog with --status backlog
sessions start<projectId> <sessionId>Start a Backlog session
sessions app-stack start<projectId> <sessionId>Start the project's services in a session that skipped its App stack, and wait until they answer
sessions env sync<projectId> <sessionId>Deliver the project's current environment variables to a running session sandbox and restart its services. Refused while a turn runs
sessions update<projectId> <sessionId>Change the title, status, model, Assignee or priority, and, while the session is in the Backlog, its --sandbox-size and --app-stack. Once the session started those two are fixed: 409 SANDBOX_SETTINGS_LOCKED
sessions delete<projectId> <sessionId>Delete a session
sessions labels set<projectId> <sessionId>Replace the session's Session Labels
sessions labels update<projectId> <sessionId>Add and remove Session Labels, leaving the rest
sessions prompt update<projectId> <sessionId>Rewrite a Backlog session's prompt and attachments
sessions send<projectId> <sessionId>Send a message. It starts a turn, or waits Up next
sessions messages list<projectId> <sessionId>Read the conversation with tool calls and subagents as stored previews. --limit reads the newest messages, and --before the page older than an olderCursor
sessions messages get<projectId> <sessionId> <messageId>Read one message with every block as recorded. --agent-output compact keeps each subagent's last output entry
sessions jobs watch<projectId> <sessionId> <jobId>Follow a turn until it ends
sessions runtime-commands run<projectId> <sessionId>Run /clear or /compact
sessions jobs list<projectId> <sessionId>List the session's turns
sessions jobs get<projectId> <sessionId> <jobId>Read one turn's status
sessions jobs cancel<projectId> <sessionId> <jobId>Stop a running turn
sessions queue list<projectId> <sessionId>List the messages Up next
sessions queue update<projectId> <sessionId> <queuedMessageId>Edit your own message Up next
sessions queue move<projectId> <sessionId> <queuedMessageId>Move your own message within Up next
sessions queue steer<projectId> <sessionId> <queuedMessageId>Steer your own message into your running turn
sessions queue delete<projectId> <sessionId> <queuedMessageId>Delete a message Up next
sessions queue resume<projectId> <sessionId>Resume a paused Up next
sessions diff files list<projectId> <sessionId>List the files the session's branch changes
sessions diff patch get<projectId> <sessionId>Read the changes as patches
sessions diff commits list<projectId> <sessionId>List the commits on the session's branch
sessions diff comments list<projectId> <sessionId>List the line comments on the changes
sessions diff comments create<projectId> <sessionId>Comment on a range of lines
sessions diff comments update<projectId> <sessionId> <commentId>Edit your own line comment, or resolve or reopen any
sessions diff comments delete<projectId> <sessionId> <commentId>Delete your own line comment
sessions sandbox-files list<projectId> <sessionId>List the files in the session's sandbox
sessions sandbox-files get<projectId> <sessionId>Read one file. Wake the sandbox first
sessions sandbox-files set<projectId> <sessionId>Write one file
sessions git state get<projectId> <sessionId>Read whether the sandbox has uncommitted changes, unpushed commits, or commits ahead of the base branch
sessions files list<projectId> <sessionId>List the session's files: what its agent wrote, a deleted one as a row, then the files its ticket points at
sessions files get<projectId> <sessionId> <fileId>Read one file of the session, by its id or its name
sessions files attach<projectId> <sessionId>Point a Backlog session at a file of the project's Files, without copying it. --file <path> names a file, or a folder whose files are all attached

deploy

CommandArgumentsWhat it does
deploys start<projectId>Start a Deploy, or answer the deploy agent. Gets 403 SETTINGS_ADMIN_ONLY: a workspace admin does it in the Deploy Chat
deploys cancel<projectId>Stop the running Deploy
deploys list<projectId>List the project's Deploys
deploys messages list<projectId>Read the Deploy Chat and the current Deploy status
deploys messages get<projectId> <messageId>Read one Deploy Chat message with every block as recorded. --agent-output compact keeps each subagent's last output entry
deploys model set<projectId>Pick the deploy agent's model
deploys queue list<projectId>List the Deploy Chat messages Up next
deploys queue update<projectId> <queuedMessageId>Edit your own message Up next
deploys queue move<projectId> <queuedMessageId>Move your own message within Up next
deploys queue steer<projectId> <queuedMessageId>Steer your own message into the running deploy turn
deploys queue delete<projectId> <queuedMessageId>Delete a message Up next
deploys queue resume<projectId>Resume the Deploy Chat's paused Up next

preview

CommandArgumentsWhat it does
preview get<projectId>Read the preview addresses of the main preview, or of a session with --session-id
preview health get<projectId>Read the health of each service behind a preview
preview sandbox reset<projectId>Kill a preview's sandbox so Sensei creates a new one
preview share get<projectId>Read a preview's share link, if it has one
preview share create<projectId>Create a preview's share link
preview share delete<projectId>Revoke a preview's share link
preview shared get<slug>Open a share link. Needs no API key
preview shared-files get<slug> <fileId>Read a file behind a share link. Needs no API key

files

A workspace's shared Files. A path is folder names and a file name joined by / from the workspace root, such as prototypes/board/a-columns.html.

CommandArgumentsWhat it does
files list<workspaceId>List one folder, folders first, with its breadcrumb. --folder takes a folder id or a path and defaults to the root
files get<workspaceId> <fileId>Read one item's details and its url. A text file of up to 1 MB includes its body. Any other file includes a short-lived downloadUrl and its expiresAt
files set<workspaceId>Write a file by --path, creating the folders on the way. --text gives the content inline and --attach <path> a local file. A file of the same name is replaced and its version counts up. --if-version <n> refuses the write with 409 when the file is on another version. --media-type overrides the type
files set<workspaceId>With --parent-id <folderId> and --name <name> in place of --path, write into a folder by its id
files folders create<workspaceId>Create a folder by --path, with the folders above it
files move<workspaceId> <fileId>Rename with --name, move with --parent-id <folderId>, or both. To move to the root, send --body '{"parentId":null}'
files delete<workspaceId> <fileId>Delete a file, or a folder with everything in it

Each command prints the item's url, which opens it in Files. A sandbox, a Cron Run and Sensei can list, read, write and move. Their instructions tell them not to delete, though their credentials reach files delete. A folder Sensei keeps and a locked file refuse every caller. A Quick Question from Spotlight can list and read only. A key reaches only the workspaces its owner belongs to.

kosuke files set <workspaceId> --path notes/plan.md --text "# Plan"
kosuke files set <workspaceId> --path designs/home.png --attach ./home.png
kosuke files list <workspaceId> --folder designs

user files

Your personal Files, which belong to you and to no workspace. Only you see them. They take the same paths, flags and limits as a workspace's files commands, with no workspace argument.

CommandArgumentsWhat it does
files list personalnoneList one folder of your personal Files, folders first, with its breadcrumb. --folder takes a folder id or a path and defaults to the root
files get personal<fileId>Read one item's details and its url. A text file of up to 1 MB includes its body. Any other file includes a short-lived downloadUrl and its expiresAt
files set personalnoneWrite a file by --path, or by --parent-id and --name, creating the folders on the way. A file of the same name is replaced; --if-version <n> refuses a stale replace
files folders create personalnoneCreate a folder by --path, with the folders above it
files move personal<fileId>Rename with --name, move with --parent-id <folderId>, or both
files delete personal<fileId>Delete a file, or a folder with everything in it. Only your API key can. A sandbox, a Cron Run, Sensei and a Connected App cannot

An agent reaches the personal Files of the member it acts as: Sensei, a chat session agent in a Turn that member sent, a Cron Run of their Personal Cron, and the Slack agent answering them. An agent acting as the workspace is refused. A Connected App's Connector Token reaches them as your API key does.

kosuke files set personal --path notes/ideas.md --text "# Ideas"

crons

CommandArgumentsWhat it does
crons list<workspaceId>List a workspace's crons. --project keeps the ones that include a project
crons get<workspaceId> <cronId>Read one cron with its projects
crons create<workspaceId>Create a cron. --project names a project and repeats for several; leave it out for a cron that runs with no repository
crons update<workspaceId> <cronId>Change a cron. --project replaces its projects, --no-enabled pauses it and --enabled resumes it. A cron disabled with "No projects left" stays disabled until an update picks a project
crons delete<workspaceId> <cronId>Delete a cron with its runs and transcripts. Their files stay in Files
crons run<workspaceId> <cronId>Fire a cron once now, in every project that is not paused or in the ones --project names
crons runs list<workspaceId> <cronId>List a cron's runs. --project and --status filter them and repeat for several
crons runs get<workspaceId> <cronId> <runId>Read one run with its Reply and the sessions it filed
crons runs messages list<workspaceId> <cronId> <runId>Read the Cron Agent's transcript of one run
crons files list<workspaceId> <cronId>List the files all of a cron's runs wrote
crons runs files list<workspaceId> <cronId> <runId>List the files a run wrote
crons runs files get<workspaceId> <cronId> <runId> <fileId>Read one file of a run
crons runs cancel<workspaceId> <cronId> <runId>Stop a run that is still going

workspaces

CommandArgumentsWhat it does
workspaces listnoneList the workspaces you belong to
workspaces get<workspaceId>Read a workspace and your role in it
workspaces members list<workspaceId>List members and pending invitations
workspaces credits get<workspaceId>Read the credit balance and limit
workspaces usage get<workspaceId>Read sandbox usage by day and by project
workspaces sandbox-limit get<workspaceId>Read how many sandboxes may run at once, and which are running
workspaces sandboxes stop<workspaceId>Pause the sandboxes of the sessions you name
providers access get<workspaceId>Read which providers you, or the workspace, can run
providers get<workspaceId>Read the workspace's Credentials, with secrets masked
providers set<workspaceId>Store or switch workspace Credentials. Admins only
providers delete<workspaceId>Remove one set of workspace Credentials. Admins only
providers usage get --provider claude_code<workspaceId>Read the workspace Claude login's usage
providers usage get --provider codex<workspaceId>Read the workspace Codex login's usage
providers usage get --provider coding_plan<workspaceId>Read the workspace GLM Coding Plan's usage
providers usage get --provider kimi_code<workspaceId>Read the workspace Kimi Code key's usage
providers usage get --provider deepseek_api<workspaceId>Read the workspace DeepSeek API key's balance
providers logins start --provider claude_code<workspaceId>Start a Claude login for the workspace. Admins only
providers logins complete --provider claude_code<workspaceId>Finish a Claude login with the code from the browser. Admins only
providers logins start --provider codex<workspaceId>Start a Codex login for the workspace. Admins only
providers logins complete --provider codex<workspaceId>Finish a Codex login once the code is approved. Admins only
skills list<workspaceId>List the workspace's Custom Skills
skills get<workspaceId> <skillId>Read one Workspace Skill with its files
skills create<workspaceId>Add a custom skill from its files. Admins only
skills update<workspaceId> <skillId>Turn a skill on or off, or replace a custom skill's files. Admins only
skills delete<workspaceId> <skillId>Delete a Custom Skill and its files. Admins only
plugins list<workspaceId>List the plugins the official marketplaces offer, and which are on
plugins update<workspaceId> <pluginId>Turn a Workspace Plugin on or off. Admins only
integrations connections list<workspaceId>List the workspace's integrations with their status
integrations connections get<workspaceId> <toolkit>Read one integration by toolkit slug, such as sentry
integrations connections delete<workspaceId> <toolkit>Disconnect an integration. Admins only

user

CommandArgumentsWhat it does
user profile getnoneRead your account and preferences
providers get personalnoneRead your Claude, Codex, GLM Coding Plan, Kimi Code and DeepSeek API Subscriptions and your Default Model
providers delete personalnoneDisconnect your Subscription for the provider --provider names
providers usage get personalnoneRead your Subscription's usage, or a DeepSeek API key's balance
providers keys set personal<provider>Connect your GLM Coding Plan, Kimi Code or DeepSeek API with its key
providers default-model set personalnoneSave your Default Model
providers logins start personal --provider claude_codenoneStart connecting your Claude Subscription
providers logins complete personal --provider claude_codenoneFinish connecting it with the code from the browser
providers logins start personal --provider codexnoneStart connecting your Codex Subscription
providers logins complete personal --provider codexnoneFinish connecting it once the code is approved
skills list personalnoneList your Personal Skills
skills get personal<skillId>Read one Personal Skill with its files
skills create personalnoneAdd a Personal Skill from its files
skills update personal<skillId>Turn a Personal Skill on or off, or replace its files
skills delete personal<skillId>Delete a Personal Skill
plugins list personalnoneList the plugins you can turn on for yourself
plugins update personal<pluginId>Turn a Personal Plugin on or off
integrations connections list personalnoneList your own integrations with their connections
integrations connections delete personal<toolkit>Disconnect one of your own integration connections, named with --connection-id
crons create personalnoneCreate a Personal Cron, up to 50 per member. --project names your Personal Repositories and repeats for several. With some, it runs in its own sandbox and needs a Model of its own on any released provider, using your own Subscription; with none, it runs in its Sensei Thread
crons update personal<cronId>Change a Personal Cron, its projects included. Removing every project returns it to its Sensei Thread
crons delete personal<cronId>Delete a Personal Cron with its runs and transcripts; its files stay in Personal Files. Only your API key can. A sandbox, a Cron Run and Sensei cannot

integrations

CommandArgumentsWhat it does
integrations listnonePrint each toolkit that has connections, with the connections and how many read and write tools it has. --toolkit <slug> lists that toolkit's tools, --search <text> keeps the tools whose name or description mention the text, --account <account> keeps what one connection offers
integrations tools get<name>Print one tool's input schema. --account picks a connection
integrations call<name>Run one tool with --args '<json>', --args-file <path> or - for stdin. --account picks a connection. --file <argument>=<path> uploads a local file, up to 5 GiB, for a file argument, such as videoFilePath=./clip.mp4 or attachment.0=./report.pdf, and repeats for several. Waits up to 330 s for the answer, as long as the platform lets a call run
integrations request<toolkit>Send one request to a Composio toolkit's own API through your connection, for an action no listed tool does. --method is GET, POST, PUT or PATCH, --path is relative to the API base URL integrations list --toolkit <slug> prints, with --query name=value and --body-file <path> beside it. --purpose is one required line on what no listed tool does, with no names, emails or event titles. A write that gets no answer exits 1 and is never sent again
integrations uploads createnoneReserve one file's upload for a tool that takes files, and print the file reference and the URL to PUT the file to. integrations call --file does this for you

sensei

CommandArgumentsWhat it does
sensei chat getnonePrint your own Sensei Chat as JSON: its latest page and its Turn. --before <messageId> prints the older messages before that one
sensei cards listnoneList your open cards in every workspace, in the order of Needs you: a teammate waiting on you, your blocked builds, failures, merges, then messages. --workspace <id> keeps one workspace's cards. --thread <threadId> lists a thread's open, sending and decided cards. Members get every decided card; Sensei's token gets those closed in the last 7 days. --since <ISO time> keeps decided cards placed at or after that time (postedAt or, if absent, createdAt); open and sending cards always return. Only member credentials can read decision messages
sensei cards setnoneOpen a card in the thread of a Sensei Turn, or update the open card with the same key. Only a Sensei Turn runs it, with --body-file holding the headline, blocks, instruction, verb, the negative button's own label and tone when the default Reject or Dismiss misdescribes it, links, target and state key
sensei cards schema[field]Print every field sensei cards set takes, with its rules and, for a JSON field, its shape. sensei cards schema blocks prints one field
sensei threads get<threadId>Read a Sensei Thread as text: the member's messages, Sensei's replies and each card's headline. --tools adds the tool calls and their results. --since <messageId> prints only the replies after that one, and --before <messageId> the ones before it
sensei sessions facts get<sessionId>Read a session this thread follows: its pull request's head, checks, mergeable, mergeStateStatus, reviewDecision, reviewRequests and isDraft, its QA report, and the revision an assessment names. Only a Sensei Turn runs it
sensei cards closenoneClose the open card with --key, naming the --revision read and a --reason. Only a Sensei Turn runs it
sensei device-requests listnoneList the device requests of --session-id, with whether you may answer each one. Only you or a Sensei Turn you started run it
sensei device-requests updatenoneApprove or decline the device request --request-id of --session-id as you, with --decision approve or decline. Only you or a Sensei Turn you started run it, the Turn only after your own yes or no; a session's agent or a Cron is refused
sensei tickets mergenoneFold the Todo drafts named by --fold into the one named by --keep, with the merged text from --content-file, refused when a prompt changed since the --revisions read. Only a Sensei Turn or you run it
sensei messages sendnoneSend one message to a member's Sensei, for any sender: your API key, your own Sensei Turn when you ask, a Cron Run or a chat session's agent. The body names memberId, projectId (or sessionId), a key and the text, and optionally a pullRequest, title, why, paths and an https or Sensei link. The recipient's Sensei draws a card whose button carries out the text, or opens the link. The same key with new text updates that card; pass ifRevision to be refused when it moved on
sensei messages movenoneSend a message from a cron or an agent on to another member. Only a Sensei Turn runs it
sensei connect-buttons createnonePut Connect buttons in a message of your Turn's own thread, under your words, for each connection the request needs: github, toolkit:<slug> or `subscription:claude_code
sensei suggestions createnonePut suggestion pills in a message of your Turn's own thread, under your words. A tap fills the member's reply; an item with "newThread": true starts a thread of its own. Only a Sensei Turn runs it
sensei repository-cards createnonePut the Repository card in a message of your Turn's own thread, naming --workspace <workspaceId>: it lists the repositories Sensei can write to, and the member imports one from it. Only a Sensei Turn runs it
sensei describe-cards createnonePut the Describe card in a message of your Turn's own thread, naming --workspace <workspaceId>: the member writes what to build and creates it as a repository from kosuke-starter. Only a Sensei Turn runs it, and it is refused with 403 KOSUKE_STARTER_OFF while Start from kosuke-starter is off on the deployment

github, models, activity and agent

CommandArgumentsWhat it does
github connection getnoneRead your GitHub Connection
github repositories listnoneList the repositories the Kosuke App can reach through your connection
models listnoneList the models a chat session can use, as the values --model takes
activity listnoneList Activity across your workspaces. --unseen keeps only New events
agent summary getnonePrint a short digest of what needs you, for an agent to read

Run integration tools

kosuke integrations lists, describes and runs the tools of the connected integrations. kosuke integrations list is an overview: one block per toolkit with the scope, label, account, short id and alias of each connection, and how many read and write tools the toolkit has. The kosuke agent summary get digest lists the same connections. Add --toolkit <slug> to see a toolkit's tools, tools get <name> for a tool's schema, and call <name> --args '<json>' to run it. A list that is cut short says how many of how many it shows. call exits 0 when the tool ran, 1 when the tool or the platform reported an error (a write whose outcome is unknown says not to retry), and 2 when the command itself was used wrongly, such as an API key without --workspace. The hidden kosuke integrations tools list and kosuke integrations tools call print the raw JSON of the same two routes.

When a toolkit has several connections, pick one with --account: its alias such as notion-personal, its short id or full id, or scope:label such as personal:Engineering. Case, curly quotes and extra spaces do not matter. A bare personal or workspace works when exactly one connection of that scope can run the tool. A missing or ambiguous account is refused with the choices, one per line with its alias, and every call prints the connection it ran on (alias, scope, label and account) on stderr, beside the tool's text on stdout.

Inside a chat sandbox, a Cron Run or a Sensei turn, the turn's credential decides what you reach, as in Who can use a connection. Sensei with no workspace named uses your personal integrations and the Personal space’s workspace integrations. Naming a workspace uses that workspace’s integrations plus your personal ones, never the Personal space’s. Personal Crons use the Personal space’s integrations plus yours; Workspace Crons and Deploy Chat use workspace integrations only. Restricted integrations need a grant for the call’s workspace, Personal included.

From your laptop with an API key:

  • list and tools get need --workspace <workspaceId>. You must belong to that workspace. They show its connections and your own personal ones. With no shared workspace, name your Personal space’s id; the flag is still required.
  • call runs your own personal connections only. A call on a workspace connection is refused: workspace connections run only inside an agent's turn.
  • A Connector Token from the MCP server is refused for all three.
kosuke integrations list --workspace <workspaceId>
kosuke integrations list --workspace <workspaceId> --toolkit gmail
kosuke integrations call notion_search_notion_page --workspace <workspaceId> --account notion-personal --args '{"query":"roadmap"}'

Follow a turn with sessions jobs watch

kosuke sessions jobs watch follows one turn as it runs, so a script does not have to poll. The job id is the chatJobId that sessions create and sessions send print when they start a turn. A send that waits Up next prints a queuedMessageId instead. Each event is one JSON line on stdout. Messages meant for a person go to stderr.

If the connection drops, watch reconnects and picks up where it left off. When the turn ends, a last watch.links line carries the session, preview and pull request links. If some events could not be read, a watch.status line says "complete": false.

FlagWhat it does
--timeout <seconds>Stop waiting after this many seconds and exit with 124
--type deployFollow a Deploy turn instead. The job id is the activeStreamId that kosuke deploys messages list prints
Exit codeMeaning
0The turn ended, or stopped to ask you a question
1The turn failed or was stopped
3The API key was refused
4The project, session or turn was not found
124--timeout passed before the turn ended

Use it with your coding agent

The MCP server covers most of what a coding agent needs. A few things only the CLI does:

  • Attach a file, with --attach.
  • Print every event of a turn as it happens, with kosuke sessions jobs watch.
  • Read your own Sensei Chat, with kosuke sensei chat get.

Give your agent a digest

kosuke agent summary get prints a digest of about 1,500 tokens for an agent to read. Its first line gives the time in your own timezone, named, such as 2026-11-05 09:12 Europe/Rome. When your timezone cannot be read it gives UTC and says so. It lists:

  • the chat sessions that need you
  • your connected Subscriptions and their usage across every released provider, and with --workspace that workspace's AI providers too
  • with --workspace (inside an agent's turn, its own workspace), the connected integrations, one line each: toolkit, alias, scope, label and account. A long list ends with "and N more", and a refused or failed read says so rather than leaving the section out
  • your oldest New Activity events, one line each
  • the workspaces it read

It marks seen only the events it prints. The rest stay New for kosuke activity list --unseen. Add --workspace <id> to cover one workspace, or --peek to mark nothing seen.

To have your coding agent start from it, paste this line into your AGENTS.md or CLAUDE.md:

Before you answer anything about my Sensei work, run `kosuke agent summary get --peek` and read what it prints.

Configuration

SettingFlagEnvironment variableDefault
API key--api-key <token>KOSUKE_API_KEYThe key kosuke auth login stored
Sensei address--api-url <url>KOSUKE_API_URLhttps://app.kosuke.ai
Config foldernoneKOSUKE_CONFIG_DIR$XDG_CONFIG_HOME/kosuke, else ~/.config/kosuke. On Windows, %APPDATA%\kosuke

A flag wins over its environment variable, and both win over the stored key. The stored key is credentials.json in the config folder, readable only by you.

Update

Run the install command again, then check the version:

npm install -g @kosuke-ai/kosuke
kosuke --version

Next steps

Use kosuke sensei threads close <threadId> to mark a thread Done. Open cards, running replies and messages waiting Up next prevent it. Threads have three states: Needs you, Working and Done; event lines and Receipts do not make them unread.