Generated banner for IWE: a Markdown knowledge base you and your AI agent work on together
Generated logo for IWE: a Markdown knowledge base you and your AI agent work on together

IWE: a Markdown knowledge base you and your AI agent work on together

Memory serverOfficial IWE project

Created by IWE

Published in iwe-org/iwe. Publisher page

1,821 GitHub stars

What it is

Markdown knowledge graph — LSP for your editor, CLI + MCP memory for your AI agents
— the description by IWE

AutoGineer overview, from the brain’s own files

IWE provides a shared workspace for humans and AI agents to collaborate on project documentation, specs, and decision logs. By treating a folder of Markdown files as a structured knowledge graph, it allows agents to read, write, and organize information that persists across sessions. It functions as a memory server via the Model Context Protocol (MCP), enabling compatibility with various AI agents while remaining accessible to users through a native Mac app, CLI, or standard text editors like Neovim and VS Code.

How it works

Memory model: Not stated

AutoGineer overview, from the brain’s own files

IWE organizes notes as a collection of Markdown files within a project folder. It uses a CLI and an MCP server to expose these files to AI agents, allowing them to perform operations like searching, creating, and updating notes. The system supports features such as backlinks, link autocomplete, and graph visualization, ensuring that both the user and the AI agent interact with the same underlying document structure.

Folders
FolderRoleFiles
.githubagent-config4
docsdocs70
.githooksfolder1
cratesfolder381
npmfolder15

Requirements

Runtimes: Rust

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Google Antigravity, Kiro, OpenCode, Amp, Roo Code, Cline, JetBrains Junie, Devin (ex-Windsurf)

Set it up

  1. This brain runs code automatically: 1 script. Review .githooks/pre-commit before opening the folder in Claude Code. No step below turns a hook on for you.

    • .githooks/pre-commit: runs on git pre-commit
  2. Not scanned by AutoGineerAutoGineer could not scan everything it runs. https://www.npmjs.com/package/@iwe-org/mcp
  3. Created by IWE. Published in iwe-org/iwe. Licence: Apache License 2.0.

Usage

AutoGineer overview, from the brain’s own files

  • Connect an AI agent to your project notes using the MCP server.
  • Use the CLI to search, create, or reorganize notes from the terminal.
  • Write and browse notes in the native Mac app while an agent works alongside you.
  • Integrate note navigation and autocomplete into your preferred text editor.
  • Maintain a persistent record of project decisions and lessons learned that both you and your agent can access.
“Explore my IWE notes and summarize what's here.”
The agent reads the Markdown files in the designated folder and provides a summary of the project context, decisions, or documentation found.
“Save the decision we just made about the database schema.”
The agent creates or updates a Markdown note in the IWE folder containing the details of the decision for future reference.

Documentation by IWE

IWE: a Markdown knowledge base you and your AI agent work on together

English · 简体中文 · 한국어

Your notes are your agent’s memory. IWE is where you work on them together.

iwe.md · Download for Mac · Docs · Reddit

Image: Crates.io Image: License Image: Documentation

Too many AI conversations start from zero. You explain your project, your decisions, your reasoning — then find yourself explaining it all again next session. Your own notes live somewhere else, out of the agent's reach.

Or worse, the agent “remembers” something in its own internal memory, but you can't easily see what it saved or correct what it got wrong. And that memory doesn't travel with you to the other agents you work with.

IWE gives you and your AI agents one shared place to work, right inside your project: a folder of connected Markdown documents — specs, plans, decisions, and more. Keep your own ideas there, ask your agent to save what you learn together, and return to that context as your work grows. You can read, edit, and organize those documents yourself — and they stay yours.

<br/> <p align="center"> <a href="https://www.youtube.com/watch?v=D58bPkOvbxE"> <img src="https://iwe.md/images/video-thumbnail.jpg" alt="Watch the IWE intro video on YouTube" width="600"> </a> </p> <br/>

Choose how you work

There are four ways to work with IWE. Mix and match them to fit your day:

ToolHow you'll use it
iWe for MacWrite and browse in a native app, and connect your existing Claude/Codex agent.
Your own editorStay in Neovim, Helix, VS Code, or Zed, with note navigation, backlinks, and autocomplete.
CLISearch and manage your notes from the terminal or scripts.
Claude/CodexLet your agent read, write, and organize memory while you work through conversation.

All four work with the same Markdown documents. Draft a spec in your editor, develop it with Claude/Codex, browse it in the iWe app, or search it from the CLI. Use any combination you like; each tool also works independently.

Bring your own AI. Neither the IWE CLI nor the iWe Mac app includes an AI model. Both work on their own as tools for your notes. When you want AI help, use your existing Claude/Codex agent — in terminal or directly in the Mac app.

<a href="https://iwe.md/?ref=readme-shot"><img src="https://iwe.md/images/app/GH-screen-1.1.png" alt="iWe for Mac showing project plans and connected documents" width="820"></a>

<p> <a href="https://iwe.md/?ref=readme-shot"><img src="https://iwe.md/images/app/GH-screen-2.png" alt="Bug tracking with charts" width="32%"></a> <a href="https://iwe.md/?ref=readme-shot"><img src="https://iwe.md/images/app/GH-screen-3.png" alt="Technical documents with code" width="32%"></a> <a href="https://iwe.md/?ref=readme-shot"><img src="https://iwe.md/images/app/GH-screen-4.png" alt="Release documents" width="32%"></a> </p>

Plans · Charts · Technical documents · Releases — click a screenshot to see the iWe app in action on iwe.md.

Why IWE

  • Shared context. Your agent can use the same notes you write for yourself. Notes link to each other, and one note can belong to several topics, so you can follow an idea wherever it connects.

  • Memory you can read. Decisions and lessons saved by your agent are ordinary notes you can browse, correct, or delete.

  • Your notes stay yours. Everything is Markdown in a folder on your machine. Back it up, sync it, or keep it in git. You don't need an IWE cloud account to keep your notes; connecting an AI agent involves that agent's own setup and account requirements.

See it working on iwe.md →

iWe for Mac

If you'd like a dedicated space for your notes, use the native Mac app. Open a folder of notes and you get a fast, keyboard-friendly space to write and browse. You can also connect your existing Claude/Codex agent to work alongside you.

  • Works with your Claude/Codex agent. Connect the agent you already use, ask questions about your notes, and have it draft or reorganize them. Watch its edits appear in the document as it works.

  • Room to experiment. Each agent run is one undo step — try an idea, and roll it back if you don't like it.

  • Follow your ideas. Jump between related notes, search in a few keystrokes, and view Mermaid diagrams right in your documents. Your editor and other tools can keep working on the same files.

See iWe for Mac on iwe.md →

Open a notes folder and start with a note about something you're working on. Once Claude/Codex is connected, try asking it to summarize that note or help you develop an idea.

Your Own Editor

Keep writing in Neovim, Helix, VS Code, or Zed. IWE adds link autocomplete, backlinks, search, and safe renaming across your notes.

Follow the guide for your editor, open your notes folder, and try linking two notes with autocomplete. You can use IWE for your own writing without connecting an AI agent.

CLI

Prefer the terminal? Use IWE to search, create, and reorganize notes, or work it into your scripts. The CLI has no AI built in: these commands work on their own. Your existing Claude/Codex agent can use IWE's tools too.

Install with Homebrew, or choose another option from the installation guide:

brew install iwe-org/iwe/iwe

Then run these commands inside your notes folder:

iwe init
iwe find
iwe find --lexical "project decisions"

iwe find lists your notes; --lexical searches their content. Explore more in the CLI reference and workflow examples.

Claude/Codex

You can use IWE entirely through your agent. Ask Claude/Codex to save decisions, look up past work, and organize what you've learned. The agent works with your notes through IWE, and you can open those files yourself whenever you want.

IWE isn't tied to one AI. The same notes work with Claude Code, Claude Desktop, Codex, Gemini, Cursor, and any tool that supports the Model Context Protocol.

Give Claude/Codex a memory — for Claude Code, install the plugin, then run /iwe:init in any project you want remembered. For Codex, follow the agent connection steps below.

/plugin marketplace add iwe-org/skills
/plugin install iwe@iwe-org
/iwe:init

Then ask it to save a decision from your current work, and open the note it creates in your project.

Connect another agent — with Homebrew installed, install IWE:

brew install iwe-org/iwe/iwe

Run iwe init in your notes folder, then follow the agent connection guide to add the iwec MCP server with that folder as its working directory. For other installation options, see the installation guide.

Once connected, ask your agent: “Explore my IWE notes and summarize what's here.”

Or let the agent set itself up — paste this into any agent that can run commands:

Set up IWE for my notes: install it (brew install iwe-org/iwe/iwe,
npm install -g @iwe-org/iwe, or cargo install iwe iwes iwec), run `iwe init`
in my notes directory, then add the `iwec` MCP server with its working
directory set to that folder.
Docs: https://iwe.md/docs/agentic/

Learn More

Ready-made workspaces: dev-workspace — project memory for a coding agent · marketing-workspace — campaign memory for a marketing agent.

Get Involved

Trying IWE with your own notes? Tell us what felt useful and where you got stuck. Questions, rough edges, and examples of how you use it are all welcome in Discussions.

IWE is open source. You can also report a bug or help improve the documentation.

Community: Twitter/X · Reddit · Discussions

Building on IWE? The CLI and MCP server are the supported ways to integrate today. Tell us what you depend on so we know what not to break.

License

Apache License 2.0

docs/cli-find.md

IWE Find

Search and discover documents in your knowledge base. Combines a text query — --fuzzy (title and key) or --lexical (BM25 full-text) — with a YAML-based filter language.

--fuzzy / --lexical are the CLI surface of the query language's search stage: they select (a document must match to appear) and order by relevance, jointly with the filter. The same stage is available in an operation document via search: { lexical, fuzzy } and through the MCP iwe_query tool.

Usage

iwe find [OPTIONS]
iwe find --fuzzy <QUERY> [OPTIONS]
iwe find --lexical <QUERY> [OPTIONS]

Options

FlagDescriptionDefault
--fuzzy <QUERY>Fuzzy match on document title and key.none
--lexical <QUERY>Lexical (BM25) full-text match on title and body.none
[QUERY]Deprecated: bare positional query. Behaves as --fuzzy and prints a warning.none
--filter <EXPR>Inline YAML filter expression. See Query Language.none
-k, --key <KEY>Match by document key. Repeatable: 1 key uses $eq, 2+ uses $in. Unknown keys match nothing.none
--includes <KEY[:DEPTH]>$includes anchor. Repeatable; anchors are ANDed.none
--included-by <KEY[:DEPTH]>$includedBy anchor. Repeatable; anchors are ANDed.none
--references <KEY[:DIST]>$references anchor. Repeatable; anchors are ANDed.none
--referenced-by <KEY[:DIST]>$referencedBy anchor. Repeatable; anchors are ANDed.none
--max-depth <N>Session default for inclusion anchor flags without a colon-suffix. 0 = unbounded.1
--max-distance <N>Session default for reference anchor flags without a colon-suffix. 0 = unbounded.1
--project <EXPR>Projection: comma-list (name, name=path, name=$selector, $selector) or inline YAML mapping. Replaces the default fields.none
--add-fields <EXPR>Additive projection: same grammar as --project, extends the defaults instead of replacing.none
--blocks <PRED>Locate blocks: adds a blocks field listing each block matching the inline block predicate.none
--matches <PATTERN>Grep over blocks: restricts results to documents whose content matches the Rust regex PATTERN and adds a matches field with the matching lines.none
--sort <field:DIR[:COLLATION]>Sort by frontmatter field. DIR is 1 (asc) or -1 (desc). COLLATION is binary for codepoint order or a BCP-47 locale tag such as sv-SE; default is the workspace locale, and a language without its own collation data uses the root rules.none
-l, --limit <N>Maximum number of results (0 = unlimited).unlimited
--max-tokens <N>Cap total projected $content tokens across all results (0 = unlimited).unlimited
--max-document-tokens <N>Cap projected $content tokens per result, head-truncating with a marker (0 = unlimited).unlimited
-f, --format <FMT>Output format: markdown, keys, json, yaml.markdown

All filter clauses (the text query plus every flag above) are AND-composed at the top level. For OR or NOT, write it inside --filter. See Query Language.

--lexical stems its terms and drops stop words; a query with no searchable terms left matches nothing (a warning suggests --fuzzy for common or partial words).

--max-tokens and --max-document-tokens only act when the projection includes a $content-shaped field — bare $content or a narrowed { $content: PREDICATE }; a narrowed body is counted and capped like a full one, while $blocks / $matches entries cost nothing. A metadata index carries no content tokens, so bound it with --limit. Token budgets are off by default, count body text only, and print a warning: to stderr when they trim the output.

Filter language

--filter accepts a YAML mapping. Bare scalars become equality predicates; $-prefixed keys are operators.

# Bare equality on a frontmatter field
iwe find --filter 'status: draft'

# Multiple top-level keys are ANDed
iwe find --filter '{status: draft, priority: { $gt: 3 }}'

# OR composition
iwe find --filter '$or: [{ status: draft }, { status: review }]'

# Comparison and ordering
iwe find --filter 'priority: { $gte: 3, $lte: 7 }' --sort modified_at:-1

# Membership
iwe find --filter 'tags: rust'                                    # array membership
iwe find --filter 'status: { $in: [draft, review] }'              # any of these

# Presence
iwe find --filter 'reviewed_by: { $exists: false }'

See Query Language for the full operator vocabulary.

Structural anchors

The four $-prefixed graph operators have CLI shortcuts. They walk inclusion edges (block-reference inclusion links) or reference edges (inline links), starting at the named anchor key.

# Direct sub-documents only — scalar shorthand fixes maxDepth: 1
iwe find --included-by projects/alpha

# Walk inclusion edges down 5 levels
iwe find --included-by projects/alpha:5

# Every descendant (unbounded — depth `0` is the unbounded sentinel)
iwe find --included-by projects/alpha:0

# Anchors are ANDed: documents under both alpha and dmytro
iwe find --included-by projects/alpha --included-by people/dmytro

# Per-anchor depth: alpha within 3 levels, dmytro direct only
iwe find --included-by projects/alpha:3 --included-by people/dmytro:1

# Session default for un-suffixed anchors
iwe find --max-depth 5 --included-by projects/alpha --included-by research/q2

# Documents that reference a specific document (inline links)
iwe find --references people/alice

# Walk reference edges within 3 hops
iwe find --referenced-by archive/index:3

# OR composition of structural anchors via --filter
iwe find --filter '$or: [{ $includedBy: projects/alpha }, { $includedBy: projects/beta }]'

The same selector flags are accepted by iwe count, iwe retrieve, iwe tree, iwe export, iwe schema, iwe update, and iwe delete.

Block projection

--project and --add-fields can address blocks — the structural nodes inside each matched document — through three sources, each taking a block predicate. See Query Language for the predicate grammar. A block predicate is structured, so these forms are written as an inline YAML mapping (the comma list reaches only bare $blocks and $content):

# Body narrowed to one section, header included
iwe find -k projects/roadmap --project 'notes: { $content: { $section: Unreleased } }'

# Table of contents: the whole argument is a block predicate (--project only)
iwe find -k guides/handbook --project '{ $header: {} }'

# Located blocks as data: type, section path, own text
iwe find --add-fields 'hits: { $blocks: { $within: Goals, $text: "Q3" } }'

# Grep: matching lines with their locations
iwe find --add-fields 'found: { $matches: "(?i)todo|fixme" }'

Two dedicated flags shortcut the common reads:

# --blocks PRED lowers to: addFields: { blocks: { $blocks: PRED } }
iwe find --blocks '{ $within: Goals, $text: "Q3" }'

# --matches PATTERN lowers to BOTH a membership clause and a projection entry:
#   filter: { $content: { $matches: PATTERN } }
#   addFields: { matches: { $matches: PATTERN } }
# — one-flag grep: only matching documents return, each carrying its lines
iwe find --matches '(?i)todo|fixme'

--blocks adds the located blocks without restricting membership; combine it with --filter '$content: …' (usually the same predicate) to drop non-matching documents. --matches restricts membership on its own.

In markdown output, $blocks and $matches entries print one grep line each — key › section path › text — under the result's index line:

- [Roadmap](projects/roadmap)
projects/roadmap › Goals › Q3 Milestones › Ship the editor integration TODO confirm date

In JSON / YAML, a narrowed $content field is a string (empty when no block matches) and $blocks / $matches fields are arrays of entries carrying path (enclosing section titles), text (own text), and — for $blocks — type.

How it works

  1. Text matching — --fuzzy matches the key and the title using SkimMatcherV2; --lexical runs a BM25 full-text query over title and body.

  2. Filter — --filter and the structural-anchor flags evaluate per document; results are intersected.

  3. Sort — --sort field:DIR orders the matched set; ties are broken by document key.

  4. Limit — applied last.

  5. Project — --project / --add-fields shape each result: frontmatter fields, system fields ($key, $content, edge selectors), or block-addressed sources.

Without a text query, results are sorted by incoming-reference popularity. With --fuzzy, they are sorted by fuzzy match score; with --lexical, by BM25 relevance.

Output formats

Markdown (default)

A compact index — one line per document, meant to be scanned:

- [User Authentication](authentication)
- [Login Flow](login-flow) <- [User Authentication](authentication)
- [Session Management](session-management) <- [User Authentication](authentication)

Each line is - [title](key), followed by any projected edge and scalar fields:

  • Link text is the title. When title is not projected (e.g. --project 'key=$key'), the key string is used instead.

  • Edge fields render as arrows after the link, by direction: incoming (includedBy, referencedBy) as <- [Title](key), outgoing (includes, references) as -> [Title](key). Multiple targets in one field are comma-joined after a single arrow. Empty edges are omitted.

  • Scalar fields render as · name: value. Arrays of scalars join with , ; richer values fall back to compact inline YAML (use -f json/yaml for those).

The index never prints document bodies. Projecting a $content-shaped field (via --project or --add-fields, bare or narrowed) switches the whole invocation to the fenced document block that iwe retrieve emits, with content as the body and other projected fields as frontmatter. A narrowed { $content: PREDICATE } puts the narrowed rendering in the body; several $content-shaped fields concatenate in projection order. $blocks / $matches fields render as grep lines instead (see Block projection).

$ iwe find --fuzzy auth --add-fields '$content'
````markdown #authentication
---
title: User Authentication
---

# User Authentication

…body…

To read full documents, use [`iwe retrieve`](cli-retrieve.md).

### Keys (`-f keys`)

authentication login-flow session-management


One key per line; suitable for piping.

### JSON (`-f json`)

``` json
[
  {
    "key": "authentication",
    "title": "User Authentication",
    "includedBy": []
  }
]

The top-level value is a bare array of result objects. Each object carries the system fields key, title, includedBy, and every user-frontmatter field merged at the top level. includedBy entries are EdgeRef { key, title, sectionPath }.

--project 'title=$title,status' projects only those fields into each result, in the listed order. A bare name projects the frontmatter field of that name; system fields need a $-selector, so bare title reads the frontmatter title and is null for documents whose title comes from their first header — use title=$title (or $title) for the document title.

YAML (-f yaml)

Same shape as JSON, rendered as YAML.

Examples

# All documents, default markdown
iwe find

# Fuzzy search on title and key
iwe find --fuzzy authentication

# Full-text search on title and body
iwe find --lexical "session token"

# Text query AND a frontmatter filter
iwe find --fuzzy auth --filter 'status: draft'

# Roots — documents with no incoming inclusion edges
iwe find --filter '$nor: [{ $includedBy: { match: {} } }]'

# Limit
iwe find --limit 10

# JSON for programmatic use, project two fields
iwe find --project 'title=$title,modified_at' -f json

# Corpus-wide grep with locations
iwe find --matches '(?i)todo|fixme'

# Locate blocks before mutating them with iwe update
iwe find --blocks '{ $within: Goals, $text: "Q3" }'

# One section of one document
iwe find -k projects/roadmap --project 'notes: { $content: { $section: Goals } }'

# Pipe keys to retrieve
iwe find --filter 'status: draft' -f keys | xargs -I {} iwe retrieve -k {}

Deprecated aliases

The following flags pre-date the query language and remain accepted for backward compatibility. Each invocation prints a one-line warning: ... is deprecated to stderr.

DeprecatedUse instead
bare positional QUERY--fuzzy QUERY (or --lexical QUERY for full-text)
--in KEY[:N]--included-by KEY[:N]
--in-any K1 K2--filter '$or: [{ $includedBy: K1 }, { $includedBy: K2 }]'
--not-in KEY--filter '$nor: [{ $includedBy: KEY }]'
--refs-to KEY--references KEY (legacy semantics: ORs $includes and $references)
--refs-from KEY--referenced-by KEY (legacy semantics: ORs $includedBy and $referencedBy)
--roots--filter '$nor: [{ $includedBy: { match: {} } }]'

Technical notes

  • All filter flags AND together at the top level. To compose with OR or NOR, wrap inside --filter.

  • The colon-suffix on an anchor flag (KEY:N) overrides --max-depth / --max-distance for that anchor only. 0 is the unbounded sentinel.

  • Combining -k KEY with a --filter whose top level also contains $key is a parse-time error. Use -k a -k b for multi-key match (lowers to $key: { $in: [a, b] }), or write the OR inside --filter.

  • Both Inclusion Links and inline references count toward incoming_refs.

485 files · 414 not served here

Advantages

  • Shared context allows agents to access and build upon the same notes written by the user. evidence: README.md
  • Memory is stored as human-readable Markdown files that can be easily browsed, corrected, or deleted. evidence: README.md
  • Data remains under user control in local folders, avoiding dependency on proprietary cloud storage. evidence: README.md

Limitations

  • Requires manual setup of the MCP server or CLI tools to enable agent connectivity. evidence: README.md
  • The system does not include an AI model, requiring the user to bring their own agent. evidence: README.md

Security

Risk level: Low risk

This brain runs

Git hooks (1)

  • .githooks/pre-commit (pre-commit): runs on git pre-commit
  • Low risk: scripts-present (.githooks/pre-commit)

Attribution and licence

Created by
IWE
Publisher
IWE (Official IWE project)
Source
iwe-org/iwe · commit b733afe
Licence
Apache License 2.0 (files served here)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by IWE.

Install from source

414 of its files are not served here, so there is no ZIP. iwe-org/iwe at b733afe