@ruvector/rvf-mcp-server 0.1.5 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ <p align="center"><img src="https://raw.githubusercontent.com/ruvnet/RuVector/main/assets/ruvector/packages/rvf-mcp-server.svg" alt="@ruvector/rvf-mcp-server: MCP server for RuVector Format vector stores — stdio and SSE transports for AI agents." width="100%"></p>
2
+
1
3
  # @ruvector/rvf-mcp-server
2
4
 
3
5
  MCP (Model Context Protocol) server for RuVector Format (RVF) vector stores. Exposes RVF capabilities to AI agents like Claude Code, Cursor, and other MCP-compatible tools.
@@ -35,7 +37,9 @@ npx @ruvector/rvf-mcp-server --transport sse --port 3100
35
37
 
36
38
  The SSE transport binds `127.0.0.1` by default and serves one session at a time. It has no authentication; use `--host <address>` to bind elsewhere only behind your own auth proxy. Point clients at `http://127.0.0.1:3100/sse` (on dual-stack hosts `localhost` may resolve to `::1`; use `--host ::1` if your client needs it).
37
39
 
38
- > **Note:** stores are held in memory for the lifetime of the server process. The `path` argument is recorded as a label only; nothing is read from or written to disk.
40
+ ## Storage
41
+
42
+ Stores are real `.rvf` files written through [`@ruvector/rvf`](https://www.npmjs.com/package/@ruvector/rvf), so they survive server restarts and queries go through the native HNSW index instead of a linear scan. Every tool `path` is resolved inside the data directory: `--data-dir <dir>`, else `$RVF_MCP_DATA_DIR`, else `~/.rvf-mcp-server`. Absolute paths, `..` segments and symlinks that lead outside it are rejected. Per-vector metadata, which the native store does not hold, lives next to each store in `<store>.mcp-meta.jsonl`. Metadata filters are applied to an over-fetched index result.
39
43
 
40
44
  ## MCP Tools
41
45
 
package/dist/cli.d.ts CHANGED
@@ -7,5 +7,6 @@
7
7
  * rvf-mcp-server --transport stdio # stdio explicitly
8
8
  * rvf-mcp-server --transport sse # SSE on port 3100
9
9
  * rvf-mcp-server --transport sse --port 8080
10
+ * rvf-mcp-server --data-dir ./stores # where .rvf stores live
10
11
  */
11
12
  export {};
package/dist/cli.js CHANGED
@@ -7,6 +7,7 @@
7
7
  * rvf-mcp-server --transport stdio # stdio explicitly
8
8
  * rvf-mcp-server --transport sse # SSE on port 3100
9
9
  * rvf-mcp-server --transport sse --port 8080
10
+ * rvf-mcp-server --data-dir ./stores # where .rvf stores live
10
11
  */
11
12
  import { createRequire } from 'node:module';
12
13
  import { createServer } from './transports.js';
@@ -16,6 +17,7 @@ function parseArgs() {
16
17
  let transport = 'stdio';
17
18
  let port = 3100;
18
19
  let host;
20
+ let dataDir;
19
21
  for (let i = 0; i < args.length; i++) {
20
22
  if (args[i] === '--transport' || args[i] === '-t') {
21
23
  const val = args[++i];
@@ -41,6 +43,13 @@ function parseArgs() {
41
43
  process.exit(1);
42
44
  }
43
45
  }
46
+ else if (args[i] === '--data-dir' || args[i] === '-d') {
47
+ dataDir = args[++i];
48
+ if (!dataDir) {
49
+ console.error('--data-dir requires a directory');
50
+ process.exit(1);
51
+ }
52
+ }
44
53
  else if (args[i] === '--help' || args[i] === '-h') {
45
54
  console.log(`
46
55
  RVF MCP Server — Model Context Protocol server for RuVector Format
@@ -54,6 +63,10 @@ Options:
54
63
  -H, --host <address> SSE bind address (default: 127.0.0.1; the SSE
55
64
  endpoint is unauthenticated, so only bind a
56
65
  public address behind your own auth proxy)
66
+ -d, --data-dir <dir> Directory holding the .rvf stores (default:
67
+ $RVF_MCP_DATA_DIR, else ~/.rvf-mcp-server).
68
+ Tool paths are resolved inside it and may
69
+ not escape it.
57
70
  -h, --help Show this help message
58
71
 
59
72
  MCP Tools:
@@ -81,24 +94,22 @@ stdio config (.mcp.json):
81
94
  process.exit(0);
82
95
  }
83
96
  }
84
- return { transport, port, host };
97
+ return { transport, port, host, dataDir };
85
98
  }
86
99
  async function main() {
87
- const { transport, port, host } = parseArgs();
100
+ const { transport, port, host, dataDir } = parseArgs();
88
101
  if (transport === 'stdio') {
89
102
  // Suppress stdout logging in stdio mode (MCP uses stdout)
90
103
  console.error('RVF MCP Server starting (stdio transport)...');
91
104
  }
92
- await createServer(transport, port, { version }, { host });
93
- // Keep process alive
94
- process.on('SIGINT', () => {
95
- console.error('\nRVF MCP Server shutting down...');
96
- process.exit(0);
97
- });
98
- process.on('SIGTERM', () => {
99
- console.error('RVF MCP Server terminated.');
100
- process.exit(0);
101
- });
105
+ const server = await createServer(transport, port, { version, ...(dataDir ? { dataDir } : {}) }, { host });
106
+ // Close stores (flushes id maps and metadata, releases locks) on shutdown.
107
+ const shutdown = (message) => {
108
+ console.error(message);
109
+ server.close().catch((err) => console.error('Close failed:', err)).finally(() => process.exit(0));
110
+ };
111
+ process.on('SIGINT', () => shutdown('\nRVF MCP Server shutting down...'));
112
+ process.on('SIGTERM', () => shutdown('RVF MCP Server terminated.'));
102
113
  }
103
114
  main().catch((err) => {
104
115
  console.error('Fatal:', err);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAwB,CAAC;AAE7F,SAAS,SAAS;IAChB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,SAAS,GAAoB,OAAO,CAAC;IACzC,IAAI,IAAI,GAAG,IAAI,CAAC;IAChB,IAAI,IAAwB,CAAC;IAE7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAClD,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACtB,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;gBACrC,SAAS,GAAG,GAAG,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,sBAAsB,GAAG,yBAAyB,CAAC,CAAC;gBAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACpD,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC/B,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;gBAC5C,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;gBAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACpD,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACjB,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;gBAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACpD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCjB,CAAC,CAAC;YACG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACnC,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,SAAS,EAAE,CAAC;IAE9C,IAAI,SAAS,KAAK,OAAO,EAAE,CAAC;QAC1B,0DAA0D;QAC1D,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,YAAY,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3D,qBAAqB;IACrB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QACzB,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  /**
2
2
  * RVF MCP Server — core server implementation.
3
3
  *
4
- * Registers all RVF tools, resources, and prompts with the MCP SDK.
4
+ * Registers all RVF tools, resources, and prompts with the MCP SDK. Stores
5
+ * are real on-disk `.rvf` files (via @ruvector/rvf) confined to a data dir,
6
+ * so queries are index-backed and data survives server restarts.
5
7
  */
6
8
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
7
9
  export interface RvfMcpServerOptions {
@@ -13,6 +15,17 @@ export interface RvfMcpServerOptions {
13
15
  defaultDimensions?: number;
14
16
  /** Maximum open stores. Default: 64. */
15
17
  maxStores?: number;
18
+ /**
19
+ * Directory that holds every store. Tool `path` arguments are resolved
20
+ * inside it and may not escape it. Default: $RVF_MCP_DATA_DIR, else
21
+ * ~/.rvf-mcp-server.
22
+ */
23
+ dataDir?: string;
24
+ /** Auto-compaction thresholds after ingest. Default: {@link AUTO_COMPACT}. */
25
+ autoCompact?: {
26
+ minBytes: number;
27
+ ratio: number;
28
+ };
16
29
  }
17
30
  /** Upper bounds on model-supplied sizes (tool arguments are untrusted). */
18
31
  export declare const LIMITS: {
@@ -20,13 +33,26 @@ export declare const LIMITS: {
20
33
  readonly maxK: 10000;
21
34
  readonly maxBatch: 10000;
22
35
  };
36
+ /** Auto-compaction after ingest: file larger than `minBytes` AND `ratio` x live vector bytes. */
37
+ export declare const AUTO_COMPACT: {
38
+ readonly minBytes: number;
39
+ readonly ratio: 8;
40
+ };
23
41
  export declare class RvfMcpServer {
24
42
  readonly mcp: McpServer;
25
43
  private stores;
26
44
  private nextId;
27
45
  private opts;
28
46
  constructor(options?: RvfMcpServerOptions);
47
+ /** Directory that holds this server's stores. */
48
+ get dataDir(): string;
49
+ private withStore;
50
+ private register;
51
+ /** k-NN with exact-match metadata filtering applied to an over-fetched result. */
52
+ private search;
29
53
  private registerTools;
54
+ private listStores;
55
+ private closeHandle;
30
56
  private registerResources;
31
57
  private registerPrompts;
32
58
  connect(transport: Parameters<McpServer['connect']>[0]): Promise<void>;