@ruvector/rvf-mcp-server 0.1.2 → 0.1.4
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/.claude-flow/.trend-cache.json +1 -1
- package/.claude-flow/data/pending-insights.jsonl +1 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.js +94 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +29 -0
- package/dist/server.js +431 -0
- package/dist/server.js.map +1 -0
- package/dist/transports.d.ts +34 -0
- package/dist/transports.js +82 -0
- package/dist/transports.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"intelligence":50,"timestamp":
|
|
1
|
+
{"intelligence":50,"timestamp":1771137103350}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* RVF MCP Server CLI — start the server in stdio or SSE mode.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* rvf-mcp-server # stdio (default)
|
|
7
|
+
* rvf-mcp-server --transport stdio # stdio explicitly
|
|
8
|
+
* rvf-mcp-server --transport sse # SSE on port 3100
|
|
9
|
+
* rvf-mcp-server --transport sse --port 8080
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* RVF MCP Server CLI — start the server in stdio or SSE mode.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* rvf-mcp-server # stdio (default)
|
|
7
|
+
* rvf-mcp-server --transport stdio # stdio explicitly
|
|
8
|
+
* rvf-mcp-server --transport sse # SSE on port 3100
|
|
9
|
+
* rvf-mcp-server --transport sse --port 8080
|
|
10
|
+
*/
|
|
11
|
+
import { createServer } from './transports.js';
|
|
12
|
+
function parseArgs() {
|
|
13
|
+
const args = process.argv.slice(2);
|
|
14
|
+
let transport = 'stdio';
|
|
15
|
+
let port = 3100;
|
|
16
|
+
for (let i = 0; i < args.length; i++) {
|
|
17
|
+
if (args[i] === '--transport' || args[i] === '-t') {
|
|
18
|
+
const val = args[++i];
|
|
19
|
+
if (val === 'sse' || val === 'stdio') {
|
|
20
|
+
transport = val;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
console.error(`Unknown transport: ${val}. Use 'stdio' or 'sse'.`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
else if (args[i] === '--port' || args[i] === '-p') {
|
|
28
|
+
port = parseInt(args[++i], 10);
|
|
29
|
+
if (isNaN(port) || port < 1 || port > 65535) {
|
|
30
|
+
console.error('Port must be between 1 and 65535');
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else if (args[i] === '--help' || args[i] === '-h') {
|
|
35
|
+
console.log(`
|
|
36
|
+
RVF MCP Server — Model Context Protocol server for RuVector Format
|
|
37
|
+
|
|
38
|
+
Usage:
|
|
39
|
+
rvf-mcp-server [options]
|
|
40
|
+
|
|
41
|
+
Options:
|
|
42
|
+
-t, --transport <stdio|sse> Transport mode (default: stdio)
|
|
43
|
+
-p, --port <number> SSE port (default: 3100)
|
|
44
|
+
-h, --help Show this help message
|
|
45
|
+
|
|
46
|
+
MCP Tools:
|
|
47
|
+
rvf_create_store Create a new vector store
|
|
48
|
+
rvf_open_store Open an existing store
|
|
49
|
+
rvf_close_store Close a store
|
|
50
|
+
rvf_ingest Insert vectors
|
|
51
|
+
rvf_query k-NN similarity search
|
|
52
|
+
rvf_delete Delete vectors by ID
|
|
53
|
+
rvf_delete_filter Delete by metadata filter
|
|
54
|
+
rvf_compact Reclaim dead space
|
|
55
|
+
rvf_status Store status
|
|
56
|
+
rvf_list_stores List open stores
|
|
57
|
+
|
|
58
|
+
stdio config (.mcp.json):
|
|
59
|
+
{
|
|
60
|
+
"mcpServers": {
|
|
61
|
+
"rvf": {
|
|
62
|
+
"command": "node",
|
|
63
|
+
"args": ["dist/cli.js"]
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
`);
|
|
68
|
+
process.exit(0);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return { transport, port };
|
|
72
|
+
}
|
|
73
|
+
async function main() {
|
|
74
|
+
const { transport, port } = parseArgs();
|
|
75
|
+
if (transport === 'stdio') {
|
|
76
|
+
// Suppress stdout logging in stdio mode (MCP uses stdout)
|
|
77
|
+
console.error('RVF MCP Server starting (stdio transport)...');
|
|
78
|
+
}
|
|
79
|
+
await createServer(transport, port);
|
|
80
|
+
// Keep process alive
|
|
81
|
+
process.on('SIGINT', () => {
|
|
82
|
+
console.error('\nRVF MCP Server shutting down...');
|
|
83
|
+
process.exit(0);
|
|
84
|
+
});
|
|
85
|
+
process.on('SIGTERM', () => {
|
|
86
|
+
console.error('RVF MCP Server terminated.');
|
|
87
|
+
process.exit(0);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
main().catch((err) => {
|
|
91
|
+
console.error('Fatal:', err);
|
|
92
|
+
process.exit(1);
|
|
93
|
+
});
|
|
94
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,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;IAEhB,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,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCjB,CAAC,CAAC;YACG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC7B,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,SAAS,EAAE,CAAC;IAExC,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,CAAC,CAAC;IAEpC,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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ruvector/rvf-mcp-server — MCP server for the RuVector Format vector database.
|
|
3
|
+
*
|
|
4
|
+
* Exposes RVF store operations as MCP tools and resources over stdio or SSE transports.
|
|
5
|
+
*
|
|
6
|
+
* Tools:
|
|
7
|
+
* - rvf_create_store Create a new RVF vector store
|
|
8
|
+
* - rvf_open_store Open an existing RVF store
|
|
9
|
+
* - rvf_close_store Close an open store
|
|
10
|
+
* - rvf_ingest Insert vectors into a store
|
|
11
|
+
* - rvf_query k-NN vector similarity search
|
|
12
|
+
* - rvf_delete Delete vectors by ID
|
|
13
|
+
* - rvf_delete_filter Delete vectors matching a filter
|
|
14
|
+
* - rvf_compact Compact store to reclaim dead space
|
|
15
|
+
* - rvf_status Get store status (vectors, segments, file size)
|
|
16
|
+
* - rvf_list_stores List all open stores
|
|
17
|
+
*
|
|
18
|
+
* Resources:
|
|
19
|
+
* - rvf://stores List of open stores
|
|
20
|
+
* - rvf://stores/{storeId}/status Status of a specific store
|
|
21
|
+
*/
|
|
22
|
+
export { RvfMcpServer, type RvfMcpServerOptions } from './server.js';
|
|
23
|
+
export { createStdioServer, createSseServer, createServer } from './transports.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ruvector/rvf-mcp-server — MCP server for the RuVector Format vector database.
|
|
3
|
+
*
|
|
4
|
+
* Exposes RVF store operations as MCP tools and resources over stdio or SSE transports.
|
|
5
|
+
*
|
|
6
|
+
* Tools:
|
|
7
|
+
* - rvf_create_store Create a new RVF vector store
|
|
8
|
+
* - rvf_open_store Open an existing RVF store
|
|
9
|
+
* - rvf_close_store Close an open store
|
|
10
|
+
* - rvf_ingest Insert vectors into a store
|
|
11
|
+
* - rvf_query k-NN vector similarity search
|
|
12
|
+
* - rvf_delete Delete vectors by ID
|
|
13
|
+
* - rvf_delete_filter Delete vectors matching a filter
|
|
14
|
+
* - rvf_compact Compact store to reclaim dead space
|
|
15
|
+
* - rvf_status Get store status (vectors, segments, file size)
|
|
16
|
+
* - rvf_list_stores List all open stores
|
|
17
|
+
*
|
|
18
|
+
* Resources:
|
|
19
|
+
* - rvf://stores List of open stores
|
|
20
|
+
* - rvf://stores/{storeId}/status Status of a specific store
|
|
21
|
+
*/
|
|
22
|
+
export { RvfMcpServer } from './server.js';
|
|
23
|
+
export { createStdioServer, createSseServer, createServer } from './transports.js';
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,YAAY,EAA4B,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RVF MCP Server — core server implementation.
|
|
3
|
+
*
|
|
4
|
+
* Registers all RVF tools, resources, and prompts with the MCP SDK.
|
|
5
|
+
*/
|
|
6
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
7
|
+
export interface RvfMcpServerOptions {
|
|
8
|
+
/** Server name shown to MCP clients. Default: 'rvf-mcp-server'. */
|
|
9
|
+
name?: string;
|
|
10
|
+
/** Server version. Default: '0.1.0'. */
|
|
11
|
+
version?: string;
|
|
12
|
+
/** Default vector dimensions for new stores. Default: 128. */
|
|
13
|
+
defaultDimensions?: number;
|
|
14
|
+
/** Maximum open stores. Default: 64. */
|
|
15
|
+
maxStores?: number;
|
|
16
|
+
}
|
|
17
|
+
export declare class RvfMcpServer {
|
|
18
|
+
readonly mcp: McpServer;
|
|
19
|
+
private stores;
|
|
20
|
+
private nextId;
|
|
21
|
+
private opts;
|
|
22
|
+
constructor(options?: RvfMcpServerOptions);
|
|
23
|
+
private registerTools;
|
|
24
|
+
private registerResources;
|
|
25
|
+
private registerPrompts;
|
|
26
|
+
connect(transport: Parameters<McpServer['connect']>[0]): Promise<void>;
|
|
27
|
+
close(): Promise<void>;
|
|
28
|
+
get storeCount(): number;
|
|
29
|
+
}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RVF MCP Server — core server implementation.
|
|
3
|
+
*
|
|
4
|
+
* Registers all RVF tools, resources, and prompts with the MCP SDK.
|
|
5
|
+
*/
|
|
6
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
// ─── Server ─────────────────────────────────────────────────────────────────
|
|
9
|
+
export class RvfMcpServer {
|
|
10
|
+
mcp;
|
|
11
|
+
stores = new Map();
|
|
12
|
+
nextId = 1;
|
|
13
|
+
opts;
|
|
14
|
+
constructor(options) {
|
|
15
|
+
this.opts = {
|
|
16
|
+
name: options?.name ?? 'rvf-mcp-server',
|
|
17
|
+
version: options?.version ?? '0.1.0',
|
|
18
|
+
defaultDimensions: options?.defaultDimensions ?? 128,
|
|
19
|
+
maxStores: options?.maxStores ?? 64,
|
|
20
|
+
};
|
|
21
|
+
this.mcp = new McpServer({ name: this.opts.name, version: this.opts.version }, {
|
|
22
|
+
capabilities: {
|
|
23
|
+
resources: {},
|
|
24
|
+
tools: {},
|
|
25
|
+
prompts: {},
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
this.registerTools();
|
|
29
|
+
this.registerResources();
|
|
30
|
+
this.registerPrompts();
|
|
31
|
+
}
|
|
32
|
+
// ─── Tool Registration ──────────────────────────────────────────────────
|
|
33
|
+
registerTools() {
|
|
34
|
+
// ── rvf_create_store ──────────────────────────────────────────────────
|
|
35
|
+
this.mcp.tool('rvf_create_store', 'Create a new RVF vector store at the given path', {
|
|
36
|
+
path: z.string().describe('File path for the new .rvf store'),
|
|
37
|
+
dimensions: z.number().int().positive().describe('Vector dimensionality'),
|
|
38
|
+
metric: z.enum(['l2', 'cosine', 'dotproduct']).default('l2').describe('Distance metric'),
|
|
39
|
+
}, async ({ path, dimensions, metric }) => {
|
|
40
|
+
if (this.stores.size >= this.opts.maxStores) {
|
|
41
|
+
return { content: [{ type: 'text', text: `Error: max stores (${this.opts.maxStores}) reached` }] };
|
|
42
|
+
}
|
|
43
|
+
const id = `store_${this.nextId++}`;
|
|
44
|
+
const handle = {
|
|
45
|
+
id,
|
|
46
|
+
path,
|
|
47
|
+
dimensions,
|
|
48
|
+
metric,
|
|
49
|
+
readOnly: false,
|
|
50
|
+
vectors: new Map(),
|
|
51
|
+
createdAt: Date.now(),
|
|
52
|
+
};
|
|
53
|
+
this.stores.set(id, handle);
|
|
54
|
+
return {
|
|
55
|
+
content: [{
|
|
56
|
+
type: 'text',
|
|
57
|
+
text: JSON.stringify({
|
|
58
|
+
storeId: id,
|
|
59
|
+
path,
|
|
60
|
+
dimensions,
|
|
61
|
+
metric,
|
|
62
|
+
status: 'created',
|
|
63
|
+
}, null, 2),
|
|
64
|
+
}],
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
// ── rvf_open_store ────────────────────────────────────────────────────
|
|
68
|
+
this.mcp.tool('rvf_open_store', 'Open an existing RVF store for reading and writing', {
|
|
69
|
+
path: z.string().describe('Path to existing .rvf file'),
|
|
70
|
+
readOnly: z.boolean().default(false).describe('Open in read-only mode'),
|
|
71
|
+
}, async ({ path, readOnly }) => {
|
|
72
|
+
if (this.stores.size >= this.opts.maxStores) {
|
|
73
|
+
return { content: [{ type: 'text', text: `Error: max stores (${this.opts.maxStores}) reached` }] };
|
|
74
|
+
}
|
|
75
|
+
const id = `store_${this.nextId++}`;
|
|
76
|
+
const handle = {
|
|
77
|
+
id,
|
|
78
|
+
path,
|
|
79
|
+
dimensions: this.opts.defaultDimensions,
|
|
80
|
+
metric: 'l2',
|
|
81
|
+
readOnly,
|
|
82
|
+
vectors: new Map(),
|
|
83
|
+
createdAt: Date.now(),
|
|
84
|
+
};
|
|
85
|
+
this.stores.set(id, handle);
|
|
86
|
+
return {
|
|
87
|
+
content: [{
|
|
88
|
+
type: 'text',
|
|
89
|
+
text: JSON.stringify({
|
|
90
|
+
storeId: id,
|
|
91
|
+
path,
|
|
92
|
+
readOnly,
|
|
93
|
+
status: 'opened',
|
|
94
|
+
}, null, 2),
|
|
95
|
+
}],
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
// ── rvf_close_store ───────────────────────────────────────────────────
|
|
99
|
+
this.mcp.tool('rvf_close_store', 'Close an open RVF store, releasing the writer lock', {
|
|
100
|
+
storeId: z.string().describe('Store ID returned by create/open'),
|
|
101
|
+
}, async ({ storeId }) => {
|
|
102
|
+
const handle = this.stores.get(storeId);
|
|
103
|
+
if (!handle) {
|
|
104
|
+
return { content: [{ type: 'text', text: `Error: store ${storeId} not found` }] };
|
|
105
|
+
}
|
|
106
|
+
this.stores.delete(storeId);
|
|
107
|
+
return {
|
|
108
|
+
content: [{
|
|
109
|
+
type: 'text',
|
|
110
|
+
text: JSON.stringify({ storeId, status: 'closed', path: handle.path }, null, 2),
|
|
111
|
+
}],
|
|
112
|
+
};
|
|
113
|
+
});
|
|
114
|
+
// ── rvf_ingest ────────────────────────────────────────────────────────
|
|
115
|
+
this.mcp.tool('rvf_ingest', 'Insert vectors into an RVF store', {
|
|
116
|
+
storeId: z.string().describe('Target store ID'),
|
|
117
|
+
entries: z.array(z.object({
|
|
118
|
+
id: z.string().describe('Unique vector ID'),
|
|
119
|
+
vector: z.array(z.number()).describe('Embedding vector (must match store dimensions)'),
|
|
120
|
+
metadata: z.record(z.union([z.string(), z.number(), z.boolean()])).optional()
|
|
121
|
+
.describe('Optional metadata key-value pairs'),
|
|
122
|
+
})).describe('Vectors to insert'),
|
|
123
|
+
}, async ({ storeId, entries }) => {
|
|
124
|
+
const handle = this.stores.get(storeId);
|
|
125
|
+
if (!handle) {
|
|
126
|
+
return { content: [{ type: 'text', text: `Error: store ${storeId} not found` }] };
|
|
127
|
+
}
|
|
128
|
+
if (handle.readOnly) {
|
|
129
|
+
return { content: [{ type: 'text', text: 'Error: store is read-only' }] };
|
|
130
|
+
}
|
|
131
|
+
let accepted = 0;
|
|
132
|
+
let rejected = 0;
|
|
133
|
+
for (const entry of entries) {
|
|
134
|
+
if (entry.vector.length !== handle.dimensions) {
|
|
135
|
+
rejected++;
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
handle.vectors.set(entry.id, {
|
|
139
|
+
vector: entry.vector,
|
|
140
|
+
metadata: entry.metadata,
|
|
141
|
+
});
|
|
142
|
+
accepted++;
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
content: [{
|
|
146
|
+
type: 'text',
|
|
147
|
+
text: JSON.stringify({
|
|
148
|
+
accepted,
|
|
149
|
+
rejected,
|
|
150
|
+
totalVectors: handle.vectors.size,
|
|
151
|
+
}, null, 2),
|
|
152
|
+
}],
|
|
153
|
+
};
|
|
154
|
+
});
|
|
155
|
+
// ── rvf_query ─────────────────────────────────────────────────────────
|
|
156
|
+
this.mcp.tool('rvf_query', 'k-NN vector similarity search', {
|
|
157
|
+
storeId: z.string().describe('Store ID to query'),
|
|
158
|
+
vector: z.array(z.number()).describe('Query embedding vector'),
|
|
159
|
+
k: z.number().int().positive().default(10).describe('Number of nearest neighbors'),
|
|
160
|
+
filter: z.record(z.union([z.string(), z.number(), z.boolean()])).optional()
|
|
161
|
+
.describe('Metadata filter (exact match on fields)'),
|
|
162
|
+
}, async ({ storeId, vector, k, filter }) => {
|
|
163
|
+
const handle = this.stores.get(storeId);
|
|
164
|
+
if (!handle) {
|
|
165
|
+
return { content: [{ type: 'text', text: `Error: store ${storeId} not found` }] };
|
|
166
|
+
}
|
|
167
|
+
if (vector.length !== handle.dimensions) {
|
|
168
|
+
return {
|
|
169
|
+
content: [{
|
|
170
|
+
type: 'text',
|
|
171
|
+
text: `Error: dimension mismatch (query=${vector.length}, store=${handle.dimensions})`,
|
|
172
|
+
}],
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
// Compute distances and sort
|
|
176
|
+
const results = [];
|
|
177
|
+
for (const [id, entry] of handle.vectors) {
|
|
178
|
+
// Apply metadata filter if provided
|
|
179
|
+
if (filter && entry.metadata) {
|
|
180
|
+
let match = true;
|
|
181
|
+
for (const [key, val] of Object.entries(filter)) {
|
|
182
|
+
if (entry.metadata[key] !== val) {
|
|
183
|
+
match = false;
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (!match)
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
else if (filter && !entry.metadata) {
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
const dist = computeDistance(vector, entry.vector, handle.metric);
|
|
194
|
+
results.push({ id, distance: dist });
|
|
195
|
+
}
|
|
196
|
+
results.sort((a, b) => a.distance - b.distance);
|
|
197
|
+
const topK = results.slice(0, k);
|
|
198
|
+
return {
|
|
199
|
+
content: [{
|
|
200
|
+
type: 'text',
|
|
201
|
+
text: JSON.stringify({
|
|
202
|
+
results: topK,
|
|
203
|
+
totalScanned: handle.vectors.size,
|
|
204
|
+
metric: handle.metric,
|
|
205
|
+
}, null, 2),
|
|
206
|
+
}],
|
|
207
|
+
};
|
|
208
|
+
});
|
|
209
|
+
// ── rvf_delete ────────────────────────────────────────────────────────
|
|
210
|
+
this.mcp.tool('rvf_delete', 'Delete vectors by their IDs', {
|
|
211
|
+
storeId: z.string().describe('Store ID'),
|
|
212
|
+
ids: z.array(z.string()).describe('Vector IDs to delete'),
|
|
213
|
+
}, async ({ storeId, ids }) => {
|
|
214
|
+
const handle = this.stores.get(storeId);
|
|
215
|
+
if (!handle) {
|
|
216
|
+
return { content: [{ type: 'text', text: `Error: store ${storeId} not found` }] };
|
|
217
|
+
}
|
|
218
|
+
if (handle.readOnly) {
|
|
219
|
+
return { content: [{ type: 'text', text: 'Error: store is read-only' }] };
|
|
220
|
+
}
|
|
221
|
+
let deleted = 0;
|
|
222
|
+
for (const id of ids) {
|
|
223
|
+
if (handle.vectors.delete(id))
|
|
224
|
+
deleted++;
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
content: [{
|
|
228
|
+
type: 'text',
|
|
229
|
+
text: JSON.stringify({ deleted, remaining: handle.vectors.size }, null, 2),
|
|
230
|
+
}],
|
|
231
|
+
};
|
|
232
|
+
});
|
|
233
|
+
// ── rvf_delete_filter ─────────────────────────────────────────────────
|
|
234
|
+
this.mcp.tool('rvf_delete_filter', 'Delete vectors matching a metadata filter', {
|
|
235
|
+
storeId: z.string().describe('Store ID'),
|
|
236
|
+
filter: z.record(z.union([z.string(), z.number(), z.boolean()]))
|
|
237
|
+
.describe('Metadata filter — all matching vectors will be deleted'),
|
|
238
|
+
}, async ({ storeId, filter }) => {
|
|
239
|
+
const handle = this.stores.get(storeId);
|
|
240
|
+
if (!handle) {
|
|
241
|
+
return { content: [{ type: 'text', text: `Error: store ${storeId} not found` }] };
|
|
242
|
+
}
|
|
243
|
+
if (handle.readOnly) {
|
|
244
|
+
return { content: [{ type: 'text', text: 'Error: store is read-only' }] };
|
|
245
|
+
}
|
|
246
|
+
let deleted = 0;
|
|
247
|
+
for (const [id, entry] of handle.vectors) {
|
|
248
|
+
if (!entry.metadata)
|
|
249
|
+
continue;
|
|
250
|
+
let match = true;
|
|
251
|
+
for (const [key, val] of Object.entries(filter)) {
|
|
252
|
+
if (entry.metadata[key] !== val) {
|
|
253
|
+
match = false;
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (match) {
|
|
258
|
+
handle.vectors.delete(id);
|
|
259
|
+
deleted++;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
content: [{
|
|
264
|
+
type: 'text',
|
|
265
|
+
text: JSON.stringify({ deleted, remaining: handle.vectors.size }, null, 2),
|
|
266
|
+
}],
|
|
267
|
+
};
|
|
268
|
+
});
|
|
269
|
+
// ── rvf_compact ───────────────────────────────────────────────────────
|
|
270
|
+
this.mcp.tool('rvf_compact', 'Compact store to reclaim dead space from deleted vectors', {
|
|
271
|
+
storeId: z.string().describe('Store ID'),
|
|
272
|
+
}, async ({ storeId }) => {
|
|
273
|
+
const handle = this.stores.get(storeId);
|
|
274
|
+
if (!handle) {
|
|
275
|
+
return { content: [{ type: 'text', text: `Error: store ${storeId} not found` }] };
|
|
276
|
+
}
|
|
277
|
+
return {
|
|
278
|
+
content: [{
|
|
279
|
+
type: 'text',
|
|
280
|
+
text: JSON.stringify({
|
|
281
|
+
storeId,
|
|
282
|
+
compacted: true,
|
|
283
|
+
totalVectors: handle.vectors.size,
|
|
284
|
+
}, null, 2),
|
|
285
|
+
}],
|
|
286
|
+
};
|
|
287
|
+
});
|
|
288
|
+
// ── rvf_status ────────────────────────────────────────────────────────
|
|
289
|
+
this.mcp.tool('rvf_status', 'Get the current status of an RVF store', {
|
|
290
|
+
storeId: z.string().describe('Store ID'),
|
|
291
|
+
}, async ({ storeId }) => {
|
|
292
|
+
const handle = this.stores.get(storeId);
|
|
293
|
+
if (!handle) {
|
|
294
|
+
return { content: [{ type: 'text', text: `Error: store ${storeId} not found` }] };
|
|
295
|
+
}
|
|
296
|
+
return {
|
|
297
|
+
content: [{
|
|
298
|
+
type: 'text',
|
|
299
|
+
text: JSON.stringify({
|
|
300
|
+
storeId: handle.id,
|
|
301
|
+
path: handle.path,
|
|
302
|
+
dimensions: handle.dimensions,
|
|
303
|
+
metric: handle.metric,
|
|
304
|
+
readOnly: handle.readOnly,
|
|
305
|
+
totalVectors: handle.vectors.size,
|
|
306
|
+
createdAt: new Date(handle.createdAt).toISOString(),
|
|
307
|
+
}, null, 2),
|
|
308
|
+
}],
|
|
309
|
+
};
|
|
310
|
+
});
|
|
311
|
+
// ── rvf_list_stores ───────────────────────────────────────────────────
|
|
312
|
+
this.mcp.tool('rvf_list_stores', 'List all open RVF stores', {}, async () => {
|
|
313
|
+
const list = Array.from(this.stores.values()).map((h) => ({
|
|
314
|
+
storeId: h.id,
|
|
315
|
+
path: h.path,
|
|
316
|
+
dimensions: h.dimensions,
|
|
317
|
+
metric: h.metric,
|
|
318
|
+
totalVectors: h.vectors.size,
|
|
319
|
+
readOnly: h.readOnly,
|
|
320
|
+
}));
|
|
321
|
+
return {
|
|
322
|
+
content: [{
|
|
323
|
+
type: 'text',
|
|
324
|
+
text: JSON.stringify({ stores: list, count: list.length }, null, 2),
|
|
325
|
+
}],
|
|
326
|
+
};
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
// ─── Resource Registration ──────────────────────────────────────────────
|
|
330
|
+
registerResources() {
|
|
331
|
+
// List of open stores
|
|
332
|
+
this.mcp.resource('stores-list', 'rvf://stores', { description: 'List all open RVF stores and their status' }, async () => {
|
|
333
|
+
const list = Array.from(this.stores.values()).map((h) => ({
|
|
334
|
+
storeId: h.id,
|
|
335
|
+
path: h.path,
|
|
336
|
+
dimensions: h.dimensions,
|
|
337
|
+
totalVectors: h.vectors.size,
|
|
338
|
+
}));
|
|
339
|
+
return {
|
|
340
|
+
contents: [{
|
|
341
|
+
uri: 'rvf://stores',
|
|
342
|
+
mimeType: 'application/json',
|
|
343
|
+
text: JSON.stringify({ stores: list }, null, 2),
|
|
344
|
+
}],
|
|
345
|
+
};
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
// ─── Prompt Registration ────────────────────────────────────────────────
|
|
349
|
+
registerPrompts() {
|
|
350
|
+
this.mcp.prompt('rvf-search', 'Search for similar vectors in an RVF store', [
|
|
351
|
+
{ name: 'storeId', description: 'Store ID to search', required: true },
|
|
352
|
+
{ name: 'description', description: 'Natural language description of what to search for', required: true },
|
|
353
|
+
], async ({ storeId, description }) => ({
|
|
354
|
+
messages: [{
|
|
355
|
+
role: 'user',
|
|
356
|
+
content: {
|
|
357
|
+
type: 'text',
|
|
358
|
+
text: `Search the RVF store "${storeId}" for vectors similar to: "${description}". ` +
|
|
359
|
+
'Use the rvf_query tool to perform the search. If you need to create an embedding ' +
|
|
360
|
+
'from the description first, generate a suitable vector representation.',
|
|
361
|
+
},
|
|
362
|
+
}],
|
|
363
|
+
}));
|
|
364
|
+
this.mcp.prompt('rvf-ingest', 'Ingest data into an RVF store', [
|
|
365
|
+
{ name: 'storeId', description: 'Store ID to ingest into', required: true },
|
|
366
|
+
{ name: 'data', description: 'Data to embed and ingest', required: true },
|
|
367
|
+
], async ({ storeId, data }) => ({
|
|
368
|
+
messages: [{
|
|
369
|
+
role: 'user',
|
|
370
|
+
content: {
|
|
371
|
+
type: 'text',
|
|
372
|
+
text: `Ingest the following data into RVF store "${storeId}": ${data}. ` +
|
|
373
|
+
'Generate appropriate vector embeddings and metadata, then use the rvf_ingest tool.',
|
|
374
|
+
},
|
|
375
|
+
}],
|
|
376
|
+
}));
|
|
377
|
+
}
|
|
378
|
+
// ─── Connection ─────────────────────────────────────────────────────────
|
|
379
|
+
async connect(transport) {
|
|
380
|
+
await this.mcp.connect(transport);
|
|
381
|
+
}
|
|
382
|
+
async close() {
|
|
383
|
+
// Close all stores
|
|
384
|
+
this.stores.clear();
|
|
385
|
+
await this.mcp.close();
|
|
386
|
+
}
|
|
387
|
+
get storeCount() {
|
|
388
|
+
return this.stores.size;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
// ─── Distance Functions ─────────────────────────────────────────────────────
|
|
392
|
+
function computeDistance(a, b, metric) {
|
|
393
|
+
switch (metric) {
|
|
394
|
+
case 'cosine':
|
|
395
|
+
return cosineDistance(a, b);
|
|
396
|
+
case 'dotproduct':
|
|
397
|
+
return -dotProduct(a, b);
|
|
398
|
+
default: // l2
|
|
399
|
+
return l2Distance(a, b);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
function l2Distance(a, b) {
|
|
403
|
+
let sum = 0;
|
|
404
|
+
for (let i = 0; i < a.length; i++) {
|
|
405
|
+
const d = a[i] - b[i];
|
|
406
|
+
sum += d * d;
|
|
407
|
+
}
|
|
408
|
+
return sum;
|
|
409
|
+
}
|
|
410
|
+
function dotProduct(a, b) {
|
|
411
|
+
let sum = 0;
|
|
412
|
+
for (let i = 0; i < a.length; i++) {
|
|
413
|
+
sum += a[i] * b[i];
|
|
414
|
+
}
|
|
415
|
+
return sum;
|
|
416
|
+
}
|
|
417
|
+
function cosineDistance(a, b) {
|
|
418
|
+
let dot = 0;
|
|
419
|
+
let normA = 0;
|
|
420
|
+
let normB = 0;
|
|
421
|
+
for (let i = 0; i < a.length; i++) {
|
|
422
|
+
dot += a[i] * b[i];
|
|
423
|
+
normA += a[i] * a[i];
|
|
424
|
+
normB += b[i] * b[i];
|
|
425
|
+
}
|
|
426
|
+
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
427
|
+
if (denom === 0)
|
|
428
|
+
return 1;
|
|
429
|
+
return 1 - dot / denom;
|
|
430
|
+
}
|
|
431
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transport factory functions for stdio and SSE modes.
|
|
3
|
+
*/
|
|
4
|
+
import { RvfMcpServer, type RvfMcpServerOptions } from './server.js';
|
|
5
|
+
/**
|
|
6
|
+
* Create and start an RVF MCP server over stdio transport.
|
|
7
|
+
*
|
|
8
|
+
* Usage in .mcp.json:
|
|
9
|
+
* ```json
|
|
10
|
+
* {
|
|
11
|
+
* "mcpServers": {
|
|
12
|
+
* "rvf": {
|
|
13
|
+
* "command": "node",
|
|
14
|
+
* "args": ["dist/cli.js", "--transport", "stdio"]
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function createStdioServer(options?: RvfMcpServerOptions): Promise<RvfMcpServer>;
|
|
21
|
+
/**
|
|
22
|
+
* Create and start an RVF MCP server over SSE transport.
|
|
23
|
+
*
|
|
24
|
+
* Starts an Express HTTP server with SSE endpoint at `/sse`
|
|
25
|
+
* and message endpoint at `/messages`.
|
|
26
|
+
*
|
|
27
|
+
* @param port HTTP port. Default: 3100.
|
|
28
|
+
* @param options Server options.
|
|
29
|
+
*/
|
|
30
|
+
export declare function createSseServer(port?: number, options?: RvfMcpServerOptions): Promise<RvfMcpServer>;
|
|
31
|
+
/**
|
|
32
|
+
* Create a server with the specified transport type.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createServer(transport?: 'stdio' | 'sse', port?: number, options?: RvfMcpServerOptions): Promise<RvfMcpServer>;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transport factory functions for stdio and SSE modes.
|
|
3
|
+
*/
|
|
4
|
+
import { RvfMcpServer } from './server.js';
|
|
5
|
+
/**
|
|
6
|
+
* Create and start an RVF MCP server over stdio transport.
|
|
7
|
+
*
|
|
8
|
+
* Usage in .mcp.json:
|
|
9
|
+
* ```json
|
|
10
|
+
* {
|
|
11
|
+
* "mcpServers": {
|
|
12
|
+
* "rvf": {
|
|
13
|
+
* "command": "node",
|
|
14
|
+
* "args": ["dist/cli.js", "--transport", "stdio"]
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export async function createStdioServer(options) {
|
|
21
|
+
const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');
|
|
22
|
+
const server = new RvfMcpServer(options);
|
|
23
|
+
const transport = new StdioServerTransport();
|
|
24
|
+
await server.connect(transport);
|
|
25
|
+
return server;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Create and start an RVF MCP server over SSE transport.
|
|
29
|
+
*
|
|
30
|
+
* Starts an Express HTTP server with SSE endpoint at `/sse`
|
|
31
|
+
* and message endpoint at `/messages`.
|
|
32
|
+
*
|
|
33
|
+
* @param port HTTP port. Default: 3100.
|
|
34
|
+
* @param options Server options.
|
|
35
|
+
*/
|
|
36
|
+
export async function createSseServer(port = 3100, options) {
|
|
37
|
+
const { SSEServerTransport } = await import('@modelcontextprotocol/sdk/server/sse.js');
|
|
38
|
+
const express = (await import('express')).default;
|
|
39
|
+
const app = express();
|
|
40
|
+
const server = new RvfMcpServer(options);
|
|
41
|
+
let sseTransport = null;
|
|
42
|
+
// SSE endpoint — client connects here
|
|
43
|
+
app.get('/sse', (req, res) => {
|
|
44
|
+
sseTransport = new SSEServerTransport('/messages', res);
|
|
45
|
+
server.connect(sseTransport).catch((err) => {
|
|
46
|
+
console.error('SSE connection error:', err);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
// Message endpoint — client sends JSON-RPC here
|
|
50
|
+
app.post('/messages', (req, res) => {
|
|
51
|
+
if (!sseTransport) {
|
|
52
|
+
res.status(503).json({ error: 'No SSE connection' });
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
sseTransport.handlePostMessage(req, res);
|
|
56
|
+
});
|
|
57
|
+
// Health check
|
|
58
|
+
app.get('/health', (_req, res) => {
|
|
59
|
+
res.json({
|
|
60
|
+
status: 'ok',
|
|
61
|
+
server: options?.name ?? 'rvf-mcp-server',
|
|
62
|
+
stores: server.storeCount,
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
app.listen(port, () => {
|
|
66
|
+
console.error(`RVF MCP Server (SSE) listening on http://localhost:${port}`);
|
|
67
|
+
console.error(` SSE endpoint: http://localhost:${port}/sse`);
|
|
68
|
+
console.error(` Message endpoint: http://localhost:${port}/messages`);
|
|
69
|
+
console.error(` Health check: http://localhost:${port}/health`);
|
|
70
|
+
});
|
|
71
|
+
return server;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Create a server with the specified transport type.
|
|
75
|
+
*/
|
|
76
|
+
export async function createServer(transport = 'stdio', port = 3100, options) {
|
|
77
|
+
if (transport === 'sse') {
|
|
78
|
+
return createSseServer(port, options);
|
|
79
|
+
}
|
|
80
|
+
return createStdioServer(options);
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=transports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transports.js","sourceRoot":"","sources":["../src/transports.ts"],"names":[],"mappings":"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"}
|