Beta

Kaizendex for your terminal and your AI tools

BetaThe CLI and the MCP server are beta.

They read and write real data in your account, and they work — but command names, flags and tool names can still change between versions. Pin a version if you script against it, and keep the connection read-only unless you mean to let an agent write.

kzx is one program that does two jobs — a command line tool you type into, and an MCP server your coding agent talks to. Both read and write the same account as the web app, from a local copy of your data, through the same audited path as the assistant inside the app.

Before you start

You need Node 22 or newer, and a Kaizendex account — the same one you sign into on the web. Check your Node version:

Terminal
node --version

Install

Try it without installing anything — this downloads it, runs it, and leaves nothing behind:

Terminal
npx -y @kaizendex/kzx@latest --version

Or keep it, so you can just type kzx:

Terminal
npm install -g @kaizendex/kzx

That installs two command names for the same program: kzx and kaizendex. Use whichever you can remember.

Sign in

This opens your browser and signs you in with Google:

Terminal
kzx login

If your account uses an email and password, pass the email instead:

Terminal
kzx login you@example.com

The session is stored in ~/.kzx/, and kzx mcp reuses it — so you sign in once, not once per tool.

Connect your AI tool

Every client runs the same command. Only the place you put it changes.

Claude Code

Run this once in any terminal. Add --scope user to make it available in every project.

Terminal
claude mcp add kaizendex -- npx -y @kaizendex/kzx@latest mcp

Claude Desktop

Settings → Developer → Edit Config, then restart the app. Any client that takes an mcpServers block reads the same shape.

claude_desktop_config.json
{
  "mcpServers": {
    "kaizendex": {
      "command": "npx",
      "args": [
        "-y",
        "@kaizendex/kzx@latest",
        "mcp"
      ]
    }
  }
}

Codex

Add this to ~/.codex/config.toml.

~/.codex/config.toml
[mcp_servers.kaizendex]
command = "npx"
args = ["-y", "@kaizendex/kzx@latest", "mcp"]

Cursor and VS Code

Save the same block as .cursor/mcp.json in Cursor, or .vscode/mcp.json in VS Code.

.cursor/mcp.json or .vscode/mcp.json
{
  "mcpServers": {
    "kaizendex": {
      "command": "npx",
      "args": [
        "-y",
        "@kaizendex/kzx@latest",
        "mcp"
      ]
    }
  }
}

As written, the server is read-only: the agent can look at your data and cannot change it. To let it write — log entries, edit Collections, change a card — add --allow-writes to the end of the arguments (“mcp”, “--allow-writes”), or to the end of the claude mcp add line. Read “Read-only by default” below before you do.

Or let your agent set it up

Copy this into Claude Code, Codex or Cursor and it will do the whole thing — install, sign-in, config file, and a check that it worked. You only have to finish the browser sign-in when it asks.

Prompt
Set up the Kaizendex CLI and its MCP server for me.

1. Check Node is 22 or newer (node --version), then verify the tool runs:
   npx -y @kaizendex/kzx@latest --version

2. Sign me in: run  npx -y @kaizendex/kzx@latest login
   It opens a browser. Tell me to finish signing in there, wait for me, then
   confirm it worked with  npx -y @kaizendex/kzx@latest whoami

3. Register the MCP server for whichever tool you are running inside:
   - Claude Code:  claude mcp add kaizendex -- npx -y @kaizendex/kzx@latest mcp
   - Codex: add to ~/.codex/config.toml
       [mcp_servers.kaizendex]
       command = "npx"
       args = ["-y", "@kaizendex/kzx@latest", "mcp"]
   - Cursor or VS Code: write the same command into .cursor/mcp.json or
     .vscode/mcp.json as
       {"mcpServers":{"kaizendex":{"command":"npx","args":["-y","@kaizendex/kzx@latest","mcp"]}}}
   Keep it read-only: do NOT add --allow-writes unless I ask you to.

4. Verify: list the server's tools, then call describe_collection on one of my
   collections and show me what came back.

5. Tell me what you changed and stop. Do not create, edit or delete any of my
   data.

Read-only by default

Nothing can be written until you say so

The MCP server starts read-only. An agent connected the way this page describes can read your Collections, entries and dashboards and cannot change any of them. Writing takes one deliberate extra step: adding --allow-writes to the arguments.

Prompt injection is real

Anything an agent reads can try to give it instructions — a web page it opens, a repository it clones, a template someone published. An agent with write access will sometimes follow those instructions against your data. Give write access only to agents and projects you trust, and prefer keeping it off for anything that browses the open web.

Every write is logged, and revertible

Writes go through exactly the same audited path as the assistant inside the app — the same closed set of operations, the same record. So anything an agent does here shows up in your AI log, with an undo next to it.

What it can do

94 tools, 24 of them without write access — generated straight from the registry the CLI runs, so if it is listed here, it works.

Available read-only

What a connected agent can do the moment you add the server, with no extra flags.

Tools available without --allow-writes
ToolWhat it does
aggregate_propertyAggregate a NUMERIC Property over a date range, bucketed by day/week/month — returns {bucket, sum, count, avg} per bucket plus totals.
describe_collectionGet one Collection's full bindings — {binding_id, binding_key, property_id, name, data_type, is_required, display_order, config} — plus its meta.
get_automationsREAD the user's automations — their own 'when this happens, do that' rules.
get_backlinksList the entries that LINK TO a given entry — its 'Mentioned by' backlinks (the wiki-graph edges).
get_card_layoutREAD a Collection's current Card layout document — the exact JSON set_card_layout writes.
get_chart_configREAD one chart's raw config-v2 JSON — the exact document set_chart_config writes.
get_collection_viewsREAD a Collection's saved views — the raw array set_collection_views writes, each view with its kind, name, settings, filters, sorts, hidden columns…
get_dashboard_layoutREAD one dashboard's whole-board layout document — the exact JSON set_dashboard_layout writes.
get_entry_bodyRead a Page/Entry's current block body as markdown (plus the raw blocks).
get_global_collectionREAD the user's GLOBAL COLLECTIONS — cross-collection containers, each with its own name, emoji, page and views.
get_relatedRead an entry's relations in BOTH directions: outgoing (per relation binding: its ordered targets) and incoming (the derived reverse side — every…
list_dashboardsList the user's dashboards (tabs) with their chart placements, plus the full standalone chart library.
list_foldersList the user's sidebar folder tree: every folder (id, name, emoji, parent_folder_id) plus the entries filed in each (entry_id, name, collection_id,…
list_memoryList the durable facts you have remembered about this user (what save_memory writes).
list_propertiesList the property catalog — the official + user properties you bind against when building a Collection.
list_theme_colorsREAD the user's saved themes and each one's NAMED PALETTE — their own colours, e.g. { 'hp-red': '#ff2d55' }.
query_entriesDiscover entries — the agentic glob+grep over the user's log.
query_rollupAggregate a Property's values over a date range (per-day sum + count).
read_entryRead a whole entry as an OKF/Tolaria markdown document — YAML frontmatter (its typed scalar values: id, type, event_at, name + each field) followed…
search_knowledgeSEARCH everything the user knows — entries, page/long text, attachment descriptions, past chats and memory facts — in ONE call.
search_librarySearch the Kaizendex Library for ready-made setups — systems, collections, dashboards, widgets, views, presets, automations, agents and themes.
session_searchSearch your PAST conversations with this user.
view_library_itemRead one Library item in full — what collections, properties, views, presets, automations and widgets it would create.
view_skillLoad the full body of one of your skills by its id (from the skills catalog) before applying it.

Needs --allow-writes

These change your data (or reach the network from your machine). They stay hidden until you add the flag.

Tools that require --allow-writes
ToolWhat it does
add_bindingAdd a Property to an EXISTING Collection (a new field on its log form).
add_chart_to_dashboardPlace an EXISTING chart from the library onto a dashboard (a chart can live on several dashboards at once).
add_entry_imageUpload an image and embed it into a Page/Entry's body (appends an image block at the end).
add_entry_to_dashboardPin an ENTRY on a dashboard — a note, a recipe, a daily briefing (plan 0044 §5.4).
add_relation_propertyAdd a Relation property to a Collection: entries of it will reference entries of a TARGET Collection (e.g. a Projects Collection gets an 'Area'…
add_tag_propertyAdd a NEW Tags property (its own option set) to a Collection.
add_view_to_dashboardEmbed an existing saved VIEW on a dashboard (plan 0044 §5.5) — a filtered list right on the board, rendered exactly as it is on its own page, with an…
convert_property_kindChange ONE column's (binding's) property kind, coercing its existing values where they fit and clearing what doesn't (returns {converted, cleared}).
copy_library_itemCopy a Library item into this user's account.
create_chartCreate a chart and place it on a dashboard — the ONE call for 'chart my sleep', 'calories vs my 2000 goal', 'work vs leisure time stacked'.
create_collectionCreate a new Collection the user can log entries against.
create_custom_agentCreate a NEW custom AI agent for the user (only available to you, the Agent Creator).
create_dashboardCreate a new dashboard tab (e.g. 'Health', 'Training').
create_folderCreate a sidebar folder.
delete_automationDelete ONE automation.
delete_bindingRemove a Property binding from a Collection (deletes that field).
delete_chartDelete a chart EVERYWHERE — it disappears from every dashboard and the library.
delete_collectionSoft-delete a Collection.
delete_dashboardDelete a dashboard tab.
delete_entrySoft-delete an Entry.
delete_folderDelete a folder.
delete_tag_optionDelete ONE tag OPTION from its Tags property's option pool — the label stops existing and disappears from every entry that carried it.
draft_library_listingPrepare a DRAFT Library listing for something the user built, and return a link where they review and publish it themselves.
fetch_urlFetch a web page and get its readable text (title, byline, article text — extracted, not raw HTML) plus image — the page's main og:image URL…Reads rather than writes, but still gated: Same as web_search: outbound egress.
generate_imageGenerate a brand-new image with an AI image model.
import_imageDownload an image from a URL and store it permanently as an attachment on an entry.
instantiate_presetInstantiate a named entry PRESET (template) on a Collection — the structured alternative to free-form log_entry.
log_entryLog one Entry against an existing Collection.
log_foodLog food the user ate, with estimated macros, against their Food/Dish Types — ONLY when their intent is to record eating ('I ate…', 'log my lunch',…
manage_calendar_placementPin, unpin, show or hide a CALENDAR VIEW on the calendar page's sidebar.
manage_presetCreate, update, or delete a named entry PRESET (template) on a Collection — use this when the user asks to save something as a…
manage_skillPropose a new skill (a reusable operating instruction) for the user to approve, or patch an existing one by skill_id.
manage_viewCreate, update, delete or reorder ONE saved view on a Collection — INCLUDING its own layout document.
move_entries_to_collectionMove MANY entries into another Collection in one call — the primitive for MERGING two Collections (e.g. fold 'Todo' into 'Todos').
move_entry_to_folderFile an entry into a folder, move it between folders, or UNFILE it from the sidebar (pass folder_id=null).
move_folderMove a folder under a new parent (omit parent_folder_id to move it to the top level).
propose_persona_editPropose a revision to your own persona/voice.
remove_chart_from_dashboardTake a chart off ONE dashboard.
rename_folderRename a folder and/or change its emoji.
rename_tag_optionRename ONE tag OPTION in place — the label changes everywhere it is used, and every entry carrying it follows.
reorder_bindingsReorder the Properties (fields) on a Collection.
reorder_sub_entriesReorder the sub-entries (children) of a parent Entry.
restore_itemRestore a soft-deleted Entry or Collection from the Trash.
save_linkSave an external URL the user wants to KEEP (an article, X/Twitter post, YouTube video, Reddit thread, any link) as an Entry in a Collection — the…
save_memoryRemember a durable, declarative fact about the user worth recalling in future conversations — their profile, stable preferences, or long-running…
set_automationCREATE or REPLACE ONE automation — a single 'when this happens, do that' rule.
set_automation_enabledTurn ONE automation on or off without deleting it or touching its rule.
set_bannerSet or clear the banner image on an Entry or Collection.
set_card_layoutWRITE a Collection's Card layout — how its entries are laid out AND styled on ONE surface.
set_chart_configREPLACE an existing chart's config with raw config-v2 JSON — the full grammar, for everything the flat update_chart DSL can't say: multi-series, a…
set_collection_tagsTag or untag the COLLECTION itself with global tags — e.g. mark a Collection as 'Exercise' or 'Health' so it groups with its kin ('tag this…
set_collection_viewsREPLACE a Collection's whole saved-views array.
set_dashboard_layoutREPLACE one dashboard's whole-board layout from a document — rename the tab, reorder/resize every placement, add and drop charts in ONE call (the…
set_entry_bodySet a Page/Entry's BODY — its rich block content (the Notion-style page).
set_entry_emojiSet or clear an Entry's per-entry emoji override (its icon).
set_favoriteStar (favorite/pin) or unstar an Entry or Collection.
set_global_collectionCREATE or PATCH one GLOBAL COLLECTION — a cross-collection container with its own name, emoji, page and views.
set_property_configSet a binding's per-kind config (advanced — Derived/Control properties, formula recipes, a GPS tracker's wiring map).
set_relationSet which entries a relation property points at.
set_subentry_columnsSet a Collection's sub-entry columns config — how the child columns of the sub-entry matrix summarise on the PARENT's table row.
set_tag_cardinalityConvert a Tags property between single and multiple selection (migrates existing values) — the "Allow multiple tags" setting.
set_theme_colorsADD or CHANGE named colours on one of the user's saved themes — the palette a dashboard is painted from.
shift_entry_dateMove an Entry to a new date/time AND cascade the shift to its sub-entries (the whole subtree moves with it).
update_bindingUpdate a Property binding on a Collection: rename it (custom_display_name), toggle required, change its default value or card column span.
update_chartUpdate an existing chart's title and/or any part of its config (same flat fields as create_chart — only the fields you pass change;…
update_collectionRename a Collection, change its emoji, rewrite its Description (markdown wiki blob), or set its AI instructions.
update_custom_agentEdit an existing custom agent — set its picture, rename it, adjust its accent colour, revise its persona (soul — the FULL rewritten persona to the…
update_dashboardRename a dashboard, change its emoji icon, or reorder it (position).
update_entryEdit an existing Entry: change its date/time (event_at), rename it (name), and/or fix values.
web_searchSearch the web (Brave Search) and get ranked results: title, url, snippet, freshness.Reads rather than writes, but still gated: Reads the public web, not the user's data — but it is outbound network egress from the user's machine, which a read-only…

Versions and updates

kzx --version tells you what you have. The tool checks for a newer release about once a day and prints a line in your terminal when there is one — it never updates itself behind your back.

Terminal
npm install -g @kaizendex/kzx@latest

If you run it through npx -y …@latest — which is how the configs above are written — there is nothing to update: every run fetches the newest version. And if a copy ever gets too old to talk to the app, it says so and stops rather than guessing.

One thing to expect: the CLI has its own version number, published separately from the app’s. They will not match, and they are not meant to.

The CLI on its own

No agent required — these are the commands you type yourself.

CommandWhat it does
kzx loginSign in with Google in the browser.
kzx login <email>Sign in with an email and password instead.
kzx logoutClear the stored session.
kzx whoamiShow who is signed in.
kzx syncPull the latest changes and push anything waiting.
kzx collectionsList your Collections.
kzx entriesList recent entries (--type, --limit).
kzx queryRead entries through the audited capability, from the local copy.
kzx log <id>Log an entry: --set key[:kind]=value.
kzx entry body <id>Set a Page or Entry's rich body (--markdown / --file).
kzx entry image <id>Upload an image and append it to a body (--file).
kzx capabilitiesList every capability the CLI and MCP server can run.
kzx call <name>Run any capability by name (--json) — the hatch the MCP server uses.
kzx vault projectWrite your data out as markdown and CSV files (--root).
kzx vault watchProject, then watch the folder and write your edits back (--root).
kzx mcpStart the MCP server on stdio (--allow-writes to enable writing).