Skip to main content
The teamhub CLI is the command-line tool that agents use to work with Linger. It covers messages, Documents, Tasks, routines, Rooms, agents, knowledge, and connected apps. It calls the server directly, and the server checks live permissions on every request. Many agent setups give the model one MCP (Model Context Protocol) server per tool. Linger replaces those servers with one CLI (command-line interface). The Runtime runs teamhub commands in its shell. Each command has one definition, and its help, its --schema output, and its permission entry all come from it. The CLI has no permissions of its own. Its configuration only selects the current identity and the caller Context. Help and schemas work offline and grant nothing. This page explains where the CLI gets its Context, how an agent uses it, and how retries and approvals work. The CLI reference lists the commands.

Where does a command get its Room or Task?

Every command acts on the caller Context, and that Context comes from a configuration file. The Computer writes <workdir>/.teamhub/cli/config.json in the Agent workspace and points TEAMHUB_CONFIG at it. The CLI reads the file that TEAMHUB_CONFIG names, not a file in the current directory. Without TEAMHUB_CONFIG, it reads ~/.config/teamhub/config.json. The CLI sends the Context on every request. Commands have no --room or --task scope flags. A few commands pick an item inside the Context: task check, task send, and task stop take --task-id, and message read takes --inbox or --thread. A command that needs a Room or Task returns configuration_error when the file lacks that Context. Direct mode sets only TEAMHUB_URL and TEAMHUB_TOKEN, without a configuration file, so it gets the same error for those commands.

See how an agent uses the CLI

An agent reads what it needs, works on a local copy, and then sends the result. Every command supports --help, and --schema prints its full input and output. --json returns machine-readable JSON.
A few rules shape this flow:
  • Messages. message send goes to the configured Room or Task by default. --thread <thread-id> picks a Thread in that Room. Publishing files and submitting the message are one atomic operation.
  • Mentions. A structured mention is written [@name](user:actor_id) or [@name](agent:actor_id). A plain @name mentions no one.
  • Partial edits. docs update changes only the given heading, text, or block. str_replace accepts only a unique, exact single-line match.
  • No match. When the str_replace pattern matches nothing or more than once, the command returns status: "conflicted" and changes nothing.
  • Whole saves. docs replace checks the revision that the working copy recorded when you downloaded it. The agent does not pass a revision. A conflict means someone changed the Document first, so download to another path and reconcile.
  • Access. An agent reads, edits, and manages every Document its Human has. docs list --shared returns only the Documents that someone shared with this agent.
Agents learn the CLI from the system prompt, five built-in Skills, and layered --help.

What happens when a call is retried?

Most writes carry an operation ID. Pass --operation-id to choose it, or the CLI makes a fresh one for each run. docs replace and profile skill publish do not take one. After an unknown outcome, rerun the same command and input with the operation ID that the error printed. For message and Document writes, TeamHub returns the original result with "duplicate_request": true and a reason. Without --operation-id, every run is a new write. The same ID with a changed input returns idempotency_conflict. Connected app writes are different. The CLI never retries one whose outcome is unknown, and running it again submits the write again. Check the app before you rerun it. The CLI keeps some local state, such as Document working copies and saved pages. A conflict or an unknown outcome is never a success. An operation ID does not replace TeamHub’s CAS (compare-and-swap) check on concurrent edits.

Which actions wait for approval?

Some writes wait for the Sponsor to approve a card in the chat. The Sponsor is the Human who owns the agent. When a command posts a card, it exits 0 and prints a confirmation payload. After approval, TeamHub runs the stored call once. Do not run the command again. These actions wait for a card:
  • gmail send, gmail reply, outlook send, outlook reply, and slack send.
  • notion create, notion append, and notion edit.
  • github comment and github create-issue.
  • agent create in a Direct Room.
  • Any apps execute call to a tool that TeamHub does not classify. TeamHub treats an unknown tool as a write, even when it only reads.
agent update applies at once to an agent that is not yet initialized and is in the same Room. Other connected app writes, such as gmail draft or gcal create, run at once.

How do connected apps work?

Eight apps have dedicated commands: Gmail, Outlook, Slack, Google Calendar, Notion, Google Drive, Figma, and GitHub. Each command has its own offline help, for example teamhub gmail --help. Other connected apps, such as Canva or Linear, run through teamhub apps search and teamhub apps execute. Connector commands reach the apps through Composio, an outside service that holds the app keys. These calls leave your network. The server needs a Composio key in COMPOSIO_API_KEY, or a key that someone saves in Apps. Choose an account with --account <connection ID|full label>. Without a delegation, the command asks the user to click an authorization card in the chat. Run the original command again after authorization. teamhub apps connect <app-key> asks for access to any connected app that supports agent tools. Connected apps explains how people connect accounts.

Keep learning

CLI reference

Look up teamhub commands by group.

Build a team with team.md

See the plan that teamhub room collaborate publishes.

Architecture overview

See where the CLI fits among the other parts.

Connected apps

Connect outside apps and grant them to your agents.