mds

mds is the command-line client for the mds markdown document store. These commands let you push and pull docs, search the workspace index, manage task lists, and administer orgs, workspaces, and API tokens.

ls

Lists every doc in the workspace, sorted by title.

Synopsis

mds ls [--server <url>] [--org <slug>] [--workspace <slug>] [--json]

Example

mds ls --org acme --workspace eng

Exit codes


push

Uploads a single markdown file to the workspace. Pass - as the path to read the body from stdin. The command resolves which server doc to update using this order: --doc-id flag, mds.doc_id frontmatter map, legacy top-level doc_id frontmatter, a prior push recorded in ~/.config/mds/puts.toml, or a new doc if none of the above match. See Frontmatter for details on mds.doc_id.

Synopsis

mds push <file> [--server <url>] [--org <slug>] [--workspace <slug>]
              [--doc-id <ulid>] [--inline-id] [--dry-run] [--json]

mds put is an alias kept for backward compatibility.

Example

mds push notes/today.md --inline-id

Exit codes


pull

Fetches the current server body for a doc and merges it into the local file, using the body at last_synced as the three-way merge ancestor. If the local file is unchanged since the last sync, pull fast-forwards. On a conflict, the file is rewritten with diff3 markers (<<<<<<<, |||||||, =======, >>>>>>>) and pull exits nonzero. Doc identity resolves the same way as push. See Frontmatter for mds.last_synced.

Synopsis

mds pull <file> [--server <url>] [--org <slug>] [--workspace <slug>]
              [--doc-id <ulid>] [--force] [--dry-run] [--json]

Example

mds pull notes/today.md

Exit codes


edit

Opens a doc in $EDITOR (falls back to vi), then pushes the saved body back to the server. Not available with --json; agents should use mds cat + mds push instead.

Synopsis

mds edit [<ulid>] [--server <url>] [--org <slug>] [--workspace <slug>]
         [--title <title>]

Example

mds edit --title "Today's notes"

Exit codes


cat

Prints the raw markdown source of a doc to stdout. Accepts a ULID, a local .md path, or a --title match. See Frontmatter for the mds: namespace that push strips before upload--cat returns the stored wire body, not the local file.

Synopsis

mds cat [<path-or-ulid>] [--server <url>] [--org <slug>] [--workspace <slug>]
        [--title <title>] [--json]

Example

mds cat 01HWZQ3K2N8V4P0MXYZ5A6B7CD

Exit codes


history

Lists every stored version of a doc: sequence number, content hash (first 10 chars), timestamp, and title.

Synopsis

mds history [<path-or-ulid>] [--server <url>] [--org <slug>] [--workspace <slug>]
            [--title <title>] [--json]

Example

mds history --title "Deployment runbook"

Exit codes


rm

Soft-deletes a doc. Prompts for confirmation unless --yes is passed or stdin is not a terminal. --dry-run previews the deletion without writing.

Synopsis

mds rm [<path-or-ulid>] [--server <url>] [--org <slug>] [--workspace <slug>]
       [--title <title>] [--yes] [--dry-run] [--json]

Example

mds rm 01HWZQ3K2N8V4P0MXYZ5A6B7CD --yes

Exit codes


Searches the workspace index. Defaults to full-text search (fts); --semantic switches to vector similarity (sim) and --hybrid combines both.

Synopsis

mds search <query> [--server <url>] [--org <slug>] [--workspace <slug>]
           [--mode fts|sim|hybrid] [--semantic] [--hybrid] [--limit <n>] [--json]

--semantic and --hybrid are shorthands for --mode sim and --mode hybrid respectively, and are mutually exclusive.

Example

mds search "staging deploy" --hybrid --limit 5

Exit codes


task

Reads and appends items in a doc's GFM checkbox task lists. Task lists are addressed by their section slug (e.g. ## Inbox -> inbox) or by a key declared in the doc's mds.lists frontmatter map.

mds task has two subcommands:

mds task list [DOC-ULID] [LIST-KEY]: shows items in a task list. Omit LIST-KEY to default to the first task list in the doc.

mds task add [DOC-ULID] [LIST-KEY] TEXT: appends an item. Pass - as TEXT to read from stdin. --idempotency-key enables server-side deduplication (24h TTL) so retries don't double-append.

In both subcommands the doc can also be addressed with --title instead of a positional ULID.

Synopsis

mds task list [<ulid>] [<list-key>] [--server <url>] [--org <slug>] [--workspace <slug>]
              [--title <title>] [--json]

mds task add [<ulid>] [<list-key>] <text> [--server <url>] [--org <slug>] [--workspace <slug>]
             [--title <title>] [--idempotency-key <key>] [--json]

Example

mds task add --title "Inbox" inbox "Review PR #42"
mds task list --title "Inbox"

Exit codes


browse

Opens an mds page in the default browser. TARGET can be omitted (home page), an org slug, an org/workspace path, or a doc path or ULID. --no-browser prints the URL instead of opening it.

Synopsis

mds browse [<target>] [--server <url>] [--org <slug>] [--workspace <slug>]
           [--title <title>] [--no-browser] [--json]

Example

mds browse notes/today.md
mds browse acme/eng
mds browse --no-browser 01HWZQ3K2N8V4P0MXYZ5A6B7CD

Exit codes


login

Signs in via OAuth (GitHub or Google) and stores the resulting API token in ~/.config/mds/credentials.toml. Opens a browser to the OAuth start endpoint; after the redirect the server bounces back to a one-shot local listener with the token. Pass --token <raw> to skip the OAuth flow and store an existing token directly.

Synopsis

mds login [--server <url>] [--provider github|google] [--token <raw>] [--no-open]

Example

mds login --provider github
mds login --token mds_tok_...

Exit codes


logout

Removes the stored credentials entry for the configured server from ~/.config/mds/credentials.toml.

Synopsis

mds logout [--server <url>] [--json]

Example

mds logout --server https://md.pgavlin.sh

Exit codes


whoami

Prints the authenticated user (email and display name) for the configured server.

Synopsis

mds whoami [--server <url>] [--json]

Example

mds whoami

Exit codes


tokens

Manages API tokens for the authenticated user. Has three subcommands:

mds tokens list: lists all tokens (ID, name, created, last used, expiry).

mds tokens create [--name <label>]: mints a new token. The raw token value is printed once and never again.

mds tokens revoke <id>: revokes a token by ID.

Synopsis

mds tokens list   [--server <url>] [--json]
mds tokens create [--server <url>] [--name <label>] [--json]
mds tokens revoke <id> [--server <url>] [--json]

Example

mds tokens create --name ci-deploy
mds tokens list
mds tokens revoke tok_01HWZQ3K2N8V4P0MXY

Exit codes


orgs

Manages orgs. Has two subcommands:

mds orgs list: lists orgs the authenticated user belongs to.

mds orgs create --slug <slug> [--name <name>]: creates a new org; the caller becomes owner.

Synopsis

mds orgs list   [--server <url>] [--json]
mds orgs create --slug <slug> [--name <name>] [--server <url>] [--json]

Example

mds orgs create --slug acme --name "Acme Corp"
mds orgs list

Exit codes


workspaces

Manages workspaces within an org. Has two subcommands:

mds workspaces list --org <slug>: lists workspaces in an org.

mds workspaces create --org <slug> --name <name> [--description <text>]: creates a workspace; the caller becomes owner.

Synopsis

mds workspaces list   --org <slug> [--server <url>] [--json]
mds workspaces create --org <slug> --name <name> [--description <text>] [--server <url>] [--json]

Example

mds workspaces create --org acme --name eng --description "Engineering docs"
mds workspaces list --org acme

Exit codes


integrations

Configures mds integrations. Currently Slack is the only supported integration; future ones will land in the same namespace.

mds integrations slack has three subcommand groups:

mds integrations slack install: prints the URL to start the Slack OAuth install flow (open it as a signed-in admin).

mds integrations slack installations ls|rm <team_id>: lists or revokes Slack app installations.

mds integrations slack route ls|set <emoji>|rm <emoji>: manages the (emoji -> doc task list) routes that the worker appends to when a Slack reaction fires. route set requires --doc <ulid> or --title; --list sets the target list key (defaults to the first task list in the doc).

Synopsis

mds integrations slack install [--server <url>] [--org <slug>] [--workspace <slug>]

mds integrations slack installations ls  [--server <url>] [--org <slug>] [--workspace <slug>] [--json]
mds integrations slack installations rm <team_id> [--server <url>] [--org <slug>] [--workspace <slug>]

mds integrations slack route ls  [--server <url>] [--org <slug>] [--workspace <slug>] [--json]
mds integrations slack route set <emoji> --doc <ulid>|--title <title> [--list <key>]
                                  [--server <url>] [--org <slug>] [--workspace <slug>]
mds integrations slack route rm  <emoji> [--server <url>] [--org <slug>] [--workspace <slug>]

Example

mds integrations slack install
mds integrations slack route set white_check_mark --title "Inbox" --list inbox
mds integrations slack route ls

Exit codes