Skip to content
Median
Esc
↑↓navigate↵open⌘Jpreview
On this page

CLI

Install the median command, sign in once, then set up and run your workspace from a terminal or a script.

npm install -g mediansh
median login

Every command and flag is in the CLI reference.

Install

Package manager Install Run without installing
npm npm install -g mediansh npx mediansh
pnpm pnpm add -g mediansh pnpm dlx mediansh
Bun bun add -g mediansh bunx mediansh

The package is mediansh. It installs a prebuilt binary for your platform. The command is median. median --version prints the installed version.

Sign in

median login
Sign in at https://median.sh/cli
Your code is ZFTT-B9CP

Any device with a browser works. Waiting for you to approve.

Open the address

Use any device with a browser. The CLI opens one for you when it can, with the code filled in. Over SSH or in a container, open it on your own machine.

Sign in to Median

A new account signs up on this page.

Approve the code

Check that the code matches your terminal and click Allow. The terminal prints Signed in as <you>, working in <organization>.

Fact Value
Code 8 characters, shown as XXXX-XXXX
Code lifetime 15 minutes. After that, login fails with login_timed_out
Don’t allow Login fails with login_refused
Organization The one you have open in the dashboard when you click Allow

Pick the organization

Command Effect
median login Binds the session to the organization open in the dashboard
median orgs use <slug> Moves this session to another of your organizations. The dashboard stays where it is
median orgs create <name> Creates an organization, makes you its owner, and moves both this session and the dashboard into it
median whoami Prints the account, the bound organization and your role

New accounts

A new account can approve the code before it belongs to any organization. Create one next:

median orgs create "Acme"

Until then, only whoami, orgs list, orgs create, orgs use and logout work. Everything else fails with no_organization.

First setup

From a signed in session with no organization:

median orgs create "Acme"
median keys create --name production
median agent set --name "Acme Support" --personality "Friendly, brief."
median knowledge write --title "Refund policy" --file ./docs/refunds.md
median webhooks add https://acme.com/median/events
median tools endpoint add https://acme.com/api/median/tools
median tools test orderStatus --input '{"orderNumber":"ORD-1042"}'
Line Result
1 The organization, with you as owner
2 Prints MEDIAN_KEY and the publishable widget key. They are shown once. Webhooks and tool endpoints need a key to exist
3 The agent’s name and personality
4 A knowledge document from a markdown file
5 A webhook endpoint for every event
6 Connects your tool route and syncs its manifest
7 Calls the tool the way the agent would and prints the answer. It needs no conversation

tools test runs a tool at any risk level with no approval, so a write tool performs a real write. Give it --conversation <id> to use a stored visitor from that thread instead of --as <user id>. The two cannot be combined.

Scripting

median conversations list --waiting --json | jq -r '.[].id'
Behavior Detail
--json One JSON value on stdout. login prints the sign in lines before it
Always JSON analytics charts and explore, billing limits, billing usage, call <method>, api
Refusals code: message on stderr, for example forbidden: Only admins and owners can edit the agent.
Usage errors Error: <message> on stderr, for a missing required flag or a value outside its choices
Unexpected errors error: <message> on stderr
Exit code 0 on success, 1 on any failure
tools test Exits 1 when the tool reports a failure, even though the API call succeeded
Paging logs list and billing invoices end a partial page with more: --cursor .... With --json, read isDone and continueCursor
Code Meaning
not_signed_in No session on this machine. Run median login
session_expired The session stopped refreshing and was cleared. Run median login
no_organization The session is not bound to an organization. Run median orgs create or median orgs use
invalid_token You are no longer in the bound organization. Run median orgs use <slug> or median login
forbidden Your role cannot do this. See roles
rate_limited Wait and retry. See rate limits
unreachable Login or a token refresh could not reach the API. Check your connection. Other commands print error: <message> when offline
no_api median login could not reach https://api.median.sh. Check your connection. Login never falls back to another address

Paste a page instead of finding its id:

median read https://median.sh/signal/q5776nawkbmazaj4qv4p26y3v98d83qc
Page median read prints
/signal/<id> The signal, every report, and commits that claim to fix it
/inbox/<id> The conversation with every message
/customers/<id> The person, their learned facts and their conversations
/knowledge/<id> The document in full

Only the path is read, so the host does not matter. Any other link fails with not_a_link.

A link also works in place of the id argument of conversations, customers, knowledge, signals, tools run and tasks adopt commands:

median signals status https://median.sh/signal/<id> planned
median conversations reply https://median.sh/inbox/<id> --body "On it."

--conversation on tools approvals, tools test and logs list takes the bare id.

Sessions and config

Fact Value
Credentials file ~/.median/credentials.json. On macOS and Linux only you can read it
Access token 8 hours. Refreshed 60 seconds before it expires, and once after a 401
Refresh Each refresh replaces both tokens and retires the old pair
Session expiry 30 days after the last refresh
Failed refresh Deletes the credentials file and prints session_expired
API address https://api.median.sh. Set another at login with --api <url> or MEDIAN_API_URL. It is stored in the credentials file
median logout Revokes the session on the server and deletes the credentials file

The CLI signs in only through median login. It never reads MEDIAN_KEY.

Where sessions show

Each session appears in Settings → API under MCP as Median CLI, with who approved it and when it was last used. Admins and owners see this section and can Disconnect a session. Its next command fails with session_expired.

CI and other machines

Run median login on each machine. A copied credentials file stops working on one machine as soon as the other refreshes, because each refresh retires the old tokens. A credentials file stored as a CI secret fails the same way, after the first run that refreshes it.

Where Use
A laptop or a long lived server median login once. The session lasts while it is used at least every 30 days
CI or a short lived container The REST API with MEDIAN_KEY. See authentication

What stays in the dashboard

These have no CLI command:

  • Creating your account. median login sends you to sign up in the browser.
  • Connecting Slack, Discord, Linear, Notion and GitHub. Each connection is an install in the browser. After that, median integrations configures it.
  • Choosing Notion pages, adding a docs site and uploading files to the knowledge base.
  • A public link on a single document. A repository’s link is median integrations repos published.
  • The organization’s picture and the agent’s picture.
  • Editing a customer.
  • Buying a plan, credits or add-ons. median billing reads them.
  • The help site. See Site.
  • Resending an invitation.
  • Linking your Slack or Discord account. See Work from Slack and Discord.
  • Disconnecting a CLI or MCP session. See Where sessions show.
  • Leaving or deleting the organization.

Member role changes are not on this list. Use median members role <userId> <owner|admin|member>.

Was this page helpful?