← iLiveMyLifeFor developers · CLI · MCP · SDK · React · Plugins

Your graph — from the command line,
and from your AI.

One open package gives you a TypeScript SDK, the ilml CLI, and an MCP server — so you can script your graph, or let Claude, Cursor and Windsurf work inside it directly. A second one, for React, drops a working graph chat onto your own site. And a plugin turns a skill into a package: publish it once, and it runs in someone else’s terminal under their own account, writing results straight into their graph — no app, no login screen, no database to build.

See it move

Your graph, live in the terminal.

Real ilml output — read who you are, walk your graph, and replay every change: who, what, when.

ilml — your graph, live
$ ilml me
════════════════════════════════════════
 User: Ilya Sorokin
 Root node: 000001731b8b…de9ac087
 Source: global config
════════════════════════════════════════
$ ilml tree 000001736056c2cb-2655b2cf545d0001 2
📁 iLiveMyLife — Collaborative Knowledge Graph  [000001736056c2cb…]
├── 📄 Team
├── 📄 Growth
├── 📄 Features
├── 📄 Whitepaper written by Lifebot  [REF]
├── 📄 Product Roadmap
└── 📄 Learning Resources
    … and 16 more
$ ilml itemHistory 000001736056c2cb-2655b2cf545d0001 2
History (2 entries):
────────────────────────────────────────
[5/19/2026, 2:08 PM] Ilya Sorokin — subCreated
  Title: Process: Digital Clone Build-out
  tags: "" → "assist"
────────────────────────────────────────
[5/19/2026, 2:22 PM] Ilya Sorokin — subCreated
  Title: Principle: Unit-Economics Break-Even
First · Install

One install — the CLI and the MCP server.

Node 18+. @ilivemylife/cli gives you the ilml command and the MCP server; for your own code, add the SDK to the project with npm install @ilivemylife/graph-sdk.

install & sign in
npm install -g @ilivemylife/cli
ilml login
ilml doctor   # verify everything works
In your terminal · CLI

Drive your graph with ilml.

The full command set — and every command speaks text or --json, reads from stdin or files, and pipes into shell scripts.

ilml — command reference
# Explore
$ ilml tree# your whole graph, as a tree
$ ilml items <node># a node and its children
$ ilml itemHistory <node># every change — who, what, when
$ ilml search <node> "text"# search a node’s chat
$ ilml messages <node># read a node’s chat
$ ilml itemUsers <node># who has access
$ ilml itemSettings <node># a node’s AI / notification settings
# Ask the AI
$ ilml ask <node> "question"# ask Lifebot, in the node’s context
$ ilml send <node> "message"# post a message (optionally trigger AI)
$ ilml editSettings <node># switch AI provider / smart model per node
# Create & reorganize
$ ilml addItem <parent> --title …# create a node
$ ilml editItem <node> --title/--desc/--tags# edit a node
$ ilml moveItem <node> <from> <to># move to another parent
$ ilml reorderChild <parent> <from> <to># reorder children
$ ilml setPosition <node> <parent> <n># move to a position
$ ilml archiveItem / unarchiveItem <node># archive / restore
$ ilml upload <node> ./file# attach a file
# Collaborate
$ ilml request-access <node># ask to enter a private node
# Plugins
$ ilml plugin install <name># add a plugin (e.g. linkedin)
$ ilml plugin list / update / remove# manage installed plugins
$ ilml <plugin> <command># run a plugin command
# Setup
$ ilml login [--local]# sign in — global or per-project
$ ilml doctor# verify your setup
$ ilml config set <key> <value># configure
$ ilml logout# sign out
Pro

One CLI, many accounts. ilml login signs you in globally — every folder. Run ilml login --local inside a project to use a different account just there (personal vs work, or a dedicated bot account for an automation). Resolution order: local config → .env token → global → shell variable.

text or JSON — composable in shell scripts
# a node + its children, piped into jq
ilml items <node> --json | jq '.[].title'

# walk 4 levels down — nested JSON, children inside children
ilml tree <node> 4 --json > branch.json

# pipe a file straight into the description
cat notes.md | ilml editItem <node> --desc -
In your AI · MCP

Plug your graph into your AI.

It runs locally over stdio — no server to host, no URL to expose. Claude Code takes one command; Claude Desktop, Cursor and Windsurf take the same package as a config entry.

Claude Code — available in every project
claude mcp add --scope user ilml -- npx -y --package=@ilivemylife/cli ilml-mcp
Claude Desktop · Cursor · Windsurf — drop into the MCP config
{ "mcpServers": {
    "ilml": { "command": "npx",
              "args": ["-y", "--package=@ilivemylife/cli", "ilml-mcp"] }
} }

That goes in your client’s MCP config — claude_desktop_config.json for Claude Desktop, ~/.cursor/mcp.json for Cursor, ~/.codeium/windsurf/mcp_config.json for Windsurf. In an assistant that can already edit your files, skip the hunt: “add the MCP server ilml-mcp from @ilivemylife/cli” — and it writes the config for you. The server runs locally over stdio: nothing to host, no URL to paste.

Then just ask, in plain language:

  • Read my latest notifications and summarize what needs my attention.
  • What changed in my “Projects” node this week — and who changed it?
  • Create a task “Call the bank” under My Life, due tomorrow.
  • Search my whole graph for everything about the landing redesign.

And the other way round: with ilml MCP connected as above, start the agent with ilml run claude (or any other terminal agent), and any node can send it work: write /agent and the task, even from your phone. Agent sessions →

In your code · SDK

Or script it yourself.

One typed package (ESM + CommonJS), and your code becomes a participant in the graph rather than a client of a database: it reads and writes nodes under your own access rights, speaks in a node’s chat, asks Lifebot with that node as context, replays who changed what and when, and streams every change as it happens. Storage, real-time, permissions and an AI — none of which you had to build.

Read your graph
const me = await graph.me()
const items = await graph.items(me.rootItemId)
console.log(items[0].title, '→', items.slice(1).map(i => i.title))
Create nodes
const project = await graph.addItem(me.rootItemId, { title: 'My Project' })
await graph.addItem(project.id, { title: 'First task' })
Ask Lifebot — AI that knows the node (needs the 'assist' tag)
const reply = await graph.askLifebot(project.id, 'What tasks do I have?')
console.log(reply.content)
Replayable change history — who, what, when
const history = await graph.itemHistory(project.id)
// every edit on the node: who made it, what changed, and when
Upload a document, search a node's chat
await graph.uploadFile(project.id, './spec.pdf')

// one node's chat, exact match — how a bot
// finds the marker line it posted earlier
const hits = await graph.searchMessages(
    project.id, 'status: deployed')
Live updates — every change, as it happens
import { ITEM_CHANGE_TYPES } from '@ilivemylife/graph-sdk'

const stop = await graph.subscribeToItems(
    project.id,
    (change, item) => {
        // added · edited · removed · movedIn · reorder
        if (change === ITEM_CHANGE_TYPES.added) {
            console.log('new node:', item.title)
        }
    },
    // without it, a dead stream looks like silence
    (err) => console.error(err.name)
)
Typed errors — every read + mutation throws a specific class
import {
    NodeAuthRequiredError,
    ForbiddenError,
    NotFoundError,
} from '@ilivemylife/graph-sdk'

try {
    await graph.editMessage({ id, content })
} catch (e) {
    // editing a message checks the node it lives in:
    // e.itemId + e.options ('private' and/or 'kyc')
    // + e.requestStatus say what the user must do
    if (e instanceof NodeAuthRequiredError) askAccess(e)
    if (e instanceof ForbiddenError) toast('Not yours')
    if (e instanceof NotFoundError) refresh()
}
Access requests — programmatically ask to enter a gated node
const result = await graph.requestAccess(nodeId)

// REQUEST_SENT · REQUEST_PENDING
// ALREADY_ACCESSED · NO_REQUEST_NEEDED
// Anyone already inside gets a Lifebot
// message and approves with a @@mention.
// (A KYC gate throws NodeKycRequiredError —
//  only a human with a card can pass it.)
Pro

Errors that tell you what to do next. Every read and mutation throws a specific class — NodeAuthRequiredError, ForbiddenError, NotFoundError, InvalidOperationError, InvalidRefError, GraphAuthError. The auth error carries.itemId, .options (private and/or kyc — the processes the node demands) and a .requestStatus, so you can dispatch straight to a "request access" or "complete KYC" flow. A wallet node asks for both. Subscriptions take the same callback — so a stream the server refuses tells you why, instead of going quiet.

In the browser · React

Chats and the login, on your own site.

The other half of the pair runs in the browser: @ilivemylife/react-sdk — components and hooks. Two chat surfaces, and the account they share. That account is the visitor's iLiveMyLife wallet: the same one they already use on every other partner site, so there is no sign-up form on your side and no password for you to store. They sign in once, and the session, the profile and the conversations follow them from site to site.

Anyone can ask — no account at all
import { IlmlAskWidget } from '@ilivemylife/react-sdk'

// You own the transport: `ask` calls your own
// service, which holds the account token and asks
// Lifebot in a node you chose. Nothing identifies
// the visitor, nothing is stored.
<IlmlAskWidget
  title="Ask us anything"
  greeting="No account needed."
  ask={q => fetch('/api/ask', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ question: q }),
  }).then(r => r.json()).then(d => d.answer)}
/>
The real node messenger — signed in
import { IlmlChatWidget } from '@ilivemylife/react-sdk'

// Runs under the VISITOR's own token, so it needs
// nothing from your servers — a static site is
// enough. The thread is a node: history, files,
// references, your whole team able to join.
<IlmlChatWidget
  ssoUrl="https://app.ilivemylife.io"
  nodeId={conversationNodeId}
  title="Support"
/>
The login your visitors already have
import { useIlmlSession, IlmlButton } from '@ilivemylife/react-sdk'

// One wallet account across every partner site.
// Mount it where login lives (your header): no
// sign-up form on your side, no password to store.
const s = useIlmlSession({
  ssoUrl: 'https://app.ilivemylife.io',
  ssoRoute: 'partnerLogin',
  graphqlUrl: 'https://api.ilivemylife.io/graphql/v1',
  clientId: 'your-site',
})

if (!s.ready) return null     // no sign-in flash
return s.isLoggedIn
  ? <button onClick={s.logout}>{s.profile.name}</button>
  : <IlmlButton onClick={s.login}>Sign in</IlmlButton>
That session, read from anywhere else
import { useIlmlSessionState } from '@ilivemylife/react-sdk'

// No config, no second login, no prop drilling.
// One `me` fetch is shared by every consumer, and
// a login or logout on any surface reaches all of
// them — across tabs too.
const { isLoggedIn, profile } = useIlmlSessionState()
Build

Which one needs a backend — the fact that decides your build. The signed-in messenger needs nothing from your servers: it works under the visitor's own token, so a static site is enough. The anonymous one does need a small service, because a service token cannot live in a browser where anyone can read it — that service is the only thing standing between your account and the public. We host it, or you run it inside your own perimeter. The chat in the corner of this page is the anonymous kind; the messenger behind a wallet login is the other.

Extend it · Plugins

Install a plugin — or build your own.

Plugins install into your ilml CLI as packages. The LinkedIn plugin is the reference: it keeps a local mirror of your LinkedIn data and runs AI-assisted workflows under your direction — and doubles as the template for authoring your own.

install one / build your own
ilml plugin install linkedin     # from npm:ilml-plugin-linkedin
ilml plugin list                 # what's installed
ilml linkedin <command>          # run a plugin command
# author one → examples/plugin-author.mjs,
#   inside the installed package

Build on your graph.

Your data, your code, your AI — all on one open graph.

Start your graph →
Lifebota few seconds ago
Ask me anything about iLiveMyLife — what a node is, how the AI sees your data, what you can automate, how to build on it. I answer from the project's own notes, so I can go deeper than a page. Nothing you ask here is saved.