Skip to content

Connect agents to Company OS ​

How to connect coding agents and terminals (Claude Code, Codex, OMP, Cursor, Windsurf, Gemini CLI, other MCP clients, the Tern terminal plugin, and remote clients such as Grok) to Company OS, and how each connection is governed.

Company OS owns company identity, policy, approvals, and the ledger. The agent brings its own model. Connecting an agent never gives it approval authority.

Commands use companyos (the package also installs company-os; same CLI). In a source checkout, ./company-os runs the same verbs.

1. Connection or governed run ​

These are three different things.

Companion MCP connectionOMP read-only profileGoverned run (AgentChat)
ClientsClaude Code, Codex, Cursor, Windsurf, Gemini CLI, generic MCPOMP, opened by handOMP TUI opened by companyos chat
Commandcompanyos connect <client>companyos connect ompcompanyos chat
IdentityHost principal commissioned by the Company Passport; credential in HSMII_HOMEYour CLI session (companyos login), bound to one companyA run admitted by the Company OS host
ToolsCompany OS MCP catalog, limited by the host principal's scopes7 read toolsRun-grant-limited MCP profile plus a native action guard
MutationsAllowed per tool; each needs confirm=true by default; the host still enforces policy and approvalsNoneEach tool call is authorized by the host before it runs and settled after
ReceiptsOrdinary ledger records for calls the host acceptsNone; not an accountable runHost authorization and settlement receipts, plus the run execution ledger

What connecting gives an agent:

  • Governed Company OS tools: tasks, memory, the tool catalog workflow, run events, trace queries, approval and HITL endpoints, and the Gestion Velora customer-intake and email handoff. tool-definitions.ts defines 75 tools (my count); 47 are classed read-only. HSM_COMPANY_OS_MCP_TOOLS (comma-separated names, at most 40) narrows what a server registers.
  • Company context: the server publishes an operator contract at MCP initialization (identify, understand, govern, simulate, authorize, execute, verify, record). Read-only work stops after grounded understanding; mutations must leave independently verified task-trail evidence.
  • Results in a hsm.company_os.result.v1 envelope with a Markdown fallback. A successful call is not treated as verification.
  • Approvals stay human (section 4).

What connecting does not give an agent: a run grant, per-action receipts, or any way to decide an approval. A manual OMP session from connect omp "remains read only and does not create an accountable run."

A governed run: companyos chat admits a terminal run through the host, then opens the installed OMP TUI in the current directory. Each governed MCP callback sends its signed run grant to the host's capability-actions/authorize route before the tool handler runs, and the host settles the exact action afterward. It checks scope, expiry, company, run status, grant issuance, revocation, and a matching unsettled action receipt before dispatch.

Known limit (docs/company-os/OMP_GOVERNED_DRIVER.md, evidence from 2026-10-03): the host action boundary was shown (an authorized and settled read; a native shell write denied before the effect, with a pending approval), but model-step receipts and turn receipt parity were not. The terminal client "must not advertise a complete governed receipt until a fresh installed run returns one from the host."

Runtimes Company OS can drive ​

The reverse direction: Company OS launching a vendor CLI. These adapter manifests exist in src/company_os/adapter_protocol.rs; the external runner contract is in docs/company-os/EXTERNAL_ADAPTER_LANE.md.

Vendor CLI adapters: vendor_cli:codex (Codex CLI), vendor_cli:claude_code (Claude Code CLI), vendor_cli:gemini (Gemini CLI), vendor_cli:opencode (OpenCode adapter), and vendor_cli:openclaw (OpenClaw 2.0 Agent CLI).

An external worker (webhook or bridged) lets any runner compute and report back through Company OS APIs. OMP is driven through companyos chat.

2. Quick start per client ​

Prerequisites: Node 20 or later. For OMP and Tern, a CLI session:

bash
companyos login --company COMPANY_ID
companyos login --device          # headless: open the shown Console URL, enter the code

login runs an Authorization Code + PKCE request in the Console and creates a separate scoped CLI worker: a one-hour access credential and a rotating refresh credential, of which only the refresh envelope is stored.

Claude Code, Codex, Cursor, Windsurf, Gemini, generic ​

bash
npx --yes @hsm/company-os-mcp-server connect codex
npx --yes @hsm/company-os-mcp-server connect claude
# or, with the CLI installed:
companyos connect claude|codex|cursor|windsurf|gemini|generic \
  [--project-dir PATH] [--install-dir PATH] [--api-base URL] [--open] [--no-start]

The README describes the npx form as available "after the package is published". connect:

  1. Runs the installer and Compose definition embedded in that exact npm release, pulls the matching versioned Company OS image, starts Postgres and hsm_console in companion mode, and verifies ledger health (/api/company/health must report Postgres ok). It fetches nothing mutable from the source repository.
  2. Writes companyos.integration.json in the project directory, then merges a company-os entry into the client's MCP configuration, keeping other servers.

No provider key or model setting is requested; the host supplies its own model.

FlagEffect
--no-startDo not start the stack; only regenerate host configuration. Use when the stack already exists.
--project-dir PATHDirectory to write configuration into. Default: current directory. Windsurf's file is global, so it is not affected.
--api-base URLCompany OS API origin written to the config. Default http://127.0.0.1:3847.
--install-dir PATHInstall and auth directory (becomes HSMII_HOME in the generated config).
--installer PATHUse a specific installer script instead of the packaged one.
--openOpen the optional Console afterward. By default the command stays in the terminal. --no-open wins over --open.

COMPANY_OS_IMAGE remains an explicit operator override for prerelease or private-registry testing.

ClientFile writtenNext step printed
claude<project>/.mcp.json (entry has "type": "stdio")Reload Claude Code in this project
codex<project>/.codex/config.toml, between # BEGIN COMPANY OS MANAGED and # END COMPANY OS MANAGEDReload Codex in this project
cursor<project>/.cursor/mcp.jsonReload Cursor (Settings, MCP shows company-os)
gemini<project>/.gemini/settings.jsonRestart Gemini CLI in this project
windsurf~/.codeium/windsurf/mcp_config.jsonReload Windsurf (Cascade, MCP servers shows company-os)
genericNothing; prints the mcpServers entryPaste it into your MCP host's configuration

Every entry is a stdio server running npx --yes --package @hsm/company-os-mcp-server@<version> company-os-mcp-server, with HSM_COMPANY_API_BASE (and HSMII_HOME when set) in env. After reload, ask the client to start the Company Passport. Re-running connect reuses an existing companyos.integration.json; flags override its values.

OMP ​

bash
companyos login --company COMPANY_ID
companyos connect omp [--agent-dir PATH]
companyos mcp doctor --client omp

connect omp verifies the selected company through the host, starts the CLI-bound MCP server for a live company_os_health and company_os_get_company call, refreshes ~/.omp/agent/mcp.json (or --agent-dir PATH, or PI_CODING_AGENT_DIR), and runs omp plugin doctor. A failed host, CLI, or MCP probe leaves the profile untouched; a doctor failure reports an error after the profile is written.

The profile runs companyos mcp serve --stdio and holds no bearer, principal token, or refresh token. The server refreshes the CLI session on each call and refuses further calls if the session expires, is revoked, or changes company. Its 7 tools (src/cli-mcp-scope.ts): company_os_health, company_os_get_company, company_os_list_tasks, company_os_get_task, company_os_list_receipts, company_os_show_receipt, company_os_verify_receipt. Rerun companyos mcp connect omp to refresh an older profile.

For governed OMP work use companyos chat, not this profile:

bash
companyos chat                       # admitted run, opens the OMP TUI here
companyos chat --prompt "TEXT"       # one noninteractive turn
companyos chat --start "TEXT"        # TUI opens with TEXT as the first message
companyos chat --thread-id UUID      # resume a host thread

On another machine, log in remotely: ./company-os login --console-url https://<company-os-host> --device. That login needs the company_os:tools scope and a non-loopback HTTPS endpoint.

companyos connect or companyos mcp connect ​

Same code path. companyos mcp connect CLIENT re-parses its arguments as companyos connect CLIENT ..., and its help says "Other clients use the existing companyos connect path." Both accept omp, codex, claude, cursor, windsurf, gemini, generic; mcp connect always prints JSON.

Source states no preference. Suggested convention: companyos connect in setup instructions (the README leads with it), companyos mcp ... for status, doctor, and tools afterward. The Tern palette runs mcp connect.

--agent-dir is OMP only. The other flags apply to the non-OMP clients, and connect omp rejects boolean options.

3. First use: the Company Passport ​

On first use, the MCP tools run the durable Company Passport flow. The operating contract tells the agent to call company_os_list_companies first and to offer the Passport only if no commissioned company exists. In order:

StepToolPurpose
1company_passport_startStart a durable session before a company exists
2company_passport_answerSave the reviewed session, with optimistic versioning
3company_passport_prepareStore the server-normalized draft for human review. It "does not commission a company or mint authority."
4company_passport_answerRecord the human's explicit authority and change-set confirmation
5company_passport_commissionCommission the exact stored, reviewed version. Needs confirm.

Helpers: company_passport_get re-reads a session and version; company_passport_industry_packs lists the industry packs.

"Authority and change-set confirmations must reflect explicit human answers, never model inference." The agent must never request, repeat, or display credential material.

What commissioning creates

  • A distinct host agent: claude-code-host (adapter claude-code) or codex-host (adapter codex), role worker.
  • Eight delegated scopes, each expiring in 720 hours (30 days): company_os:tasks, company_os:memory, company_os:customers, company_os:connectors, company_os:tools, company_os:workspace_files, company_os:validation, work_packages:workflow.
  • A host principal credential, also 720 hours, and an owner credential whose expiry the server sets.

company_passport_commission takes host of claude or codex only. Source does not describe commissioning for Cursor, Windsurf, Gemini CLI, or generic clients.

Credentials and where they live

  • Commissioning writes company-os-owner.binding.json and company-os-host.binding.json under HSMII_HOME (default ~/.hsm-ii), each private with mode 0600. Credentials are never written to .mcp.json, .codex/config.toml, command arguments, or MCP results.
  • The server refuses a credential file that is not a regular non-symlink file, has any group or other permission bit, or belongs to another user.
  • Auth home lookup when reading: HSM_COMPANY_OS_AUTH_HOME, then HSMII_HOME, then COMPANY_OS_INSTALL_DIR, then ~/.hsm-ii.
  • The CLI login session is separate. On macOS its refresh envelope is a 0600 file under ~/Library/Application Support/Company OS/; Linux and Windows use the OS credential store. It does not create ~/.hsm-ii. companyos logout revokes every credential for that CLI worker, then deletes the envelope.

4. Approval model for agents ​

HSM_COMPANY_MCP_APPROVAL_MODEBehavior
unsetstrict (default). Mutating and approval-sensitive tools return approval_required unless called with confirm=true.
permissiveSkips the check. README: only for trusted local automation.
boundIn the client code, not the README. A mutation must cite an approval_id that is approved, decided by someone other than its requester, unconsumed, and unexpired. The binding is consumed whether or not it verifies.

confirm=true is an intent check, not authority. src/client.ts says it is "asserted by whoever calls the tool, which may be a model, so strict is an intent check, not an authority boundary." Authority is enforced by Company OS: it refuses approval decisions for model-driven principals, and external effects need a consumed human grant. The README states for the remote bridge: "A model-supplied confirm=true is not human approval." The operating contract adds: "Never treat the assistant's own proposal as approval." A CLI --confirm is not approval either ("A CLI confirmation never grants authority").

Other rules:

  • company_os_call_tool defaults to dry_run=true; the flow is company_os_discover_tools, company_os_describe_tool, company_os_call_tool. A real call needs confirm=true in strict mode.
  • Direct mutations without dry-run support need a bounded change presented and current state read first (operating contract, step 4).
  • The phone-call handoff tools need confirmation and reject raw transcript and recording parameters. company_os_propose_email_reply leaves the reply pending_approval; Company OS does not send it.

Who decides. A person, in the Console (Approvals inbox, /workspace/approvals) or at a terminal:

bash
companyos approvals --status pending
companyos approval show APPROVAL_ID
companyos approval approve|reject APPROVAL_ID [--reason TEXT] --confirm
companyos approval decide APPROVAL_ID --decision approved|rejected --confirm

The decision refreshes the authoritative inbox and binds your choice to the server-stored presentation, subject, and request digests. Afterward: companyos receipt list|show|verify ID, companyos verify task|run ID.

5. Check a connection ​

companyos mcp checks the selected CLI company's host, connector projection, and a read-only stdio MCP handshake. It needs a CLI session. --help on any command does not contact the host.

bash
companyos mcp status                  # company, host, connectors, MCP handshake
companyos mcp doctor                  # each check, PASS or FAIL; nonzero exit on failure
companyos mcp doctor --client omp     # adds OMP version, plugin doctor, profile checks
companyos mcp tools --search task     # tools the CLI-bound session actually exposes
companyos mcp tools --quiet           # names only (also --json, --table)
companyos mcp connectors list         # host-owned connectors and OAuth state
companyos mcp connectors show|resources|prompts ID
companyos mcp serve --stdio           # the read-only server the OMP profile runs
  • --company-id UUID selects the company bound to the CLI grant; --json prints the typed report.
  • doctor check ids: omp_version, omp_plugin_doctor, omp_profile (OMP only), then cli_grant, company, host, connectors, mcp_handshake. The OMP checks run even if the host is down; the rest need a valid CLI session.
  • mcp status and mcp tools inspect the CLI-bound read-only server (the OMP profile), not the companion server that Claude Code or Codex launch with npx. Check those in the client's own MCP view.
  • companyos mcp connectors enable|disable ID --confirm (optional --idempotency-key KEY) asks the host, which rechecks authority and returns a receipt or a typed refusal. OAuth and reconnect are not in this CLI.
  • Also: companyos doctor (client preflight plus server checks).
  • After an OMP upgrade, run the offline smoke node services/company-os-mcp-server/scripts/omp-compatibility-smoke.mjs (after npm --prefix services/company-os-mcp-server run build). It uses a temporary profile and a dummy model credential and does not verify the live host.

6. Tern terminal plugin ​

integrations/tern-companyos makes governed AgentChat the main entry point and adds a cockpit, palette actions, and read-only tools for Tern's assistant, Carly.

bash
tern plugin link ./integrations/tern-companyos     # from the repository root
tern plugin list
tern plugin unlink companyos

Tern reloads linked plugins when files change. Every action runs the Company OS command resolved in this order: HSM_COMPANY_OS_CLI; the checkout's scripts/company-os through /bin/bash (HSM_COMPANY_OS_REPO or the checkout the plugin is linked from); $HOME/.local/bin/companyos. Several actions run the built operator CLI (services/company-os-mcp-server/dist/company-os-cli.js); build it once with npm --prefix services/company-os-mcp-server run build.

Palette actions (search for Company OS). Each opens a new tab and leaves a shell open so output stays visible.

ActionRuns
Company OS AgentChat: Start governed chatcompanyos chat
Connect Claude Code to Company OScompanyos mcp connect claude
Connect Codex to Company OScompanyos mcp connect codex
Connect OMP to Company OS (read-only)companyos mcp connect omp
Check OMP connectioncompanyos mcp doctor --client omp
Log this computer in to Company OScompanyos login
Start Company OScompanyos up (starts or reuses local services, opens the Console)
Open Company OS approvals waiting on youapprovals --status pending --table
Open Company OS tasks, recent agent runs, receiptstask list --table (25), ps --table (20), receipt list --table
Open Company OS usage and cost; Run Company OS doctorcost; doctor
Check Company OS readinesscompanyos status
Open Company OS Console/workspace/start on 127.0.0.1, port HSM_COMPANY_CONSOLE_PORT or 3050; does not start services
Open Company OS cockpitNative block: workspace health and Beads queue. Enter on a bead runs companyos chat --start "Work on Beads issue ..."

The OMP profile stays read-only. Use Start governed chat when a turn needs the host-admitted run and its receipts. Approvals are listed by the palette but decided in the Console or with companyos approval approve|reject ID --confirm. Optional key binding: "cmd+shift+g": "plugin.companyos.agentchat" under keybinds in Tern's settings.json (pick a free chord).

Carly. Every Carly request carries one context line (Company OS installed, last known status, read the guide first). The plugin exports 16 tools under plugins.companyos, the Tern maximum: 15 read-only tools and open.

  • guide(topic?): the plugin guide, GUIDE.md.
  • status(): API host (127.0.0.1:3847/api/company/health) and Console (/api/agent-chat-runtime), checked separately.
  • tasks, task, approvals, runs, run (views what, why, timeline, inspect, events), receipts, verify (task, run, or receipt).
  • memory (memory search), usage (cost, usage, stats, operator-status), beads (br ready|blocked|stats|show), tools (mcp tools), connectors (mcp connectors list), doctor.
  • open(target, page?): opens a palette view or Console page for the person.

Each live read runs one command and returns {ok, command, output, truncated, stderr, hint}, with output cut at about 9 KB. Arguments go to argv, never a shell, and a value starting with - is refused, so Carly cannot add --confirm. Carly never approves, sends, creates, or runs anything; for a change it opens the matching view and a person acts. The plugin does not read or store Company OS credentials.

7. Remote MCP bridge (Grok and other remote clients) ​

The package includes a stateful Streamable HTTP MCP server for a remote MCP connector such as xAI/Grok. It reuses the stdio handlers and operator contract; it is not a second agent runtime or policy engine. Start it after the API is up:

bash
cd services/company-os-mcp-server
npm run build
HSM_COMPANY_API_BASE=https://company-os.internal \
HSM_COMPANY_ID=<company-uuid> \
HSM_COMPANY_PRINCIPAL_TOKEN=<server-held-principal-token> \
HSM_COMPANY_PRINCIPAL_COMPANY_ID=<company-uuid> \
HSM_COMPANY_OS_REMOTE_MCP_TOKEN=<strong-random-grok-token> \
npm run start:http

company-os-mcp-http is the installed bin for the same server.

SettingDefault and rule
Endpointhttp://127.0.0.1:3850/mcp. Change with HSM_COMPANY_OS_REMOTE_MCP_HOST, ..._PORT, ..._PATH.
Inbound authHSM_COMPANY_OS_REMOTE_MCP_TOKEN, required. Accepted only as a bearer header, never forwarded to Company OS. A bad token gets HTTP 401 with WWW-Authenticate: Bearer.
Server-held credentialsHSM_COMPANY_ID, HSM_COMPANY_PRINCIPAL_TOKEN, and a matching HSM_COMPANY_PRINCIPAL_COMPANY_ID are required even for read-only. They can load from the private binding files.
HealthGET /healthz, unauthenticated.
Company bindingEach session is bound to the configured company; a request naming another company_id is refused.
Non-loopback bindAlso set HSM_COMPANY_OS_REMOTE_MCP_ALLOWED_HOSTS, or startup fails. ..._ALLOWED_ORIGINS is optional.
Limits..._MAX_BODY_BYTES (1048576); ..._MAX_REQUESTS_PER_MINUTE (120 per source); session cap and idle timeout.
Approval modeAlways bound. Every mutation must cite an approval_id a human already decided; the model's confirm=true is not accepted.

Put the bridge behind an HTTPS reverse proxy before giving the URL to Grok.

Default allowlist, read-only (16 tools, from src/remote-mcp-config.ts):

text
company_os_health, company_os_list_companies, company_os_get_company,
company_os_get_document_profile, company_os_dashboard, company_os_list_tasks,
company_os_get_task, company_os_list_agent_runs, company_os_run_story,
company_os_list_run_surfaces, company_os_trace_query, company_os_search_memory,
company_os_list_approvals, company_os_show_approval, company_os_verify_task,
company_os_verify_run

Override with HSM_COMPANY_OS_REMOTE_MCP_TOOLS (comma-separated). A tool outside the read-only set also needs HSM_COMPANY_OS_REMOTE_MCP_ALLOW_MUTATIONS=1, or startup fails. Company OS confirmation, governance, approval, execution, verification, and receipt checks still apply.

For the xAI Remote MCP connector, give it the HTTPS server_url, a list of allowed_tools, and the same token as HSM_COMPANY_OS_REMOTE_MCP_TOKEN in authorization (conceptual configuration in the package README).

Set HSM_COMPANY_OS_CONSOLE_ORIGIN (absolute HTTPS origin) to add Console links to results; links are navigation only and grant no authority.

8. Troubleshooting ​

Messages are quoted from the source. Run companyos mcp doctor first; its Next: line names the action.

SymptomFix
connect host must be one of claude, codex, cursor, windsurf, gemini, genericUse one of those, or omp (companyos connect omp).
Company OS companion bootstrap failed: ...The embedded installer failed; the tail of its stderr is included. If the stack already exists, rerun with --no-start.
Company OS health verification failed: HTTP <n> or ... did not confirm PostgresThe stack started but the ledger is not healthy. Check GET /api/company/health on the API base, then rerun connect.
invalid Claude MCP config <path> or invalid mcpServers object in <path>The existing client config is invalid JSON or mcpServers is not an object. Fix the file; connect will not overwrite it.
unsupported Company OS integration manifest: <path>companyos.integration.json does not match schema hsm.company_os.integration.v1. Fix or remove it, then rerun.
Client does not show company-osReload or restart the client as connect printed. Windsurf's file is global.
Agent says the Passport must startNo commissioned company exists. See section 3.
Company OS credential file must have mode 0600: <path>chmod 600 the file; it must be a regular file you own.
Tool returns approval_requiredExpected in strict mode. A person approves, then the agent retries with confirm=true. In bound mode, pass an approval_id a human already decided.
Agent wants to approve its own requestNot possible. Decide in the Console or with companyos approval approve|reject ID --confirm.
Company OS host is unreachable. Start or reconnect the host, then retry companyos connect omp.Start the host (companyos up), then retry.
An authorized Company OS CLI session is required for OMP connectioncompanyos login --company COMPANY_ID.
Doctor cli_grant fails"Resolve the CLI session error, then run companyos mcp doctor." Log in again; a session can expire or be revoked.
Doctor company fails"Reauthorize the selected company with companyos login --company ID."
Doctor host fails"Start or reconnect the Company OS host, then retry companyos mcp doctor."
OMP company-os profile is missing or stale at <path>; run companyos mcp connect ompRerun companyos mcp connect omp.
OMP version check failed: ... or OMP plugin doctor failed: ...Fix the OMP installation (is omp on PATH?), then companyos mcp doctor --client omp.
Company OS CLI session changed; restart OMP to bind the new sessionLogin or company changed under a running OMP. Restart OMP.
MCP tool outside the CLI read-only scope: <names>Rerun companyos mcp connect omp to refresh the profile.
Governed chat refuses to start"Governed terminal chat requires a loopback Company OS CLI session. Run companyos login against the local Company OS host."
Company OS remote MCP configuration is missing <NAME>Set the named variable (HSM_COMPANY_OS_REMOTE_MCP_TOKEN, HSM_COMPANY_ID, HSM_COMPANY_PRINCIPAL_TOKEN, or HSM_COMPANY_PRINCIPAL_COMPANY_ID).
Company OS remote MCP non-loopback binding requires HSM_COMPANY_OS_REMOTE_MCP_ALLOWED_HOSTSSet the allowlist, or bind to loopback behind a proxy.
Remote MCP mutation tools require HSM_COMPANY_OS_REMOTE_MCP_ALLOW_MUTATIONS=1: <names>Remove those tools from the allowlist, or set the variable deliberately.
Tern: workspace is not readyRun Start Company OS, then Check Company OS readiness.
Tern: operator CLI is not builtnpm --prefix services/company-os-mcp-server run build.
Tern: Node not foundSet HSM_COMPANY_OS_NODE.
Tern: login or grant errorsRun Log this computer in to Company OS.
Tern: tools fail with fetch failed while the API answersThe Console is down or hung. Restart it, then Start Company OS.
Anything elsecompanyos doctor, or Run Company OS doctor in Tern.

Company OS documentation — built with VitePress