feat: add frictionless RA-H OS setup
- Add MCP setup, doctor, init-db, config, and rules CLI commands - Publish latest MCP package wiring and local setup helper - Update OS install docs for MCP-only, full app, and demo-safe setup Generated with Claude Code
This commit is contained in:
@@ -1,44 +1,54 @@
|
||||
# RA-H MCP Server
|
||||
|
||||
Connect Claude Code and Claude Desktop to your RA-H knowledge base. This package talks directly to an existing RA-H SQLite database.
|
||||
Connect Claude Code, Claude Desktop, Cursor, Codex, and other MCP clients to your RA-H knowledge base. This package talks directly to the local RA-H SQLite database.
|
||||
|
||||
## Install
|
||||
## Quick Install
|
||||
|
||||
```bash
|
||||
npx --yes ra-h-mcp-server@2.1.2
|
||||
npx -y ra-h-mcp-server@latest setup --client claude-code --yes
|
||||
```
|
||||
|
||||
Run RA-H once first so the database exists, then use the MCP server from any client.
|
||||
The setup command creates or verifies the database, prints or writes MCP config for the selected client, and runs `doctor`.
|
||||
|
||||
Other useful commands:
|
||||
|
||||
```bash
|
||||
npx -y ra-h-mcp-server@latest setup --client cursor --yes
|
||||
npx -y ra-h-mcp-server@latest setup --client codex
|
||||
npx -y ra-h-mcp-server@latest init-db
|
||||
npx -y ra-h-mcp-server@latest doctor
|
||||
npx -y ra-h-mcp-server@latest print-config --client claude-code
|
||||
```
|
||||
|
||||
`--yes` lets the installer write supported JSON client config automatically. Codex uses TOML config, so the installer prints the block to add.
|
||||
|
||||
Important contract:
|
||||
- pinned package version recommended
|
||||
- `@latest` is the default user-facing install path
|
||||
- exact versions are only for release/debug reproducibility
|
||||
- standalone MCP reads and writes node data directly
|
||||
- standalone MCP does not own chunking, embeddings, or live schema migration on an existing DB
|
||||
|
||||
## Configure Claude Code / Claude Desktop
|
||||
|
||||
Add to your Claude config (`~/.claude.json` or Claude Desktop settings):
|
||||
Prefer the setup command above. Manual config is still available for troubleshooting:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"ra-h": {
|
||||
"command": "npx",
|
||||
"args": ["--yes", "ra-h-mcp-server@2.1.2"]
|
||||
"args": ["-y", "ra-h-mcp-server@latest"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Restart Claude fully. Done.
|
||||
|
||||
If you publish a newer MCP release and need this client to pick it up immediately, bump the pinned version here and restart Claude. Do not assume plain `npx ra-h-mcp-server` always refreshes instantly.
|
||||
Restart Claude fully. If you need to freeze behavior for debugging, pin an exact version intentionally and restart the client.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Node.js 18-22 LTS recommended
|
||||
- an existing RA-H database at `~/Library/Application Support/RA-H/db/rah.sqlite`
|
||||
- run the RA-H app at least once before using the standalone MCP server
|
||||
- a RA-H database at `~/Library/Application Support/RA-H/db/rah.sqlite`, created by `setup`, `init-db`, or the app
|
||||
|
||||
## Environment Variables
|
||||
|
||||
@@ -46,6 +56,15 @@ If you publish a newer MCP release and need this client to pick it up immediatel
|
||||
|----------|---------|-------------|
|
||||
| `RAH_DB_PATH` | `~/Library/Application Support/RA-H/db/rah.sqlite` | Database path |
|
||||
|
||||
For demos or isolated installs:
|
||||
|
||||
```bash
|
||||
npx -y ra-h-mcp-server@latest setup \
|
||||
--client claude-code \
|
||||
--yes \
|
||||
--db "$HOME/Desktop/ra-h_os-demo-data/rah.sqlite"
|
||||
```
|
||||
|
||||
## What To Expect
|
||||
|
||||
Once connected, the agent should:
|
||||
@@ -98,6 +117,7 @@ Do not create contradictory instruction files. Prefer one short reinforcement li
|
||||
|
||||
Verification tip:
|
||||
- after config changes, fully restart the client and confirm you can see tools like `queryNodes`, `retrieveQueryContext`, and `createNode`
|
||||
- run `npx -y ra-h-mcp-server@latest doctor` to verify package version, DB path, schema health, and node count
|
||||
|
||||
## Node Metadata Contract
|
||||
|
||||
@@ -152,6 +172,10 @@ This is a lightweight CRUD server. Advanced features are handled by the main app
|
||||
# Test database connection
|
||||
node -e "const {initDatabase,query}=require('./services/sqlite-client');initDatabase();console.log(query('SELECT COUNT(*) as c FROM nodes')[0].c,'nodes')"
|
||||
|
||||
# Test CLI setup path
|
||||
node index.js init-db --db /tmp/rah-test.sqlite
|
||||
node index.js doctor --db /tmp/rah-test.sqlite
|
||||
|
||||
# Run the server
|
||||
node index.js
|
||||
```
|
||||
|
||||
@@ -0,0 +1,446 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
|
||||
const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
const { spawnSync } = require('node:child_process');
|
||||
const Database = require('better-sqlite3');
|
||||
const packageJson = require('./package.json');
|
||||
const { getDatabasePath } = require('./services/sqlite-client');
|
||||
|
||||
const SUPPORTED_CLIENTS = new Set([
|
||||
'claude-code',
|
||||
'claude-desktop',
|
||||
'cursor',
|
||||
'codex',
|
||||
'opencode',
|
||||
'vscode',
|
||||
'windsurf',
|
||||
'aider',
|
||||
]);
|
||||
|
||||
function log(message) {
|
||||
console.log(`[ra-h-mcp-server] ${message}`);
|
||||
}
|
||||
|
||||
function fail(message) {
|
||||
console.error(`[ra-h-mcp-server] ERROR: ${message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function usage() {
|
||||
console.log(`RA-H MCP Server ${packageJson.version}
|
||||
|
||||
Usage:
|
||||
ra-h-mcp-server Start MCP stdio server
|
||||
ra-h-mcp-server setup --client <name> Configure MCP for an agent
|
||||
ra-h-mcp-server doctor Verify package, DB, and schema
|
||||
ra-h-mcp-server init-db Create/verify the RA-H SQLite DB
|
||||
ra-h-mcp-server print-config --client <name>
|
||||
ra-h-mcp-server install-rules --client <name> [--target <path>]
|
||||
|
||||
Options:
|
||||
--client <name> claude-code, claude-desktop, cursor, codex, opencode, vscode, windsurf, aider
|
||||
--db <path> Override DB path for this command
|
||||
--scope <scope> user or project (default: user)
|
||||
--pin current Use this package version instead of @latest in generated config
|
||||
--yes Write supported config files without prompting
|
||||
--print-only Print config/rules without writing files
|
||||
--target <path> Directory for project rule files
|
||||
`);
|
||||
}
|
||||
|
||||
function parseArgs(argv) {
|
||||
const args = {
|
||||
_: [],
|
||||
client: null,
|
||||
db: null,
|
||||
scope: 'user',
|
||||
pin: null,
|
||||
yes: false,
|
||||
printOnly: false,
|
||||
target: null,
|
||||
};
|
||||
|
||||
for (let i = 0; i < argv.length; i += 1) {
|
||||
const arg = argv[i];
|
||||
if (arg === '--help' || arg === '-h') {
|
||||
args.help = true;
|
||||
} else if (arg === '--yes' || arg === '-y') {
|
||||
args.yes = true;
|
||||
} else if (arg === '--print-only' || arg === '--dry-run') {
|
||||
args.printOnly = true;
|
||||
} else if (['--client', '--db', '--scope', '--pin', '--target'].includes(arg)) {
|
||||
const value = argv[i + 1];
|
||||
if (!value || value.startsWith('--')) fail(`${arg} requires a value`);
|
||||
args[arg.slice(2)] = value;
|
||||
i += 1;
|
||||
} else {
|
||||
args._.push(arg);
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
function expandPath(rawPath) {
|
||||
if (!rawPath) return rawPath;
|
||||
let expanded = rawPath;
|
||||
if (expanded.startsWith('~')) {
|
||||
expanded = path.join(os.homedir(), expanded.slice(1));
|
||||
}
|
||||
expanded = expanded.replace(/\$HOME/g, os.homedir());
|
||||
return path.resolve(expanded);
|
||||
}
|
||||
|
||||
function defaultDbPath() {
|
||||
return getDatabasePath();
|
||||
}
|
||||
|
||||
function resolveDbPath(args) {
|
||||
return expandPath(args.db || process.env.RAH_DB_PATH || process.env.SQLITE_DB_PATH || defaultDbPath());
|
||||
}
|
||||
|
||||
function ensureMinimumSchema(db) {
|
||||
db.pragma('foreign_keys = ON');
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS nodes (
|
||||
id INTEGER PRIMARY KEY,
|
||||
title TEXT,
|
||||
description TEXT,
|
||||
source TEXT,
|
||||
link TEXT,
|
||||
event_date TEXT,
|
||||
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
||||
metadata TEXT,
|
||||
embedding BLOB,
|
||||
embedding_updated_at TEXT,
|
||||
embedding_text TEXT,
|
||||
chunk_status TEXT DEFAULT 'not_chunked'
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS chunks (
|
||||
id INTEGER PRIMARY KEY,
|
||||
node_id INTEGER NOT NULL,
|
||||
chunk_idx INTEGER,
|
||||
text TEXT,
|
||||
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
||||
embedding_type TEXT DEFAULT 'text-embedding-3-small',
|
||||
metadata TEXT,
|
||||
FOREIGN KEY (node_id) REFERENCES nodes(id) ON DELETE CASCADE
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_chunks_by_node ON chunks(node_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_chunks_by_node_idx ON chunks(node_id, chunk_idx);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS edges (
|
||||
id INTEGER PRIMARY KEY,
|
||||
from_node_id INTEGER NOT NULL,
|
||||
to_node_id INTEGER NOT NULL,
|
||||
source TEXT,
|
||||
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
||||
context TEXT,
|
||||
explanation TEXT,
|
||||
FOREIGN KEY (from_node_id) REFERENCES nodes(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (to_node_id) REFERENCES nodes(id) ON DELETE CASCADE
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_edges_from ON edges(from_node_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_edges_to ON edges(to_node_id);
|
||||
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS nodes_fts USING fts5(
|
||||
title,
|
||||
source,
|
||||
description,
|
||||
content='nodes',
|
||||
content_rowid='id'
|
||||
);
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS chunks_fts USING fts5(
|
||||
text,
|
||||
content='chunks',
|
||||
content_rowid='id'
|
||||
);
|
||||
`);
|
||||
}
|
||||
|
||||
function initDb(dbPath) {
|
||||
fs.mkdirSync(path.dirname(dbPath), { recursive: true });
|
||||
const db = new Database(dbPath);
|
||||
try {
|
||||
ensureMinimumSchema(db);
|
||||
const quickCheck = db.prepare('PRAGMA quick_check').get();
|
||||
return quickCheck.quick_check || Object.values(quickCheck)[0];
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
|
||||
function inspectDb(dbPath) {
|
||||
if (!fs.existsSync(dbPath)) {
|
||||
return { exists: false, ok: false, missing: ['database file'] };
|
||||
}
|
||||
|
||||
const db = new Database(dbPath, { readonly: true, fileMustExist: true });
|
||||
try {
|
||||
const requiredTables = ['nodes', 'edges', 'chunks'];
|
||||
const missing = requiredTables.filter(
|
||||
(table) => !db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name = ?").get(table)
|
||||
);
|
||||
const quickCheck = db.prepare('PRAGMA quick_check').get();
|
||||
const nodeCount = missing.includes('nodes')
|
||||
? null
|
||||
: db.prepare('SELECT COUNT(*) as count FROM nodes').get().count;
|
||||
|
||||
return {
|
||||
exists: true,
|
||||
ok: missing.length === 0,
|
||||
missing,
|
||||
quickCheck: quickCheck.quick_check || Object.values(quickCheck)[0],
|
||||
nodeCount,
|
||||
};
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
|
||||
function packageSpec(args) {
|
||||
return args.pin === 'current'
|
||||
? `ra-h-mcp-server@${packageJson.version}`
|
||||
: 'ra-h-mcp-server@latest';
|
||||
}
|
||||
|
||||
function mcpServerJson(args, dbPath) {
|
||||
return {
|
||||
command: 'npx',
|
||||
args: ['-y', packageSpec(args)],
|
||||
env: {
|
||||
RAH_DB_PATH: dbPath,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function clientConfig(client, args, dbPath) {
|
||||
const server = mcpServerJson(args, dbPath);
|
||||
|
||||
if (client === 'claude-code') {
|
||||
return {
|
||||
type: 'json-merge',
|
||||
path: path.join(os.homedir(), '.claude.json'),
|
||||
snippet: { mcpServers: { 'ra-h': server } },
|
||||
writable: true,
|
||||
};
|
||||
}
|
||||
|
||||
if (client === 'claude-desktop') {
|
||||
return {
|
||||
type: 'json-merge',
|
||||
path: path.join(os.homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'),
|
||||
snippet: { mcpServers: { 'ra-h': server } },
|
||||
writable: process.platform === 'darwin',
|
||||
};
|
||||
}
|
||||
|
||||
if (client === 'cursor') {
|
||||
return {
|
||||
type: 'json-merge',
|
||||
path: path.join(os.homedir(), '.cursor', 'mcp.json'),
|
||||
snippet: { mcpServers: { 'ra-h': server } },
|
||||
writable: true,
|
||||
};
|
||||
}
|
||||
|
||||
if (client === 'vscode') {
|
||||
return {
|
||||
type: 'json-merge',
|
||||
path: path.join(process.cwd(), '.vscode', 'mcp.json'),
|
||||
snippet: { servers: { 'ra-h': server } },
|
||||
writable: args.scope === 'project',
|
||||
note: 'VS Code MCP config is project-local here; pass --scope project --yes to write it.',
|
||||
};
|
||||
}
|
||||
|
||||
if (client === 'codex') {
|
||||
return {
|
||||
type: 'toml',
|
||||
path: path.join(os.homedir(), '.codex', 'config.toml'),
|
||||
snippet: `[mcp_servers.ra-h]\ncommand = "npx"\nargs = ["-y", "${packageSpec(args)}"]\n\n[mcp_servers.ra-h.env]\nRAH_DB_PATH = "${dbPath.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"\n`,
|
||||
writable: false,
|
||||
note: 'Codex config is TOML; this installer prints the block instead of mutating existing config.',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'json',
|
||||
path: null,
|
||||
snippet: { mcpServers: { 'ra-h': server } },
|
||||
writable: false,
|
||||
note: `${client} config writing is not automated yet. Copy this MCP block into that client's MCP settings.`,
|
||||
};
|
||||
}
|
||||
|
||||
function readJson(filePath) {
|
||||
if (!fs.existsSync(filePath)) return {};
|
||||
const raw = fs.readFileSync(filePath, 'utf8').trim();
|
||||
if (!raw) return {};
|
||||
return JSON.parse(raw);
|
||||
}
|
||||
|
||||
function writeJsonMerge(config) {
|
||||
const current = readJson(config.path);
|
||||
const next = {
|
||||
...current,
|
||||
mcpServers: {
|
||||
...(current.mcpServers || {}),
|
||||
...(config.snippet.mcpServers || {}),
|
||||
},
|
||||
};
|
||||
|
||||
if (config.snippet.servers) {
|
||||
next.servers = {
|
||||
...(current.servers || {}),
|
||||
...config.snippet.servers,
|
||||
};
|
||||
}
|
||||
|
||||
fs.mkdirSync(path.dirname(config.path), { recursive: true });
|
||||
fs.writeFileSync(config.path, `${JSON.stringify(next, null, 2)}\n`);
|
||||
}
|
||||
|
||||
function formatSnippet(snippet) {
|
||||
return typeof snippet === 'string' ? snippet : JSON.stringify(snippet, null, 2);
|
||||
}
|
||||
|
||||
function validateClient(client) {
|
||||
if (!client) fail('Missing --client');
|
||||
if (!SUPPORTED_CLIENTS.has(client)) {
|
||||
fail(`Unsupported client "${client}". Supported: ${Array.from(SUPPORTED_CLIENTS).join(', ')}`);
|
||||
}
|
||||
}
|
||||
|
||||
function rulesSnippet() {
|
||||
return `You are helping build a thoughtful graph of atomic units of context.
|
||||
|
||||
- Before substantive work that touches the user's projects, ideas, people, decisions, or prior context, retrieve relevant graph context from RA-H.
|
||||
- Use queryNodes for direct lookup of a specific existing node.
|
||||
- Use retrieveQueryContext for broader grounding before answering.
|
||||
- Search before creating. Prefer updating the same artifact when it is clearly the same thing.
|
||||
- When the user states a durable decision, preference, project fact, or useful idea, surface one concise candidate node for confirmation.
|
||||
- Do not pester. Ask at most once per turn, and drop it if the user moves on.
|
||||
- Preserve the user's wording in source for user-authored ideas unless they explicitly want a rewrite.
|
||||
`;
|
||||
}
|
||||
|
||||
function rulesTarget(client, target) {
|
||||
const base = expandPath(target || process.cwd());
|
||||
if (client === 'cursor') return path.join(base, '.cursor', 'rules', 'ra-h.mdc');
|
||||
if (client === 'aider') return path.join(base, 'CONVENTIONS.md');
|
||||
if (client === 'claude-code' || client === 'claude-desktop') return path.join(base, 'CLAUDE.md');
|
||||
return path.join(base, 'AGENTS.md');
|
||||
}
|
||||
|
||||
function commandInitDb(args) {
|
||||
const dbPath = resolveDbPath(args);
|
||||
const quickCheck = initDb(dbPath);
|
||||
log(`Database ready at ${dbPath}`);
|
||||
log(`SQLite quick_check: ${quickCheck}`);
|
||||
}
|
||||
|
||||
function commandDoctor(args) {
|
||||
const dbPath = resolveDbPath(args);
|
||||
const report = inspectDb(dbPath);
|
||||
let latest = null;
|
||||
const npmResult = spawnSync('npm', ['view', 'ra-h-mcp-server', 'version'], {
|
||||
encoding: 'utf8',
|
||||
timeout: 5000,
|
||||
});
|
||||
if (npmResult.status === 0) latest = npmResult.stdout.trim();
|
||||
|
||||
log(`Package version: ${packageJson.version}`);
|
||||
if (latest) log(`npm latest: ${latest}`);
|
||||
log(`DB path: ${dbPath}`);
|
||||
|
||||
if (!report.exists) fail(`Database does not exist at ${dbPath}. Run init-db or setup first.`);
|
||||
if (!report.ok) fail(`Database schema missing: ${report.missing.join(', ')}`);
|
||||
|
||||
log(`SQLite quick_check: ${report.quickCheck}`);
|
||||
log(`Node count: ${report.nodeCount}`);
|
||||
log('Doctor passed.');
|
||||
}
|
||||
|
||||
function commandPrintConfig(args) {
|
||||
validateClient(args.client);
|
||||
const dbPath = resolveDbPath(args);
|
||||
const config = clientConfig(args.client, args, dbPath);
|
||||
console.log(formatSnippet(config.snippet));
|
||||
if (config.note) log(config.note);
|
||||
if (config.path) log(`Target path: ${config.path}`);
|
||||
}
|
||||
|
||||
function commandInstallRules(args) {
|
||||
validateClient(args.client);
|
||||
const content = rulesSnippet();
|
||||
const targetPath = rulesTarget(args.client, args.target);
|
||||
|
||||
if (args.printOnly || !args.yes) {
|
||||
console.log(content);
|
||||
log(`Rule file target: ${targetPath}`);
|
||||
log('Pass --yes to write it.');
|
||||
return;
|
||||
}
|
||||
|
||||
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
||||
fs.writeFileSync(targetPath, content);
|
||||
log(`Wrote rules to ${targetPath}`);
|
||||
}
|
||||
|
||||
function commandSetup(args) {
|
||||
validateClient(args.client);
|
||||
const dbPath = resolveDbPath(args);
|
||||
initDb(dbPath);
|
||||
log(`Database ready at ${dbPath}`);
|
||||
|
||||
const config = clientConfig(args.client, args, dbPath);
|
||||
console.log(formatSnippet(config.snippet));
|
||||
if (config.path) log(`MCP config target: ${config.path}`);
|
||||
if (config.note) log(config.note);
|
||||
|
||||
const canWrite = config.writable && config.type === 'json-merge' && config.path;
|
||||
if (canWrite && args.yes && !args.printOnly) {
|
||||
writeJsonMerge(config);
|
||||
log(`Updated ${config.path}`);
|
||||
} else if (canWrite) {
|
||||
log('Pass --yes to write this config automatically.');
|
||||
} else {
|
||||
log('Automatic config writing is not available for this client; copy the printed config.');
|
||||
}
|
||||
|
||||
const rulePath = rulesTarget(args.client, args.target);
|
||||
log(`Recommended rules target: ${rulePath}`);
|
||||
log(`Install rules with: npx -y ${packageSpec(args)} install-rules --client ${args.client} --target <repo> --yes`);
|
||||
commandDoctor(args);
|
||||
}
|
||||
|
||||
function runCli(argv) {
|
||||
const [command, ...rest] = argv;
|
||||
const args = parseArgs(rest);
|
||||
|
||||
if (!command || command === '--help' || command === '-h' || args.help) {
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
|
||||
if (command === 'setup') return commandSetup(args);
|
||||
if (command === 'doctor') return commandDoctor(args);
|
||||
if (command === 'init-db') return commandInitDb(args);
|
||||
if (command === 'print-config') return commandPrintConfig(args);
|
||||
if (command === 'install-rules') return commandInstallRules(args);
|
||||
|
||||
fail(`Unknown command "${command}"`);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
runCli,
|
||||
initDb,
|
||||
inspectDb,
|
||||
rulesSnippet,
|
||||
};
|
||||
@@ -36,6 +36,13 @@ const skillService = require('./services/skillService');
|
||||
const retrievalService = require('./services/retrievalService');
|
||||
const { directNodeLookup } = require('./services/directNodeLookupService');
|
||||
|
||||
const cliCommands = new Set(['setup', 'doctor', 'init-db', 'print-config', 'install-rules', '--help', '-h']);
|
||||
if (cliCommands.has(process.argv[2])) {
|
||||
const { runCli } = require('./cli');
|
||||
runCli(process.argv.slice(2));
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Server info
|
||||
const serverInfo = {
|
||||
name: 'ra-h-standalone',
|
||||
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "ra-h-mcp-server",
|
||||
"version": "2.1.2",
|
||||
"version": "3.2.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ra-h-mcp-server",
|
||||
"version": "2.1.2",
|
||||
"version": "3.2.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/sdk": "^1.0.0",
|
||||
@@ -17,7 +17,7 @@
|
||||
"ra-h-mcp-server": "index.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
"node": ">=18.0.0 <24.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@hono/node-server": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ra-h-mcp-server",
|
||||
"version": "2.1.2",
|
||||
"version": "3.2.0",
|
||||
"description": "Connect Claude Code/Desktop to your RA-H knowledge base. Direct SQLite access to an existing RA-H database.",
|
||||
"main": "index.js",
|
||||
"bin": {
|
||||
@@ -8,7 +8,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"validate:syntax": "node --check index.js && node --check services/*.js",
|
||||
"validate:syntax": "node --check index.js && node --check cli.js && node --check services/*.js",
|
||||
"validate:publish": "npm run validate:syntax && npm pack --dry-run >/dev/null",
|
||||
"prepublishOnly": "node ../../scripts/dev/sync-skills.mjs --check && npm run validate:publish"
|
||||
},
|
||||
@@ -29,11 +29,11 @@
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/bradwmorris/ra-h.git"
|
||||
"url": "git+https://github.com/bradwmorris/ra-h_os.git"
|
||||
},
|
||||
"homepage": "https://ra-h.app",
|
||||
"bugs": {
|
||||
"url": "https://github.com/bradwmorris/ra-h/issues"
|
||||
"url": "https://github.com/bradwmorris/ra-h_os/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/sdk": "^1.0.0",
|
||||
@@ -45,6 +45,7 @@
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"cli.js",
|
||||
"services/",
|
||||
"skills/",
|
||||
"README.md"
|
||||
|
||||
Reference in New Issue
Block a user