Agent skill

Hypatia

by MarchLiu in MarchLiu/hypatia

Interact with the Hypatia AI memory system using natural language.

MITAuto-check: notesKnowledge Management

Install Hypatia

skills CLI
$ npx skills add MarchLiu/hypatia --skill hypatia -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install MarchLiu/hypatia hypatia --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/MarchLiu/hypatia.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/hypatia .claude/skills/hypatia && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
hypatia
GitHub stars
239
Token cost
~7.9k tokens
SKILL.md length
3,147 words
Files
1
Skills in repo
3
Repo updated
First seen
Licence
MIT

At a glance

Interact with the Hypatia AI memory system using natural language.

  • Works in 3 steps: hypatia — if installed on PATH → ./target/debug/hypatia — debug build in… → ./target/release/hypatia — release build…
  • : user mentions memories
  • SKILL.md covers Binary Location, Shelf Management, Archive Files and Knowledge CRUD, plus 6 more sections
  • Calls sqlite3

What it does

Hypatia is an agent skill from MarchLiu/hypatia. Interact with the Hypatia AI memory system using natural language. Translate user requests into hypatia CLI commands for knowledge CRUD, statement (RDF triple) management, JSE queries, full-text search, and shelf management. Trigger when: user mentions memories, knowledge bases, knowledge graphs, triples, statements, relationships, shelves, or asks to store, recall, remember, record, save, find, or search information in hypatia. Also trigger when user wants to create or explore relationships between concepts…

Its SKILL.md is about 7.9k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Knowledge Management, covering Search implementation, Knowledge bases and Knowledge graphs. It works with Rust. The repository describes itself as: "We can wander through the stacks of the Library of Alexandria, imagining the scrolls and the knowledge they contain. Its destruction is a warning: all we have is…. The licence is MIT.

When your agent uses it

  • : user mentions memories
  • Knowledge bases
  • Knowledge graphs
  • Search information in hypatia

Example prompts

  • “remember that Rust is a systems language”
  • “find everything about Alice”
  • “record that Alice knows Bob”
  • “/hypatia”

Requirements

  • Python 3
  • Pre-approved tools (allowed-tools): Bash, Read, Grep, Glob

Workflow steps

3 steps, taken from the first numbered list in SKILL.md.

  1. hypatia — if installed on PATH
  2. ./target/debug/hypatia — debug build in current project
  3. ./target/release/hypatia — release build in current project

What it can do on your machine

Read from SKILL.md and the folder at commit d32f94e. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves these tools, so the agent can use them without asking each time:

    • Bash
    • Read
    • Grep
    • Glob

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • sqlite3

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Hypatia loads about 7.9k tokens when it runs. Until then it costs about 187 tokens; SKILL.md has 3,147 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~187
When it runs · the whole SKILL.md, loaded when a task matches
~7.9k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: notes

The automated check noted patterns worth knowing about, such as sudo or a known installer.

  • NotePre-approves every shell command (allowed-tools: Bash)SKILL.md
    allowed-tools: Bash, Read, Grep, Glob

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from MarchLiu/hypatia at commit d32f94e, republished under its MIT licence (© MarchLiu). 3,147 words, ~7,931 tokens.

Download SKILL.mdSave it as .claude/skills/hypatia/SKILL.md (or your agent's skills folder).
name
hypatia
description
Interact with the Hypatia AI memory system using natural language. Translate user requests into hypatia CLI commands for knowledge CRUD, statement (RDF triple) management, JSE queries, full-text search, and shelf management. Trigger when: user mentions memories, knowledge bases, knowledge graphs, triples, statements, relationships, shelves, or asks to store, recall, remember, record, save, find, or search information in hypatia. Also trigger when user wants to create or explore relationships between concepts, query existing knowledge, or manage shelves. Examples: 'remember that Rust is a systems language', 'find everything about Alice', 'record that Alice knows Bob', 'search for programming', 'show all knowledge', 'list shelves'.
allowed-tools
Bash, Read, Grep, Glob
user-invocable
true
argument-hint
<natural-language instruction>

Hypatia Query Skill

You are operating the Hypatia CLI — an AI-oriented memory management system. Translate the user's natural language request into the appropriate hypatia CLI command and execute it via Bash.

Binary Location

First check which binary is available:

  1. hypatia — if installed on PATH
  2. ./target/debug/hypatia — debug build in current project
  3. ./target/release/hypatia — release build in current project

Use the first one found. All examples below use hypatia for brevity.

Shelf Management

User saysCommand
"list shelves" / "show connected shelves"hypatia list
"connect shelf at PATH" / "open data at PATH"hypatia connect <path> [-n <name>]
"disconnect shelf NAME" / "close shelf NAME"hypatia disconnect <name>
"export shelf NAME to DEST"hypatia export <name> <dest>

Archive Files

Archive files (images, PDFs, data, etc.) are stored in the shelf's archives/ directory and referenced via archive:// paths.

User saysCommand
"store this image" / "add figure fig.png"hypatia archive-store <file> -n <dest_path>
"get archive fig.png" / "show image path"hypatia archive-get <name>
"copy archive to /tmp"hypatia archive-get <name> -o /tmp/output.png
"list archives" / "show all files"hypatia archive-list

archive-store automatically creates a knowledge entry with file metadata (size, MIME type) and an is_a archive statement. Archive files can be queried via JSE:

bash
hypatia query '["$knowledge", ["$contains", "tags", "archive"]]'
hypatia query '["$knowledge", ["$content", {"mime_type": "image/png"}]]'

To reference an archive when creating knowledge:

bash
hypatia knowledge-create "Euclid Prop 1" -d "equilateral triangle" --figures "archive://euclid/fig1.png"
Scopes

Use --scopes to assign project or global scope to knowledge and statements. The value is comma-separated. Global scope is stored as an empty-string entry, and only a trailing comma writes it: --scopes "," is global only, and --scopes "my-project," is both. --scopes "" stores no scope at all, so global lookups such as ["$has", "scopes", ""] will never find the entry.

bash
# Project-scoped only
hypatia knowledge-create "API convention" -d "REST endpoints use kebab-case" --tags "rule" --scopes "my-project"

# Global scope only (trailing comma; `--scopes ""` would store no scope)
hypatia knowledge-create "prefer immutable" -d "always create new objects" --tags "rule" --scopes ","

# Both project and global (trailing comma)
hypatia knowledge-create "no mock DB" -d "never mock database in tests" --tags "taboo" --scopes "my-project,"
Listing the scopes and tags already in use

A scope or tag you invent is not an error — the entry is stored, and every later lookup by the value you meant misses it. Check before you write:

bash
# What this shelf already uses, with how many entries carry each
hypatia scope list --count
hypatia tag list --count

# Exact values, when you are going to write one back
hypatia scope list --json      # [{"value":"","entries":12},{"value":"my-project",…}]

# Confirm one spelling; exit 0 if in use, 1 if not
hypatia tag exists rule
hypatia scope exists my-project
hypatia scope exists ""        # the global scope

The plain listing prints the global scope as (global). That is a label for the terminal, not the value — the value is the empty string, and --json and exists both give it back verbatim. Never copy (global) into --scopes.

Both cover knowledge and statements. An entry that declares no scopes at all is not listed as global.

User saysCommand
"what scopes/projects are in here?"hypatia scope list --count
"what tags exist?" / "which labels are used?"hypatia tag list --count
"is there already a rule tag?"hypatia tag exists rule

Knowledge CRUD

Knowledge entries are independent information points with a name, content, and tags.

Create
hypatia knowledge-create <name> -d "<data>" -t "<tag1,tag2>" --figures "archive://path/to/file" [--no-embed]

--no-embed keeps the entry out of the vector index: it is still stored and still found by search and query, but it is never embedded, so it costs no model call on the way in and is not a similar result. Use it for raw session logs and other bulk that carries no distilled knowledge. A shelf can skip whole tags instead, with embedding.skip_tags in shelf.toml.

User saysCommand
"remember Rust as a systems programming language"hypatia knowledge-create "Rust" -d "systems programming language" -t "language,compiled"
"save knowledge about Go with tags language and compiled"hypatia knowledge-create "Go" -d "" -t "language,compiled"
"store that Python is a scripting language, tag it as dynamic"hypatia knowledge-create "Python" -d "scripting language" -t "dynamic"
"log this turn but don't make it searchable by meaning"hypatia knowledge-create "msg-42" -d "<turn>" -t "message" --no-embed
Read
hypatia knowledge-get <name>
User saysCommand
"show me knowledge about Rust" / "get Rust entry"hypatia knowledge-get "Rust"
Update
hypatia knowledge-update <name> [-d "<data>"] [-t "<tags>"] [--synonyms "<csv>"] [--figures "<refs>"] [--scopes "<scopes>"] [--no-embed | --embed]

--no-embed takes the entry out of the vector index and discards the vector it had; --embed puts it back, and it is embedded on the next flush. The two are mutually exclusive. --embed does not override the shelf's embedding.skip_tags: an entry can ask for less indexing than its shelf, never more.

Only the fields you pass change. An omitted field keeps its stored value, and exactly "" clears a field, such as -t ""; for tags, "," or " " would store blank tags instead. --scopes replaces the stored scopes and is parsed as on create: end the list with a comma, such as "q,", to include the global scope, or the entry drops out of global lookups. The entry keeps its created_at. Its old vector is discarded, and a new one is generated on the next flush, as after knowledge-create. Updating an entry that does not exist is an error. An update that changes nothing prints Knowledge unchanged: <name> and writes nothing.

User saysCommand
"update Rust's description to mention memory safety"hypatia knowledge-update "Rust" -d "systems programming language with memory safety"
"retag Go as language and google"hypatia knowledge-update "Go" -t "language,google"
"remove all tags from Python"hypatia knowledge-update "Python" -t ""
Delete
hypatia knowledge-delete <name>
User saysCommand
"delete knowledge Rust" / "remove the Rust entry"hypatia knowledge-delete "Rust"

Statement Creation — Proactive Graph Building

Statements are RDF-style triples: (head, relation, tail). They form the edges of the knowledge graph.

Key Principle: Always Enrich with Relationships

When the user asks to store or remember information, always create statements alongside knowledge entries to build graph connectivity. The goal is a rich, traversable knowledge graph, not isolated data points.

Pattern: After creating a knowledge entry, identify entities mentioned in the content and create $triple relationships between them. At minimum, create one is_a statement for every new knowledge entry.

hypatia statement-create <head> <relation> <tail> -d "<data>" [--no-embed]

--no-embed works as it does on knowledge-create: the triple is still stored and still traversable, but gets no vector. Two differences: statements carry no tags, so a shelf's embedding.skip_tags cannot reach them and bulk links must say --no-embed themselves; and there is no statement-update, so the choice is made once at creation.

Triple Extraction Patterns
User saysheadrelationtail
"record that Alice knows Bob"AliceknowsBob
"X is a Y" / "X is an Y"Xis_aY
"X belongs to Y" / "X is part of Y"Xbelongs_toY
"X works for Y"Xworks_forY
"X is related to Y"Xrelated_toY
"X depends on Y"Xdepends_onY
"X uses Y"XusesY
"X contains Y"XcontainsY
"X created Y"Xcreated_byY (reversed)

Normalize relations to snake_case. Common relations: is_a, knows, related_to, works_for, belongs_to, depends_on, uses, contains, created_by.

Proactive Creation Examples

When the user says "remember that Rust is a systems programming language", execute BOTH:

bash
hypatia knowledge-create "Rust" -d "systems programming language" -t "language,compiled"
hypatia statement-create "Rust" "is_a" "systems programming language"

When the user says "remember that PostgreSQL is a relational database used by the API", execute:

bash
hypatia knowledge-create "PostgreSQL" -d "relational database" -t "database,relational"
hypatia statement-create "PostgreSQL" "is_a" "relational database"
hypatia statement-create "API" "depends_on" "PostgreSQL" -d "primary data store"

When the user says "note that Alice is a senior engineer on the Backend team", execute:

bash
hypatia knowledge-create "Alice" -d "senior engineer on Backend team" -t "person,engineer"
hypatia statement-create "Alice" "is_a" "senior engineer"
hypatia statement-create "Alice" "works_for" "Backend team"
Auto-linking Rules

When creating knowledge entries, automatically extract and create statements for:

  1. Category: "X" is_a "<category>" — every entity has a type
  2. Dependencies: if the content mentions tools, frameworks, or systems X depends on → X depends_on Y
  3. Relationships: if the content mentions other entities → link them with appropriate relations
  4. Containment: if X is part of Y → X belongs_to Y

Thinking Aloud Protocol

Every query execution MUST be preceded by a brief explanation. Before running any hypatia command, output a thinking block in this format:

**Step N: <goal>**

> `hypatia <command>`

为什么用这个查询:<1-2 sentence explanation of why this operator/strategy was chosen>
预期结果:<what kind of results to expect>

Then execute the command. After results come back, briefly interpret them before deciding the next step.

Example Walkthrough

User asks: "查找与 Alice 相关的所有知识,以及她的关系网络"

**Step 1: 直接获取 Alice 的知识条目**

> `hypatia knowledge-get "Alice"`

为什么用这个查询:用户提到了明确的实体名 "Alice",先尝试直接 lookup 获取完整条目。
预期结果:如果存在,返回 Alice 的知识条目(content, tags, figures 等)。

(执行... 得到结果或 "not found")

**Step 2: 查找 Alice 参与的所有三元组关系**

> `hypatia query '["$statement", ["$triple", "Alice", "$*", "$*"]]'`

为什么用这个查询:用 $triple 对 head 位精确匹配 "Alice",wildcard relation 和 tail,
这样可以拿到 Alice 作为主语的所有关系(knows, is_a, works_for 等),$triple 走索引,比 $search 更快更精确。
预期结果:返回所有 Alice 作为 head 的 statement triples。

(执行... 得到结果)

**Step 3: 查找指向 Alice 的关系(Alice 作为 tail)**

> `hypatia query '["$statement", ["$triple", "$*", "$*", "Alice"]]'`

为什么用这个查询:上一步只查了 Alice 作为 head 的关系,但其他人可能指向 Alice(如 "Bob knows Alice"),
需要查 tail 位 = Alice 的三元组才能得到完整的关系网络。
预期结果:返回所有以 Alice 为宾语的 statement triples。

(执行... 得到结果)

**Step 4: 2-hop 图遍历,探索 Alice 的更远关系**

> `hypatia query '["$statement", ["$k-hop", "Alice", "$*", 2]]'`

为什么用这个查询:前两步只查了 Alice 的直接关系,用户问的是"关系网络",需要通过 2-hop 递归遍历
发现 Alice → Bob → Charlie 这样的间接关系。$k-hop 用递归 CTE 实现,适合图探索。
预期结果:返回 Alice 的 2-hop 邻域内所有 statement triples。
Rules for Thinking Aloud
  1. Always explain before executing — never run a query silently
  2. Explain the "why" — which operator was chosen and why, not just what it does
  3. Keep it concise — 1-2 sentences for explanation, 1 sentence for expected results
  4. Interpret results — after each step, briefly note what was found before deciding next steps
  5. Multi-step reasoning — for complex requests, show the decomposition into steps and explain the strategy
  6. Empty results are informative — if a query returns nothing, explain what that tells us and adjust strategy

Search Strategy — Graph-First Retrieval

When searching for information, prefer precise graph operators over broad FTS search. Use the following decision tree:

Search Decision Tree

For each step, include the thinking aloud explanation before executing.

1. User mentions a specific entity name?
   → knowledge-get (direct lookup)

2. User asks about relationships involving a known entity?
   → $triple operator (fastest, indexed)

3. User asks about a type of relationship (e.g., "who works for X")?
   → $triple with wildcard on entity positions

4. User wants to explore graph neighborhood (e.g., "who can X reach in 2 hops")?
   → $k-hop operator (graph traversal)

5. User wants semantic/similarity search (e.g., "find similar concepts")?
   → hypatia similar (vector search)

6. User wants to match a pattern (e.g., "names starting with X")?
   → $like operator

7. User wants to filter by content attributes (e.g., "markdown entries", "entries with specific format")?
   → $content operator

8. User asks about a specific entity's relationships?
   → $triple + knowledge-get combined

9. Broad/ambiguous query?
   → $search (FTS fallback)
Prefer $triple over $search for entity queries

When the query involves a known entity (person, tool, concept), use $triple for precise, indexed lookups instead of FTS:

Instead ofUse
["$statement", ["$search", "Alice"]]["$statement", ["$triple", "Alice", "$*", "$*"]]
["$statement", ["$search", "manages"]]["$statement", ["$triple", "$*", "manages", "$*"]]
["$statement", ["$contains", "triple", "Alice"]]["$statement", ["$triple", "Alice", "$*", "$*"]]
Combined Queries

For rich retrieval, combine graph traversal with content filtering:

bash
# Find all relationships involving Alice, created after a date
hypatia query '["$statement", ["$and", ["$triple", "Alice", "$*", "$*"], ["$gt", "created_at", "2025-01-01"]]]'

# Find all knowledge entries in markdown format about a topic
hypatia query '["$knowledge", ["$and", ["$content", {"format": "markdown"}], ["$search", "database"]]]'

# Find all people (entities that are_a "engineer")
hypatia query '["$statement", ["$triple", "$*", "is_a", "engineer"]]'

Search is the fallback for broad or ambiguous queries. It covers both knowledge and statements.

hypatia search <query> [-c <catalog>] [--limit N] [--offset N]
  • -c knowledge — search only knowledge entries
  • -c statement — search only statements
  • No -c — search everything
Examples
User saysCommand
"search for programming" / "find everything about programming"hypatia search "programming"
"search knowledge for rust"hypatia search "rust" -c knowledge
"what do you know about databases?"hypatia search "databases"

Semantic search using embedding vectors. Finds entries with similar meaning, even when keywords don't match.

hypatia similar <query> [--limit N] [-t knowledge|statement|both] [--tags <a,b>] [--exclude-tags <a,b>] [--where '<JSE condition>']

--tags keeps entries carrying at least one of the tags, --exclude-tags drops entries carrying any of them, and --where takes a JSE condition such as ["$contains", "scopes", "project-a"] ($eq, $like, $contains, $and/$or/$not and the other filters $knowledge takes, but not $search, $similar or $k-hop). They narrow the entries before ranking, so --limit N still returns N entries whenever that many qualify. --exclude-tags message,summary,session keeps the session-log layer from crowding out the knowledge distilled from it. With the default target both the filter applies to statements too, so a condition on name needs -t knowledge.

Requires an embedding model configured in shelf.toml (default: BAAI/bge-m3).

Entries are embedded in batches after they are written or updated. With a remote embedding API, similar can miss entries changed in the last minute; search finds them at once.

Entries written with --no-embed, and entries carrying a tag the shelf lists in embedding.skip_tags, are never embedded and so are never similar results. search and query still find them. Each entry keeps the answer it was written with, so after changing skip_tags run hypatia backfill once to settle what is already stored.

Examples
User saysCommand
"find similar to distributed systems"hypatia similar "distributed systems"
"semantic search for memory management"hypatia similar "memory management" --limit 5
"what do we know about auth, not the chat logs"hypatia similar "auth" --exclude-tags message,summary,session
"rules like this one for project-a"hypatia similar "<rule text>" -t knowledge --tags rule --where '["$contains", "scopes", "project-a"]'

JSE Query Translation

JSE (JSON Search Expression) enables precise queries against the knowledge or statement tables.

hypatia query '<JSE-JSON>' [-s <shelf>]
Query Structure

The top-level operator is always $knowledge or $statement:

json
["$knowledge", condition1, condition2, ...]
["$statement", condition1, condition2, ...]

No conditions means "return all":

json
["$knowledge"]
Operator Reference
OperatorPurposeSyntax
$eqEquals["$eq", "field", "value"]
$neNot equals["$ne", "field", "value"]
$gtGreater than["$gt", "field", "value"]
$ltLess than["$lt", "field", "value"]
$gteGreater than or equal["$gte", "field", "value"]
$lteLess than or equal["$lte", "field", "value"]
$likeSQL LIKE pattern match["$like", "field", "pattern"]
$containsSubstring match in content JSON["$contains", "field", "value"]
$contentMatch content JSON key-value pairs["$content", {"key": "value"}]
$searchFull-text search (FTS)["$search", "query text"]
$andLogical AND["$and", cond1, cond2, ...]
$orLogical OR["$or", cond1, cond2, ...]
$notLogical NOT["$not", condition]
$tripleTriple position match["$triple", "Alice", "$*", "Bob"]
$k-hopK-hop graph traversal (statement only)["$k-hop", "head", "relation", depth]
$hasExact membership in a JSON field (arrays: element; scalars: equality; array value = any-of) — indexed["$has", "tags", "rust"]
$json-containsStructural containment (PG @>) — indexed recall + exact recheck["$json-contains", {"tags": ["rust"]}]
Show full SKILL.md (1,299 more words)Show less
Critical Syntax Rules
  1. $and and $or take multiple operands directly, NOT a nested array:

    • CORRECT: ["$and", ["$eq", "name", "rust"], ["$contains", "tags", "systems"]]
    • WRONG: ["$and", [["$eq", "name", "rust"], ["$contains", "tags", "systems"]]]
  2. $search must be inside $knowledge or $statement, never top-level. When inside $knowledge, it searches FTS with catalog=knowledge. When inside $statement, it searches with catalog=statement.

  3. Field names like "name", "triple" are used as plain strings. For content JSON sub-fields (e.g., tags), $contains uses json_extract_string automatically.

  4. Available fields for knowledge: name, created_at, plus any content JSON field via $contains.

  5. Available fields for statement: triple (CSV-formatted head,relation,tail), head, relation, tail, created_at, tr_start, tr_end, plus content JSON fields via $has/$contains. For position-based triple matching, prefer $triple over $contains.

  6. New in 0.3: $has is the exact-membership operator (indexed; use it for tags/scopes lookups). $contains on array fields (tags/scopes/figures) routes to exact membership too; on other fields it stays substring. $json-contains matches whole-document containment (PG @>), e.g. ["$json-contains", {"tags": ["rust"]}].

$triple Operator

The $triple operator provides position-based matching on statement triples. Each argument corresponds to head, relation, or tail. Use "$*" as a wildcard to match any value.

["$triple", <head_pattern>, <relation_pattern>, <tail_pattern>]
PatternMeaning
"Alice"Exact match
"$*"Wildcard — match any value

Behavior:

  • All 3 specified (no wildcards): uses triple = ? (primary key lookup, fastest)
  • Partial match: generates conditions on individual columns (head = ? AND tail = ?, etc.)
  • At least one non-wildcard required — all wildcards is an error
  • Arguments must be exactly 3
User saysJSECommand
"find all relationships where Alice is the head"["$statement", ["$triple", "Alice", "$*", "$*"]]hypatia query '["$statement", ["$triple", "Alice", "$*", "$*"]]'
"find all knows relationships"["$statement", ["$triple", "$*", "knows", "$*"]]hypatia query '["$statement", ["$triple", "$*", "knows", "$*"]]'
"find everything related to Bob as tail"["$statement", ["$triple", "$*", "$*", "Bob"]]hypatia query '["$statement", ["$triple", "$*", "$*", "Bob"]]'
"find the exact Alice knows Bob triple"["$statement", ["$triple", "Alice", "knows", "Bob"]]hypatia query '["$statement", ["$triple", "Alice", "knows", "Bob"]]'
"Alice's relationships with Bob, combined with date filter"["$statement", ["$and", ["$triple", "Alice", "$*", "Bob"], ["$gt", "created_at", "2025-01-01"]]]hypatia query '["$statement", ["$and", ["$triple", "Alice", "$*", "Bob"], ["$gt", "created_at", "2025-01-01"]]]'
$like Operator

SQL LIKE pattern matching with user-defined wildcards (% = any chars, _ = single char).

["$like", "field", "pattern"]
User saysJSECommand
"find entries whose name starts with Rust"["$knowledge", ["$like", "name", "Rust%"]]hypatia query '["$knowledge", ["$like", "name", "Rust%"]]'
"find entries created in January 2025"["$knowledge", ["$like", "created_at", "2025-01-%"]]hypatia query '["$knowledge", ["$like", "created_at", "2025-01-%"]]'
"find statements with head matching pattern"["$statement", ["$like", "head", "Alice%"]]hypatia query '["$statement", ["$like", "head", "Alice%"]]'
$content Operator

Match key-value pairs inside the content JSON column. Checks exact string equality for each specified key.

["$content", {"key1": "value1", "key2": "value2"}]
User saysJSECommand
"find all markdown-format entries"["$knowledge", ["$content", {"format": "markdown"}]]hypatia query '["$knowledge", ["$content", {"format": "markdown"}]]'
"find json-format statements"["$statement", ["$content", {"format": "json"}]]hypatia query '["$statement", ["$content", {"format": "json"}]]'
"find entries with specific data and format"["$knowledge", ["$content", {"format": "markdown", "data": "hello"}]]hypatia query '["$knowledge", ["$content", {"format": "markdown", "data": "hello"}]]'
$k-hop Operator

K-hop graph traversal on statement triples using recursive CTE. Explores entity neighborhoods and relationship paths.

["$k-hop", "head", "relation", depth]
  • "head" — starting entity (required)
  • "relation" — filter by relation, or use "$*" for any
  • depth — number of hops (positive integer)
User saysJSECommand
"who can Alice reach in 2 hops?"["$statement", ["$k-hop", "Alice", "$*", 2]]hypatia query '["$statement", ["$k-hop", "Alice", "$*", 2]]'
"what's reachable from Alice via knows in 3 hops?"["$statement", ["$k-hop", "Alice", "knows", 3]]hypatia query '["$statement", ["$k-hop", "Alice", "knows", 3]]'
"explore the graph around PostgreSQL"["$statement", ["$k-hop", "PostgreSQL", "$*", 2]]hypatia query '["$statement", ["$k-hop", "PostgreSQL", "$*", 2]]'
Natural Language to JSE Examples
User saysJSECommand
"find knowledge named rust"["$knowledge", ["$eq", "name", "rust"]]hypatia query '["$knowledge", ["$eq", "name", "rust"]]'
"find all relationships involving Alice"["$statement", ["$triple", "Alice", "$*", "$*"]]hypatia query '["$statement", ["$triple", "Alice", "$*", "$*"]]'
"who does Alice know?"["$statement", ["$triple", "Alice", "knows", "$*"]]hypatia query '["$statement", ["$triple", "Alice", "knows", "$*"]]'
"what type of things relate to Bob?"["$statement", ["$triple", "$*", "$*", "Bob"]]hypatia query '["$statement", ["$triple", "$*", "$*", "Bob"]]'
"find knowledge named rust that contains 'systems' in tags"["$knowledge", ["$and", ["$eq", "name", "rust"], ["$contains", "tags", "systems"]]]hypatia query '["$knowledge", ["$and", ["$eq", "name", "rust"], ["$contains", "tags", "systems"]]]'
"find knowledge NOT named rust"["$knowledge", ["$not", ["$eq", "name", "rust"]]]hypatia query '["$knowledge", ["$not", ["$eq", "name", "rust"]]]'
"find all is_a relationships"["$statement", ["$triple", "$*", "is_a", "$*"]]hypatia query '["$statement", ["$triple", "$*", "is_a", "$*"]]'
"find entries whose name starts with 'Al'"["$knowledge", ["$like", "name", "Al%"]]hypatia query '["$knowledge", ["$like", "name", "Al%"]]'
"show all knowledge"["$knowledge"]hypatia query '["$knowledge"]'
"find knowledge created after 2025-01-01"["$knowledge", ["$gt", "created_at", "2025-01-01"]]hypatia query '["$knowledge", ["$gt", "created_at", "2025-01-01"]]'
"find knowledge containing 'language' in data"["$knowledge", ["$contains", "data", "language"]]hypatia query '["$knowledge", ["$contains", "data", "language"]]'
Options (limit, offset, catalog)

Use object form for the top-level operator to pass options:

json
{"$knowledge": [["$search", "rust"]], "limit": 10, "offset": 0}

Command: hypatia query '{"$knowledge": [["$search", "rust"]], "limit": 10}'

Disambiguation Rules

When the user's request is ambiguous, follow this priority:

  1. Exact name mentioned ("get Rust", "show Alice") → knowledge-get for direct lookup
  2. Explicit type ("find knowledge about X" / "find statements about X") → JSE query with the corresponding top-level operator
  3. Relationship language ("who does Alice know?", "what is Rust related to?", "relationships of X") → JSE $statement query with $triple operator
  4. Graph exploration ("who can Alice reach?", "what's connected to X", "neighborhood of X") → JSE with $k-hop operator
  5. Semantic/similarity ("find similar to X", "things like X", "semantically related") → hypatia similar (vector search)
  6. Pattern matching ("names starting with X", "entries from January") → JSE with $like operator
  7. Content filtering ("markdown entries", "entries with format X") → JSE with $content operator
  8. Broad/ambiguous ("find everything about X", "what do you know about X") → hypatia search (covers both knowledge and statements)
  9. Create/store/remember → knowledge-create + statement-create (always create relationships alongside knowledge entries)

Shell Escaping

Always wrap JSE JSON in single quotes to prevent shell interpretation of $, ", !, etc.:

bash
hypatia query '["$knowledge", ["$eq", "name", "rust"]]'

If the content contains single quotes, escape them:

bash
hypatia query '["$knowledge", ["$eq", "name", "Alice'\''s project"]]'

Output Format

  • Knowledge entries: {"name": "...", "content": {"format": "...", "data": "...", "tags": [...]}, "created_at": "..."}
  • Statements: {"triple": "head,relation,tail", "head": "...", "relation": "...", "tail": "...", "content": {...}, "created_at": "...", "tr_start": "...", "tr_end": "..."}
  • Search results: {"id": N, "catalog": "...", "key": "...", "content": "...", "rank": N.N}
  • Empty results: prints "No results found."

Sandboxed / Read-Only Direct Access (known workaround)

When running inside a sandboxed harness (e.g. DSH workspace-write), the hypatia CLI and plain sqlite3 ~/.hypatia/... may both fail with SQLite error 14 (unable to open database file): even read-only SQLite needs to create WAL/journal temp files next to the database, and ~/.hypatia lies outside the writable workspace. Do not retry the same failing command — go straight to the immutable read-only URI, which needs no journal and no directory writes:

bash
sqlite3 "file:<shelf-dir>/hypatia.sqlite?mode=ro&immutable=1" "SELECT count(*) FROM knowledge;"
  • Use only for reads (SELECT). Never write through this path — immutable=1 tells SQLite the file never changes, so writes would corrupt state or be lost.
  • First, get <shelf-dir> from hypatia list, which prints the directory each shelf is open at. Do not assume ~/.hypatia/<shelf>/: any shelf, default included, can be registered elsewhere. If the CLI itself cannot run, read the paths from ~/.hypatia/shelves.json.
  • Then check the -wal/-shm siblings; if a WAL exists and is non-empty, immutable=1 may miss recent un-checkpointed rows — in that case prefer requesting wider sandbox permissions for a normal read instead.
  • Schema hints: tables include knowledge and statement; statement triples are stored in head / relation / tail columns.

This fallback was validated: the same query fails at error 14 without the URI params and returns correctly with them.

Important Notes

  • There is no statement-get CLI command. Use JSE queries ($statement with conditions) to find statements. statement-delete is available for deletion.
  • The -s / --shelf flag defaults to "default" for all commands.
  • The REPL mode (hypatia repl) is interactive and should NOT be used from this skill. Always use one-shot CLI commands.
  • Content (-d) is stored as a string in the content JSON's data field.
  • Tags (-t) are comma-separated strings.
  • Always create statements alongside knowledge entries to maintain graph connectivity. Every knowledge entry should have at least one corresponding is_a statement.
  • Normalize relative temporal expressions to absolute dates/times before storing. When content contains "明天", "下周一", "三小时后", "tonight", etc., rewrite them using the current date/time as the reference point. Example: "明天提醒我备份数据" → store "2026年8月29日提醒我备份数据". A relative date is meaningless when the memory is recalled later.

© MarchLiu, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/hypatia of MarchLiu/hypatia.

Open the folder on GitHubat commit d32f94e

Compare with similar skills

Hypatia next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Hypatia compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Hypatia this skillMarchLiu/hypatia239—~7.9kAutomated safety check: NotesMIT
Engraphdevwhodevs/engraph171—~792Automated safety check: PassMIT
Wiki Viewerrohitg00/pro-workflow2.9k—~1.1kAutomated safety check: PassNone
Graph Searchathola/claude-night-market341—~555Automated safety check: PassMIT
LLM Wiki Knowledge GraphEgonex-AI/Understand-Anything86k—~1.5kAutomated safety check: PassMIT
Project Orchestratorthis-rs/project-orchestrator140—~2.6kAutomated safety check: PassCustom licence

Similar skills

  • Engraph

    devwhodevs/engraph

    Index and search document collections using hybrid semantic + graph + full-text search.

    171 GitHub stars~792 tokensUpdated 4 mo ago
    Knowledge ManagementAuto-check passed
  • Wiki Viewer

    rohitg00/pro-workflow

    Render a self-contained HTML viewer for a pro-workflow wiki.

    2.9k GitHub stars~1.1k tokensUpdated 10 days ago
    Knowledge ManagementAuto-check passed
  • Graph Search

    athola/claude-night-market

    Searches the code knowledge graph by function, class, or type using FTS5 full-text search.

    341 GitHub stars~555 tokensUpdated 4 days ago
    Knowledge ManagementAuto-check passed
  • LLM Wiki Knowledge Graph

    Egonex-AI/Understand-Anything

    Detects a Karpathy-pattern LLM wiki and builds an interactive knowledge graph with entities, implicit relationships and topic clusters.

    86k GitHub stars~1.5k tokensUpdated yesterday
    Knowledge ManagementAuto-check passed
  • Project Orchestrator

    this-rs/project-orchestrator

    AI agent orchestrator with Neo4j knowledge graph, Meilisearch search, and Tree-sitter parsing.

    140 GitHub stars~2.6k tokensUpdated yesterday
    Knowledge ManagementAuto-check passed
  • My Wiki

    NimaChu/my-wiki

    Work with a local My Wiki knowledge base, Dashboard, and knowledge graph.

    124 GitHub stars~674 tokensUpdated 2 days ago
    Knowledge ManagementAuto-check passed

More from MarchLiu/hypatia

  • Hypatia Dream

    MarchLiu/hypatia

    Run an incremental Hypatia graph-consolidation pass at a work-period boundary, like sleep-time knowledge organization.

    239 GitHub stars~4.4k tokensUpdated 10 days ago
    Auto-check: notes
  • Hypatia Memory

    MarchLiu/hypatia

    Automatic memory extraction and management for hypatia knowledge graph

    239 GitHub stars~5.5k tokensUpdated 10 days ago
    Auto-check: notes

Works with

Questions about Hypatia

What does Hypatia do?

Interact with the Hypatia AI memory system using natural language. Hypatia is an agent skill from MarchLiu/hypatia. Interact with the Hypatia AI memory system using natural language.

When should I use Hypatia?

Hypatia fits situations like: : user mentions memories; knowledge bases; knowledge graphs; search information in hypatia.

How do I install Hypatia in Claude Code?

Run `npx skills add MarchLiu/hypatia --skill hypatia -a claude-code`. Or copy the skill folder (skills/hypatia in MarchLiu/hypatia) into .claude/skills/hypatia in your project. Claude Code loads it when a task matches its description.

How do I install Hypatia in Codex?

Run `npx skills add MarchLiu/hypatia --skill hypatia -a codex`. Or copy the skill folder (skills/hypatia in MarchLiu/hypatia) into .agents/skills/hypatia in your project. Codex loads it when a task matches its description.

Can I use Hypatia in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add MarchLiu/hypatia --skill hypatia -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/hypatia, .gemini/skills/hypatia, .github/skills/hypatia and .opencode/skills/hypatia in your project.

What does Hypatia need to run?

Going by SKILL.md and its folder, Hypatia needs the command-line tools its instructions call (sqlite3). Our summary lists: Python 3. Its frontmatter pre-approves these tools: Bash, Read, Grep, Glob.

Does Hypatia access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Hypatia safe to install?

Our automated static check of SKILL.md found notes only (pre-approves every shell command (allowed-tools: bash)), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.

What licence does Hypatia use?

Hypatia is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Hypatia use?

About 7.9k tokens (SKILL.md is roughly 32k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Hypatia?

Skills that share tags, products or a category with Hypatia: Engraph (devwhodevs/engraph, 171 stars), Wiki Viewer (rohitg00/pro-workflow, 2.9k stars), Graph Search (athola/claude-night-market, 341 stars) and LLM Wiki Knowledge Graph (Egonex-AI/Understand-Anything, 86k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Hypatia?

MarchLiu (a GitHub user) maintains it in MarchLiu/hypatia, which has 239 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on September 29, 2026.

Source: MarchLiu/hypatia on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.