@ruvector/rvf-mcp-server 0.1.6 → 0.2.1
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 +3 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +23 -12
- package/dist/cli.js.map +1 -1
- package/dist/server.d.ts +27 -1
- package/dist/server.js +242 -279
- package/dist/server.js.map +1 -1
- package/dist/stores.d.ts +46 -0
- package/dist/stores.js +196 -0
- package/dist/stores.js.map +1 -0
- package/package.json +2 -1
- package/src/cli.ts +23 -14
- package/src/server.ts +265 -305
- package/src/stores.ts +192 -0
package/README.md
CHANGED
|
@@ -37,7 +37,9 @@ npx @ruvector/rvf-mcp-server --transport sse --port 3100
|
|
|
37
37
|
|
|
38
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).
|
|
39
39
|
|
|
40
|
-
|
|
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.
|
|
41
43
|
|
|
42
44
|
## MCP Tools
|
|
43
45
|
|
package/dist/cli.d.ts
CHANGED
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
|
-
//
|
|
94
|
-
|
|
95
|
-
console.error(
|
|
96
|
-
process.exit(0);
|
|
97
|
-
}
|
|
98
|
-
process.on('
|
|
99
|
-
|
|
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
|
|
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>;
|