@embd/cli
v0.7.7
Published
Private collaborative Markdown/HTML workspaces and embeddable charts from your terminal
Readme
embd CLI
Publish charts and docs (hosted HTML/markdown pages) to embd.sh from your terminal or CI.
# The npm package is @embd/cli; its binary is `embd`. Always install by the
# scoped name — plain `npx embd` runs an unrelated third-party package.
npx @embd/cli chart data.csv
# or
bunx --package @embd/cli embd chart data.csv
# or install it once and call `embd` directly
npm i -g @embd/cli && embd chart data.csvPrivate collaborative workspaces
For a document invitation, accept it while signed in with the invited email, then open Agent access from that document. Its credential is limited to that document and your current viewer/commenter/editor access. The same CLI commands work, but listing/search/sync only return that authorized document; creating documents, importing sets, managing folders or uploading workspace images still requires workspace access. Links and embedded documents do not grant access to their targets. Invitations and role changes remain human controls in Share.
embd workspace uses the same operation names, schemas and transport as
embd-documents-mcp. Use a workspace agent credential from Agent access in
EMBD_DOCUMENT_TOKEN; public publishing keys do not authorize this API.
EMBD_DOCUMENT_ORIGIN defaults to https://app.embd.sh.
embd workspace tools
embd workspace workspace_documents --input '{"workspaceId":"WORKSPACE_UUID"}'
embd workspace read_document --input '{"documentId":"DOCUMENT_UUID"}'
embd workspace revise_document --input @revision-metadata.json --source-file spec.md
embd workspace comment_on_document --helpAll successful results are JSON. --input accepts inline JSON, @file, or -
for stdin. Revision metadata includes documentId, title, summary and the exact
expectedRevision/expectedEditVersion returned by a fresh read. Conflicts fail
without automatic overwrite: read again, reconcile, then retry. Older history
and discussion pages, search, named checkpoints, thread status and reversible
Trash operations are available through the same operation catalog. Credentials
remain in the environment, not command-line arguments. Do not put secrets in
source or commit private client configuration.
The document tools are included in paired CLI/MCP releases starting at 0.2.0; 0.1.1 only supports the earlier public embed workflow. Until a new version is confirmed in npm, use a local build. CI tests clean installed tarballs and verifies the registry installation after publishing.
Login
Only needed for hosted embeds — see no account required to skip it entirely.
embd login # opens embd.sh/account, then prompts (input hidden)
embd login --no-browser # prints the URL instead of opening it
embd login --key embd_sk_...embd login opens https://www.embd.sh/account so you can sign up (or sign
in) and create a key, then prompts for it. The key is stored in
~/.config/embd/config.json (mode 0600). The EMBD_API_KEY environment
variable always takes precedence — handy for CI.
No account required
--link encodes your data into the URL itself. No key, no network call,
nothing stored on our side:
embd chart sales.csv --link
# → https://embd.sh/playground/chart#<payload>Everything else (embd chart without --link, doc, list, delete)
publishes to a hosted URL and needs a key.
Try it right now
Copy-paste this whole block — it needs no account and no setup:
cat > sales.csv <<'CSV'
month,region,revenue,units
2026-01,North,24680,118
2026-01,South,18170,71
2026-02,North,26620,110
2026-02,South,25440,87
2026-03,North,36856,130
2026-03,South,17081,93
CSV
embd chart sales.csv --link --kind bar --split region --y revenue --open--open launches the URL in your browser; drop it to just print the link.
The link opens a preview — add --edit if you'd rather hand someone the
editor. A larger version of this file lives at
examples/sales.csv
in the repo.
Note on messy CSVs. A value containing a comma must be quoted —
"$1,200.00", not$1,200.00. Unquoted, it splits into two fields and shifts every later column. The CLI warns on stderr when it sees this, but it cannot tell which reading you meant.
Create a chart
embd chart sales.csv
embd chart sales.csv --kind bar --x month --y revenue --y profit --title "Q3 sales"
cat rows.json | embd chart - --split region --theme dark
embd chart sales.csv --draft # save without publishing
embd chart sales.csv --slug q3-sales # custom slug (Pro)Input is a CSV file, a JSON array of row objects, or stdin (-). On success
the chart URL is printed on the first line, followed by the embeddable
<iframe> snippet:
https://www.embd.sh/c/abc123
<iframe src="https://www.embd.sh/embed/abc123" ...></iframe>Use --json for the full machine-readable API response.
Publish a doc
embd doc report.md # format inferred from the extension
embd doc page.html --title "Launch notes"
cat notes.md | embd doc - --format markdown # stdin requires --format
embd doc report.md --draft # save without publishing
embd doc report.md --slug launch-report # custom slug (Pro)embd doc publishes an HTML or markdown file as a hosted page. The format is
inferred from the extension (.md/.markdown → markdown, .html/.htm →
html); --format html|markdown overrides it and is required for stdin or
unrecognized extensions. Output matches embd chart: the hosted URL, then the
<iframe> snippet (docs render inside a sandboxed iframe on the hosted page).
Content is limited to 100,000 characters. --json prints the full response.
Manage embeds
embd list # table of your embeds: id, kind, status, title, url
embd delete <id> # prints "ok"embd list shows charts and docs alike — the KIND column is the chart type
for charts and html or markdown for docs.
CI usage
- name: Publish chart
run: bun x --package @embd/cli embd chart out/benchmarks.csv --title "Benchmarks $GITHUB_SHA" --json > chart.json
env:
EMBD_API_KEY: ${{ secrets.EMBD_API_KEY }}--json writes the full response (id, url, embedUrl, iframe) to stdout for
scripting, e.g. jq -r .url chart.json.
Reference
embd --help,embd <command> --help,embd --version- Exit codes:
0ok,1API/user error,2usage error - Environment:
EMBD_API_KEY— API key (overrides the stored config)EMBD_API_URL— override the API base URL (self-hosted / staging)
API access is free during the beta; after launch it will require a Pro plan. Free plans have caps on saved and live (published) embeds — charts and docs count against the same limits; the CLI will point you to upgrade when you hit them. Zero runtime dependencies; works on Bun and Node.js >= 18.
Development
bun test # unit tests
bun run typecheck
bun run build # bundles src/main.ts -> dist/embd.js (the bin)Local knowledge-base replica
Keep personal QMD collections independent. These tools maintain a separate embd SQLite FTS5 index and perform no network request for search/read/link resolution. Local tools require Node.js 22.13+ (or Bun for source development); existing remote commands retain their previous runtime support. The server must have the local-KB sync migration/API deployed.
Set EMBD_DOCUMENT_TOKEN to a read-scoped workspace agent credential. Do not put it in request JSON, shell history or the database. EMBD_DOCUMENT_ORIGIN defaults to https://app.embd.sh; EMBD_KB_DIR can override the cache root (default ~/.cache/embd/kb). Data is isolated by origin, credential fingerprint and workspace. Explicit sync selection authorizes local storage. Offline access lasts at most one hour and never outlives credential expiry. Revocation is detected on sync; previously downloaded copies cannot be recalled remotely.
# selection.json: {"workspaceId":"<workspace UUID>","documentIds":["<document UUID>"]}
embd workspace kb_sync --input @selection.json
# Optional background catch-up: keep this process running; Ctrl-C stops it.
embd workspace kb_sync --input @selection.json --watch 60
embd workspace kb_search --input '{"workspaceId":"<workspace UUID>","query":"authentication decision"}'
embd workspace kb_read --input '{"workspaceId":"<workspace UUID>","documentId":"<document UUID>"}'
embd workspace kb_resolve_link --input '{"workspaceId":"<workspace UUID>","documentId":"<document UUID>","href":"../decisions/auth.md#tradeoffs"}'
embd workspace kb_status --input '{"workspaceId":"<workspace UUID>"}'
embd workspace kb_forget --input '{"workspaceId":"<workspace UUID>"}'The same seven kb_* operations are available in embd-documents-mcp. Call kb_sync explicitly there or run the CLI watch process with the same token/origin/cache directory. MCP does not silently start a daemon. workspace tools and each command's --help expose shared schemas. Search requires all literal terms, with Unicode tokenization; it is lexical, not semantic. Results contain stable document URLs, exact source versions/hashes and freshness. kb_read returns bounded source slices; use nextOffset to continue. Reads can be stale: fetch the current server document before editing. Relative links resolve only within the synced selection using retained bases and rename aliases; unresolved targets are not automatically downloaded.
Paired client 0.7.4 makes local search format-aware: Markdown headings, prose, lists, tables, link/image labels and literal code are searchable, including angle-bracket code such as <Widget>. HTML is parsed inertly; actual script/style/template/iframe/object/SVG payloads and comments are excluded. Raw or malformed HTML inside Markdown follows the same HTML5 recovery rules, while fenced and inline code remains literal. Nothing is executed or fetched by text extraction. Search uses displayed text plus document title/path, not link destinations; it does not evaluate CSS visibility or index image pixels.
Upgrade both CLI and MCP together and restart the MCP process. Run kb_sync again after upgrading: older extractor indexes are marked incompatible until a complete rebuild succeeds. Interrupted downloads or failed writes preserve the previous stored replica for retry, but incompatible indexes cannot be read. Sync rejects backwards cursors and document versions instead of replacing a newer local copy. Exact source, hashes, revisions and citation URLs are unchanged.
Changing the selected IDs atomically replaces the local set after complete sync. Interrupted attempts retain the previous complete replica and its original expiry. A server cursor reset triggers a full reconciliation. A 401/403/404 clears the affected replica. kb_forget removes local content without deleting server documents. This is pull-only source sync: discussions, offline editing, automatic folder ingestion and embeddings are not included.
Portable document images
export_document returns the versioned embd.document.v2 JSON package: exact
current source, authorized PNG/JPEG/WebP bytes, and a path manifest. It composes
existing authorized reads, so it works with the managed-image API without a new
server endpoint. CLI and MCP use the same collector and limits: at most 30 images
and 30 MB. A missing/denied/corrupt image or document edit aborts collection.
It does not contain comments, history, linked documents, or external resources.
External image URLs stay in source and are listed in externalImages; they are
never fetched. HTML base/srcset overrides and root-relative image paths require
conversion to ordinary relative image paths first.
The CLI can write a ZIP without overwriting an existing file:
embd workspace export_document --input @document.json --archive-file document.zipdocument.json contains { "documentId": "<document UUID>" }. Extract the ZIP
and open the source at sourcePath from embd-export.json. A moved document uses
its retained link base within files/, preserving exact relative image links;
its current workspace path remains in the manifest. The JSON form has each file's
encoding/content; the ZIP contains real source/image files instead of base64.
MCP returns the same JSON package and does not write to the machine's filesystem.
