Skip to Content
LoreHub is now in open beta! 🎉
DocsAPI Reference

API Reference

LoreHub provides programmatic access through its MCP (Model Context Protocol) server and command-line interface.

MCP Server

The Model Context Protocol server allows AI assistants and other tools to interact with LoreHub.

Starting the Server

lh serve-mcp

This starts a Model Context Protocol server that AI assistants like Claude can connect to.

Available MCP Tools

The MCP server exposes the following tools:

1. search_lores

Search for lores with wildcards and filters.

{ query: string; // Search query (supports wildcards * and ?) realm_path?: string; // Realm to search in type?: string; // Filter by type province?: string; // Filter by province limit?: number; // Max results (default: 50) }

2. list_lores

List lores with optional filters.

{ realm_path?: string; // Realm to list from type?: string; // Filter by type province?: string; // Filter by province limit?: number; // Max results (default: 20) }

3. get_lore

Get a specific lore by ID.

{ lore_id: string; // The lore ID }

4. list_realms

List all tracked realms.

No parameters required.

5. create_lore

Create a new lore.

{ realm_path: string; // Where to create the lore content: string; // The lore content type: string; // Type of lore confidence?: number; // 0-100 (default: 80) why?: string; // Additional context provinces?: string[]; // For monorepos sigils?: string[]; // Tags }

6. update_lore

Update an existing lore.

{ lore_id: string; content?: string; type?: string; confidence?: number; status?: string; why?: string; }

7. delete_lore

Permanently delete a lore.

{ lore_id: string; confirm: boolean; // Must be true }

8. archive_lore

Soft delete a lore.

{ lore_id: string; }

9. restore_lore

Restore an archived lore.

{ lore_id: string; }

10. create_relation

Create relationship between lores.

{ from_lore_id: string; to_lore_id: string; type: string; // supersedes/contradicts/supports/depends_on/relates_to }

11. delete_relation

Remove relationship between lores.

{ from_lore_id: string; to_lore_id: string; type: string; }

12. list_relations

List lore relationships.

{ lore_id: string; direction?: string; // from/to/both (default: both) }

13. get_realm_stats

Get realm statistics.

{ realm_path: string; }

14. semantic_search_lores

Semantic similarity search.

{ query: string; realm_path?: string; threshold?: number; // 0-1 (default: 0.7) limit?: number; // (default: 20) }

15. find_similar_lores

Find similar lores.

{ lore_id: string; threshold?: number; // 0-1 (default: 0.5) limit?: number; // (default: 10) }

MCP Integration Example

{ "mcpServers": { "lorehub": { "command": "node", "args": ["/path/to/node_modules/lorehub/dist/mcp/index.js"] } } }

CLI JSON Output

Most LoreHub commands support JSON output for scripting.

Search JSON Format

lh search "caching" --format json

Output structure:

{ "lores": [ { "id": "abc123", "content": "Use Redis for session caching", "type": "decree", "confidence": 85, "sigils": ["redis", "cache", "performance"], "realm": "main-api", "created_at": "2024-01-15T10:30:00Z" } ] }

List JSON Format

lh list --format json

Output structure:

{ "lores": [ { "id": "def456", "content": "Database migrations timeout on large tables", "type": "risk", "confidence": 90, "provinces": ["database"], "status": "living" } ] }

Export Format

lh export --format json

Output structure:

{ "version": "1.0", "exported_at": "2024-01-15T10:30:00Z", "lores": [ { "id": "abc123", "content": "Always use prepared statements", "type": "wisdom", "confidence": 100, "why": "Prevents SQL injection", "sigils": ["security", "database"], "status": "living", "created_at": "2024-01-10T08:00:00Z", "updated_at": "2024-01-10T08:00:00Z" } ] }

Data Types

Lore Types

type LoreType = | "decree" // Architectural or technical choice | "wisdom" // Something discovered or learned | "belief" // Unverified belief or hypothesis | "constraint" // Limitation or restriction | "requirement" // Business or technical requirement | "risk" // Potential problem or concern | "quest" // Future action needed | "saga" // Major initiative | "story" // User story | "anomaly" // Bug or issue | "other" // Miscellaneous

Lore Status

type LoreStatus = | "living" // Active and current (default) | "ancient" // Outdated but historically important | "whispered" // Uncertain or unverified | "proclaimed" // Officially documented | "archived" // Soft deleted

Relation Types

type RelationType = | "supersedes" // Replaces older knowledge | "contradicts" // Conflicts with another lore | "supports" // Reinforces another lore | "depends_on" // Requires another lore | "relates_to" // General connection

Database Schema

Direct database access is not recommended. Use the CLI or MCP server instead.

Main Tables

-- Realms (tracked repositories) CREATE TABLE realms ( id TEXT PRIMARY KEY, name TEXT NOT NULL, path TEXT NOT NULL UNIQUE, gitRemote TEXT, isMonorepo BOOLEAN DEFAULT 0, provinces TEXT, -- JSON array lastSeen DATETIME, createdAt DATETIME DEFAULT CURRENT_TIMESTAMP ); -- Lores (knowledge entries) CREATE TABLE lores ( id TEXT PRIMARY KEY, realmId TEXT NOT NULL, content TEXT NOT NULL, why TEXT, type TEXT DEFAULT 'other', provinces TEXT, -- JSON array sigils TEXT, -- JSON array confidence INTEGER DEFAULT 80, origin TEXT, -- JSON object status TEXT DEFAULT 'living', createdAt DATETIME DEFAULT CURRENT_TIMESTAMP, updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (realmId) REFERENCES realms(id) ); -- Relations between lores CREATE TABLE lore_relations ( id TEXT PRIMARY KEY, fromLoreId TEXT NOT NULL, toLoreId TEXT NOT NULL, type TEXT NOT NULL, metadata TEXT, -- JSON object strength REAL DEFAULT 1.0, createdAt DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (fromLoreId) REFERENCES lores(id), FOREIGN KEY (toLoreId) REFERENCES lores(id), UNIQUE(fromLoreId, toLoreId, type) ); -- Embeddings for semantic search CREATE VIRTUAL TABLE lores_vec USING vec0( lore_id TEXT PRIMARY KEY, embedding FLOAT[384] ); -- Change log for sync CREATE TABLE change_log ( id TEXT PRIMARY KEY, entityType TEXT NOT NULL, entityId TEXT NOT NULL, realmId TEXT, operation TEXT NOT NULL, changes TEXT, -- JSON object timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, syncStatus TEXT DEFAULT 'pending' );

Scripting Examples

Bash

#!/bin/bash # backup-lores.sh # Create timestamped backup BACKUP_FILE="lores-backup-$(date +%Y%m%d-%H%M%S).json" lh export --format json --output "$BACKUP_FILE" echo "Backup created: $BACKUP_FILE"

Node.js

const { exec } = require('child_process'); const util = require('util'); const execPromise = util.promisify(exec); async function analyzeLores() { // Get all lores const { stdout } = await execPromise('lh export --format json'); const data = JSON.parse(stdout); // Analyze confidence distribution const byConfidence = {}; data.lores.forEach(lore => { const bucket = Math.floor(lore.confidence / 10) * 10; byConfidence[bucket] = (byConfidence[bucket] || 0) + 1; }); console.log('Confidence Distribution:'); Object.entries(byConfidence) .sort(([a], [b]) => a - b) .forEach(([bucket, count]) => { console.log(`${bucket}-${parseInt(bucket)+9}: ${count} lores`); }); } analyzeLores().catch(console.error);

Python

import subprocess import json from collections import Counter def get_lore_stats(): # Execute LoreHub command result = subprocess.run( ['lh', 'export', '--format', 'json'], capture_output=True, text=True ) data = json.loads(result.stdout) # Count by type type_counts = Counter(lore['type'] for lore in data['lores']) print("Lores by Type:") for lore_type, count in type_counts.most_common(): print(f" {lore_type}: {count}") # Average confidence by type print("\nAverage Confidence by Type:") for lore_type in type_counts: lores_of_type = [l for l in data['lores'] if l['type'] == lore_type] avg_confidence = sum(l['confidence'] for l in lores_of_type) / len(lores_of_type) print(f" {lore_type}: {avg_confidence:.1f}%") if __name__ == "__main__": get_lore_stats()

Error Handling

Exit Codes

CodeMeaning
0Success
1General error
2Command not found
3Invalid arguments

Common Errors

  1. Database locked

    • Only one LoreHub process can access the database at a time
    • Solution: Ensure no other LoreHub commands are running
  2. Embeddings not found

    • Semantic search requires embeddings to be generated
    • Solution: Run lh migrate-embeddings
  3. Realm not found

    • The specified path is not a tracked realm
    • Solution: Check path or use lh realm list

Performance Tips

Bulk Operations

For better performance with multiple operations:

# Instead of multiple individual adds lh add "Decision 1" lh add "Decision 2" lh add "Decision 3" # Create a JSON file and import cat > bulk-lores.json << EOF { "lores": [ {"content": "Decision 1", "type": "decree"}, {"content": "Decision 2", "type": "decree"}, {"content": "Decision 3", "type": "decree"} ] } EOF lh import bulk-lores.json

Search Performance

  • Use --limit to reduce result set size
  • Literal search is faster than semantic search
  • Filter by type or province to narrow results
  • Hybrid search balances speed and relevance

Best Practices

  1. Use appropriate types: Choose the most specific lore type
  2. Set meaningful confidence: Reflect your certainty accurately
  3. Add context with why: Future you will thank you
  4. Use consistent sigils: Establish team conventions
  5. Export regularly: Backup your knowledge base

Support

Last updated on