feat: MCP server v1.2.0 — guide system + read/write guide tools
Adds full guide system to MCP standalone server. System guides (schema, creating-nodes, edges, dimensions, extract) are bundled and immutable. Users can create up to 10 custom guides via rah_write_guide. Syncs guide infrastructure from main repo to OS repo app code. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.5
parent
2465e7562c
commit
be675be4e0
@@ -0,0 +1,38 @@
|
||||
---
|
||||
name: Creating Nodes
|
||||
description: When and how to create nodes. Link field rules. Synthesis patterns.
|
||||
immutable: true
|
||||
---
|
||||
|
||||
# Creating Nodes
|
||||
|
||||
## When to Create
|
||||
|
||||
- User explicitly asks to save/capture something
|
||||
- Extracting insights from existing content (synthesis)
|
||||
- Ingesting external content (YouTube, website, PDF)
|
||||
|
||||
## Link Field Rules
|
||||
|
||||
- **Has link:** Node directly represents external content (YouTube video, website, PDF, article)
|
||||
- **No link:** Node is derived/synthesized from existing content (ideas, insights, summaries, questions)
|
||||
- Never add a link to synthesis or idea nodes
|
||||
|
||||
## Synthesis Pattern
|
||||
|
||||
When creating a node derived from existing content:
|
||||
1. Create the node WITHOUT a link field
|
||||
2. Call `createEdge` to connect it to ALL source nodes
|
||||
3. Each edge needs an explanation ("Insight extracted from...", "Synthesized from...")
|
||||
|
||||
## Dimension Assignment
|
||||
|
||||
- New nodes should be assigned to relevant existing dimensions
|
||||
- Check locked/priority dimensions — these auto-assign
|
||||
- If no existing dimension fits, create a new one (but prefer existing)
|
||||
|
||||
## Description Field
|
||||
|
||||
- AI auto-generates a ~1 sentence description after creation
|
||||
- Description is used for embeddings and search ranking (5x boost)
|
||||
- Format: what is this node about, in plain language
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
name: Dimensions
|
||||
description: Create, lock, describe, organize, clean up dimensions.
|
||||
immutable: true
|
||||
---
|
||||
|
||||
# Dimensions
|
||||
|
||||
Dimensions are how nodes are categorized and organized. Think of them as flexible tags with descriptions.
|
||||
|
||||
## Operations
|
||||
|
||||
- **Create:** `createDimension(name, description, isPriority)`
|
||||
- **Update:** `updateDimension(name, { newName, description, isPriority })`
|
||||
- **Delete:** `deleteDimension(name)` — removes from all nodes
|
||||
- **Query:** Use sqliteQuery to list dimensions and their node counts
|
||||
|
||||
## Locking (Priority)
|
||||
|
||||
- `isPriority = true` (locked) → dimension auto-assigns to new nodes when relevant
|
||||
- `isPriority = false` (unlocked) → manual assignment only
|
||||
- Lock dimensions that represent active areas of focus
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
- Lowercase, concise (e.g., "ai", "philosophy", "ra-h")
|
||||
- Use singular form where natural
|
||||
- Avoid overlapping names (don't have both "ai" and "artificial-intelligence")
|
||||
|
||||
## Description
|
||||
|
||||
Every dimension should have a description explaining its purpose. This helps the AI correctly assign nodes to dimensions.
|
||||
|
||||
## Cleanup
|
||||
|
||||
- Delete dimensions with 0 nodes
|
||||
- Merge overlapping dimensions (update nodes, then delete the redundant one)
|
||||
- Regularly review dimension list for coherence
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
name: Edges
|
||||
description: Edge philosophy. Explanations, direction, types. Connection patterns.
|
||||
immutable: true
|
||||
---
|
||||
|
||||
# Edges
|
||||
|
||||
## Philosophy
|
||||
|
||||
Edges are the most valuable part of the knowledge graph. Individual nodes are useful; the web of connections between them is what makes the graph powerful.
|
||||
|
||||
## Rules
|
||||
|
||||
1. **Every edge needs an explanation** — why does this connection exist? Be specific.
|
||||
2. **Direction matters** — FROM → TO should read like a sentence
|
||||
3. **Types are inferred** — the system infers category/type from your explanation. Don't set types manually.
|
||||
|
||||
## Direction Convention
|
||||
|
||||
Write the explanation so FROM → TO reads naturally:
|
||||
- Episode → Podcast: "Episode of this podcast"
|
||||
- Book → Author: "Written by this author"
|
||||
- Insight → Source: "Extracted from this source"
|
||||
- Idea → Related idea: "Builds on this concept"
|
||||
|
||||
## Edge Context JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"explanation": "Human-readable reason",
|
||||
"category": "inferred (created_by, features, part_of, source_of, related_to)",
|
||||
"type": "inferred specific type",
|
||||
"confidence": 0.0-1.0,
|
||||
"created_via": "chat|mcp|workflow"
|
||||
}
|
||||
```
|
||||
|
||||
## Hub Traversal
|
||||
|
||||
Hub nodes (most-connected) are the user's core themes. To understand context around a topic:
|
||||
1. Find the relevant hub node
|
||||
2. Use `queryEdge` or sqliteQuery to get its connections
|
||||
3. Traverse outward to related nodes
|
||||
|
||||
## When to Create Edges
|
||||
|
||||
- After creating synthesis/idea nodes (connect to sources)
|
||||
- When user mentions a relationship between topics
|
||||
- When running the Connect or Integrate guides
|
||||
- When obvious connections exist that aren't captured
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
name: Extract
|
||||
description: Extraction pre-check. When to reuse chunks vs re-extract.
|
||||
immutable: true
|
||||
---
|
||||
|
||||
# Content Extraction
|
||||
|
||||
## Pre-Check (REQUIRED)
|
||||
|
||||
Before running any extraction tool, always check the node first:
|
||||
|
||||
1. Call `getNodesById` on the target node
|
||||
2. Check `chunk_status`:
|
||||
- **'chunked'** → content already extracted. Reuse existing chunks. Do NOT re-extract.
|
||||
- **'pending'** or missing → safe to extract
|
||||
- **'failed'** → previous extraction failed, safe to retry
|
||||
|
||||
3. Check if embeddings are available (chunk length > 0)
|
||||
- If available, use `searchContentEmbeddings` instead of re-extracting
|
||||
|
||||
## Extraction Tools
|
||||
|
||||
- **youtubeExtract** — YouTube videos (requires URL with video ID)
|
||||
- **websiteExtract** — Web pages (uses Jina.ai for JS-rendered sites)
|
||||
- **paperExtract** — PDF files (requires direct PDF URL)
|
||||
|
||||
## After Extraction
|
||||
|
||||
- The extracted content goes into `chunk` (full source)
|
||||
- AI generates a `description` (grounding summary)
|
||||
- Embeddings are created automatically
|
||||
- Assign to relevant dimensions
|
||||
@@ -0,0 +1,92 @@
|
||||
---
|
||||
name: Schema
|
||||
description: Full database schema, tables, columns, query patterns.
|
||||
immutable: true
|
||||
---
|
||||
|
||||
# Database Schema
|
||||
|
||||
## Tables
|
||||
|
||||
### nodes
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| id | INTEGER | Primary key, auto-increment |
|
||||
| title | TEXT | Required |
|
||||
| description | TEXT | AI-generated grounding context (~1 sentence) |
|
||||
| content | TEXT | User's notes/thoughts (not source content) |
|
||||
| chunk | TEXT | Full verbatim source content |
|
||||
| chunk_status | TEXT | 'pending', 'chunked', 'failed' |
|
||||
| link | TEXT | External URL (only for nodes representing external content) |
|
||||
| type | TEXT | Nullable (reserved for future use) |
|
||||
| metadata | TEXT | JSON blob (map_position, transcript_length, etc.) |
|
||||
| is_pinned | INTEGER | Legacy — use hub node queries instead |
|
||||
| created_at | TEXT | ISO timestamp |
|
||||
| updated_at | TEXT | ISO timestamp |
|
||||
|
||||
### edges
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| id | INTEGER | Primary key |
|
||||
| from_node_id | INTEGER | FK → nodes.id |
|
||||
| to_node_id | INTEGER | FK → nodes.id |
|
||||
| context | TEXT | JSON: `{ explanation, category, type, confidence, created_via }` |
|
||||
| source | TEXT | 'user', 'ai_similarity', or helper name |
|
||||
| explanation | TEXT | Human-readable reason for connection |
|
||||
| created_at | TEXT | ISO timestamp |
|
||||
|
||||
### dimensions
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| id | INTEGER | Primary key |
|
||||
| name | TEXT | Unique, case-insensitive |
|
||||
| description | TEXT | Purpose description |
|
||||
| is_locked | INTEGER | 1 = priority dimension (auto-assigns to new nodes) |
|
||||
|
||||
### node_dimensions (junction)
|
||||
| Column | Type |
|
||||
|--------|------|
|
||||
| node_id | INTEGER FK → nodes.id |
|
||||
| dimension_id | INTEGER FK → dimensions.id |
|
||||
|
||||
### chunks (for semantic search)
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| id | INTEGER | Primary key |
|
||||
| node_id | INTEGER | FK → nodes.id |
|
||||
| chunk_index | INTEGER | Position in sequence |
|
||||
| text | TEXT | Chunk content |
|
||||
| embedding | BLOB | Vector (via sqlite-vec) |
|
||||
|
||||
### FTS Tables
|
||||
- `chunks_fts` — full-text search on chunk text
|
||||
- `nodes_fts` — full-text search on node title + content
|
||||
|
||||
## Common Query Patterns
|
||||
|
||||
**Top connected nodes (hubs):**
|
||||
```sql
|
||||
SELECT n.id, n.title, n.description, COUNT(DISTINCT e.id) AS edge_count
|
||||
FROM nodes n
|
||||
LEFT JOIN edges e ON (e.from_node_id = n.id OR e.to_node_id = n.id)
|
||||
GROUP BY n.id ORDER BY edge_count DESC LIMIT 5
|
||||
```
|
||||
|
||||
**Nodes in a dimension:**
|
||||
```sql
|
||||
SELECT n.* FROM nodes n
|
||||
JOIN node_dimensions nd ON n.id = nd.node_id
|
||||
JOIN dimensions d ON nd.dimension_id = d.id
|
||||
WHERE d.name = ?
|
||||
```
|
||||
|
||||
**Edges for a node (both directions):**
|
||||
```sql
|
||||
SELECT e.*, n1.title as from_title, n2.title as to_title
|
||||
FROM edges e
|
||||
JOIN nodes n1 ON e.from_node_id = n1.id
|
||||
JOIN nodes n2 ON e.to_node_id = n2.id
|
||||
WHERE e.from_node_id = ? OR e.to_node_id = ?
|
||||
```
|
||||
|
||||
**Use sqliteQuery for any read operation not covered by structured tools.**
|
||||
Reference in New Issue
Block a user