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

123 tools, 37 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_entriesDatabase COUNT/DISTINCT/SUM/AVG/MIN/MAX over ALL matching entries, never a page.
aggregate_propertyAggregate a NUMERIC Property over a date range, bucketed by day/week/month — returns {bucket, sum, count, avg} per bucket plus totals.
calculateDeterministic arithmetic on numbers you already hold — percentages, ratios, differences, rounding, unit-checked sums.
describe_collectionGet one Collection's full bindings — {binding_id, binding_key, property_id, name, data_type, unit, aggregatable, is_required, display_order, config}…
get_attachment_usagesRead where a managed attachment is used, including entry property/body/banner references and supported other owners.
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_entry_connectionsRead an entry's permanent metadata (Created at, Updated at, nullable Entry date/event_at), Related Entries and Files even when hidden in the UI.
get_global_collectionREAD the user's GLOBAL COLLECTIONS — cross-collection containers, each with its own name, emoji, page and views.
get_guide_claimsREAD a guide entry's claims — each guide section's citations: the claim text, its kind (source statement / AI interpretation / user decision /…
get_relatedRead an entry's relations in BOTH directions: outgoing (per relation binding: its ordered targets) and incoming (the derived reverse side — every…
get_source_dependentsThe REVERSE face of citations: which guides (and through them which skills) depend on this source entry, with the claims each guide draws from it.
get_theme_controlsRead saved themes and their current controls and deck documents before editing typography, density, scrollbars or the window frame.
learn_from_sourcesASSEMBLE the learning packet for updating a guide from sources — no writing, no model call: the guide's current version, body, claims, linked goals…
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 compact entries by collection_id, local from/to dates and optional keyword q.
query_entries_structuredExact SQL-like query over entries — typed AND/OR/NOT filters by binding_id and intrinsic field, ranges, null checks, tags, relations, ordering,…
query_rollupAggregate a Property's values over a date range (per-day sum + count).
read_attachmentREAD AN ATTACHED FILE'S CONTENT — its extracted text as located SEGMENTS (page N, sheet rows, a time range of a recording, char offsets) or as raw…
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…
read_entry_valueREAD ONE LONG TEXT PROPERTY of an entry completely, by offset — a Summary, a Transcript, Notes, the body — where read_entry shows only a…
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.
search_skillsFIND a skill by what it is about — the catalog in your prompt lists only the pinned and most recently updated ones, so a skill written months ago…
session_searchSearch your PAST conversations with this user.
view_attachmentLook at an attached picture — the image itself (or its thumbnail / a video's poster frame), even while its text is still being processed.
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.
add_chart_to_dashboardPlace an EXISTING chart from the library onto a dashboard (a chart can live on several dashboards at once).
add_entry_fileAttach ANY file (PDF, Office, text, audio, video, image) to a Page/Entry, keeping its name — or add it to a Files & media property (binding_key);…
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 can reference any accessible collection by default.
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…
configure_relation_displayAdd or configure an optional reverse display of an existing Relation on this Collection, using its shared relation binding ID.
configure_system_propertyAdd, remove, rename or change entry-page visibility of one built-in field on a Collection.
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.
correct_attachment_textCorrect an attached file's extracted text or transcript with the user's supplied correction.
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.
create_shared_propertyCreate a user-owned shared property and attach it to a collection.
delete_automationDelete ONE automation.
delete_bindingSoft-remove a property binding from a collection; restore_item can recover it.
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_urlRead web pages, PDFs or public JSON/text/CSV/XML feeds.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, and it fetches whatever…
forget_memoryForget a fact.
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.
instantiate_presetInstantiate a named entry PRESET (template) on a Collection — the structured alternative to free-form log_entry.
log_entryHeart rate: pass kind heart_rate_series and value {samples:[{t:ISO,bpm:number}]}; raw samples are archived before the normalized series is stored.
manage_calendar_placementPin, unpin, show or hide a CALENDAR VIEW on the calendar page's sidebar.
manage_guideWRITE a learning decision to a guide entry.
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_propertyRename a user-owned property in every collection using it.
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.
reprocess_attachmentQueue an attached file for extraction and description again from its original bytes, for example after processing failed.
restore_itemRestore a soft-deleted Entry or Collection from the Trash, or a deleted automation (kind "automation", its id from get_automations before the delete)…
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_guide_claimsWRITE claim-level citations for a guide without changing its body: each claim ties one guide section to one source entry at a locator (transcript…
set_page_backgroundSet or clear ONE page's own background — an Entry, Collection, Folder or Global view page (the same owners that carry a banner).
set_property_configSet a binding's per-kind config (advanced — Derived/Control properties, formula recipes, a GPS tracker's wiring map, a Rating's scale under…
set_property_sharedShare a user-owned property for reuse by other collections, or make it local when only one collection uses it.
set_property_unitSet the unit of a user-owned Number property everywhere it is used.
set_relationSet which entries a relation property points at.
set_relation_inverseReplace the source entries pointing at this target through one shared Relation binding.
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_system_property_visibilityChange entry-page visibility of a built-in field without adding or removing it from a Collection.
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.
set_theme_controlsReplace one saved theme's full controls document.
set_theme_deckReplace one saved theme's full deck document — the window frame: layout windowed|fullscreen, gutter/gutterX/gutterY (edge space), gap (between…
shift_entry_dateMove an Entry to a new date/time AND cascade the shift to its sub-entries (the whole subtree moves with it).
sync_guide_skillREGENERATE the short skill that digests a guide entry: when to use the guide, how to retrieve it and its claims, how to query the user's actual…
update_bindingUpdate a Property binding on a Collection: rename it (custom_display_name; an owned property is renamed in EVERY collection using it), toggle…
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_entryHeart rate: pass kind heart_rate_series and value {samples:[{t:ISO,bpm:number}]}; raw samples are archived before the normalized series is stored.

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 entry files <id>List an entry's files and their processing status (--download <dir> saves them all).
kzx attachment upload <id>Attach any file to an entry, keeping its name (--file, --property).
kzx attachment download <id>Save a file's original under its original name (--out, --thumb).
kzx attachment url <id>Print a short-lived link to a file (--expires <seconds>).
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).