@retrodeck/mcp 1.0.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/dist/http-server.d.ts +3 -0
- package/dist/http-server.d.ts.map +1 -0
- package/dist/http-server.js +71 -0
- package/dist/http-server.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24693 -0
- package/dist/index.js.map +1 -0
- package/dist/node.d.ts +76 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +470 -0
- package/dist/node.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +134 -0
- package/dist/server.js.map +1 -0
- package/dist/sync-service.d.ts +29 -0
- package/dist/sync-service.d.ts.map +1 -0
- package/dist/sync-service.js +123 -0
- package/dist/sync-service.js.map +1 -0
- package/package.json +28 -0
package/dist/server.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// packages/rdk-mcp/src/server.ts
|
|
2
|
+
// RDK MCP Server — all 6 tools exposed via stdio transport.
|
|
3
|
+
// Activation is tool-call driven, not passive.
|
|
4
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
5
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
6
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
7
|
+
import { RDKNode } from './node.js';
|
|
8
|
+
const RDK_TOOLS = [
|
|
9
|
+
{
|
|
10
|
+
name: 'rdk_query',
|
|
11
|
+
description: `Query the RDK knowledge network. Returns pre-indexed context chunks from your private vault and the public knowledge network. Use this BEFORE making any LLM call about factual domain knowledge. Reduces token usage by serving pre-computed answers.`,
|
|
12
|
+
inputSchema: {
|
|
13
|
+
type: 'object',
|
|
14
|
+
properties: {
|
|
15
|
+
query: { type: 'string', description: 'The question or topic to retrieve context for' },
|
|
16
|
+
domain: { type: 'string', description: 'Optional domain filter (e.g. fintech, legal, engineering)' },
|
|
17
|
+
includePrivate: { type: 'boolean', default: true },
|
|
18
|
+
includeNetwork: { type: 'boolean', default: true },
|
|
19
|
+
topK: { type: 'number', default: 5 },
|
|
20
|
+
},
|
|
21
|
+
required: ['query'],
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'rdk_index',
|
|
26
|
+
description: `Index a document into your RDK knowledge vault. Content is chunked, embedded, and stored locally. If marked public, contributed to the network to earn tips.`,
|
|
27
|
+
inputSchema: {
|
|
28
|
+
type: 'object',
|
|
29
|
+
properties: {
|
|
30
|
+
content: { type: 'string' },
|
|
31
|
+
title: { type: 'string' },
|
|
32
|
+
isPublic: { type: 'boolean', default: true },
|
|
33
|
+
domain: { type: 'string' },
|
|
34
|
+
categories: { type: 'array', items: { type: 'string' } },
|
|
35
|
+
},
|
|
36
|
+
required: ['content', 'title'],
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'rdk_index_url',
|
|
41
|
+
description: `Fetch and index a URL into your RDK knowledge vault.`,
|
|
42
|
+
inputSchema: {
|
|
43
|
+
type: 'object',
|
|
44
|
+
properties: {
|
|
45
|
+
url: { type: 'string' },
|
|
46
|
+
isPublic: { type: 'boolean', default: true },
|
|
47
|
+
domain: { type: 'string' },
|
|
48
|
+
},
|
|
49
|
+
required: ['url'],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: 'rdk_index_vault',
|
|
54
|
+
description: `Re-index your connected vault (Obsidian, filesystem, Logseq, or Notion). Scans for new or modified files.`,
|
|
55
|
+
inputSchema: {
|
|
56
|
+
type: 'object',
|
|
57
|
+
properties: {
|
|
58
|
+
forceReindex: { type: 'boolean', default: false },
|
|
59
|
+
publicOnly: { type: 'boolean', default: false },
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'rdk_status',
|
|
65
|
+
description: `Get current RDK node status: chunks indexed, network connectivity, plan, vault sync.`,
|
|
66
|
+
inputSchema: { type: 'object', properties: {} },
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: 'rdk_earnings',
|
|
70
|
+
description: `View tip earnings from other nodes retrieving your contributed knowledge.`,
|
|
71
|
+
inputSchema: { type: 'object', properties: {} },
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
export async function startMcpServer() {
|
|
75
|
+
const node = new RDKNode();
|
|
76
|
+
await node.init();
|
|
77
|
+
const server = new Server({ name: 'rdk', version: '1.0.0' }, { capabilities: { tools: {} } });
|
|
78
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
79
|
+
tools: RDK_TOOLS,
|
|
80
|
+
}));
|
|
81
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
82
|
+
const { name, arguments: args } = request.params;
|
|
83
|
+
const a = (args ?? {});
|
|
84
|
+
try {
|
|
85
|
+
switch (name) {
|
|
86
|
+
case 'rdk_query':
|
|
87
|
+
return await node.handleQuery(a.query, {
|
|
88
|
+
domain: a.domain,
|
|
89
|
+
includePrivate: a.includePrivate !== false,
|
|
90
|
+
includeNetwork: a.includeNetwork !== false,
|
|
91
|
+
topK: a.topK ?? 5,
|
|
92
|
+
});
|
|
93
|
+
case 'rdk_index':
|
|
94
|
+
return await node.handleIndex({
|
|
95
|
+
content: a.content,
|
|
96
|
+
title: a.title,
|
|
97
|
+
isPublic: a.isPublic,
|
|
98
|
+
domain: a.domain,
|
|
99
|
+
categories: a.categories,
|
|
100
|
+
});
|
|
101
|
+
case 'rdk_index_url':
|
|
102
|
+
return await node.handleIndexUrl({
|
|
103
|
+
url: a.url,
|
|
104
|
+
isPublic: a.isPublic,
|
|
105
|
+
domain: a.domain,
|
|
106
|
+
});
|
|
107
|
+
case 'rdk_index_vault':
|
|
108
|
+
return await node.handleIndexVault({
|
|
109
|
+
forceReindex: a.forceReindex,
|
|
110
|
+
publicOnly: a.publicOnly,
|
|
111
|
+
});
|
|
112
|
+
case 'rdk_status':
|
|
113
|
+
return await node.handleStatus();
|
|
114
|
+
case 'rdk_earnings':
|
|
115
|
+
return await node.handleEarnings();
|
|
116
|
+
default:
|
|
117
|
+
return {
|
|
118
|
+
content: [{ type: 'text', text: `Unknown tool: ${name}` }],
|
|
119
|
+
isError: true,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch (e) {
|
|
124
|
+
return {
|
|
125
|
+
content: [{ type: 'text', text: `RDK error: ${e.message}` }],
|
|
126
|
+
isError: true,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
const transport = new StdioServerTransport();
|
|
131
|
+
await server.connect(transport);
|
|
132
|
+
}
|
|
133
|
+
startMcpServer().catch(console.error);
|
|
134
|
+
//# 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,29 @@
|
|
|
1
|
+
import { LocalStore } from '@rdk/core';
|
|
2
|
+
export interface SyncConfig {
|
|
3
|
+
enabled: boolean;
|
|
4
|
+
intervalMinutes: number;
|
|
5
|
+
centralApiUrl: string;
|
|
6
|
+
centralApiKey: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class SyncService {
|
|
9
|
+
private config;
|
|
10
|
+
private store;
|
|
11
|
+
private timer;
|
|
12
|
+
private syncing;
|
|
13
|
+
private jwtToken?;
|
|
14
|
+
private jwtExpiry;
|
|
15
|
+
constructor(config: SyncConfig, store: LocalStore);
|
|
16
|
+
start(): void;
|
|
17
|
+
stop(): void;
|
|
18
|
+
syncOnce(): Promise<{
|
|
19
|
+
synced: number;
|
|
20
|
+
errors: number;
|
|
21
|
+
}>;
|
|
22
|
+
getStatus(): {
|
|
23
|
+
enabled: boolean;
|
|
24
|
+
intervalMinutes: number;
|
|
25
|
+
running: boolean;
|
|
26
|
+
};
|
|
27
|
+
private getJwt;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=sync-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-service.d.ts","sourceRoot":"","sources":["../src/sync-service.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,WAAW;IAMV,OAAO,CAAC,MAAM;IAAc,OAAO,CAAC,KAAK;IALrD,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAK;gBAEF,MAAM,EAAE,UAAU,EAAU,KAAK,EAAE,UAAU;IAEjE,KAAK,IAAI,IAAI;IAab,IAAI,IAAI,IAAI;IAQN,QAAQ,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAuE7D,SAAS,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE;YAQ9D,MAAM;CAYrB"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// packages/rdk-mcp/src/sync-service.ts
|
|
2
|
+
// Background sync loop. Runs inside the mcp:serve process.
|
|
3
|
+
// Every N minutes, finds unsynced public chunks and POSTs them to RDK Central.
|
|
4
|
+
// All output goes to console.error — never console.log (stdio is JSON-RPC).
|
|
5
|
+
export class SyncService {
|
|
6
|
+
config;
|
|
7
|
+
store;
|
|
8
|
+
timer = null;
|
|
9
|
+
syncing = false;
|
|
10
|
+
jwtToken;
|
|
11
|
+
jwtExpiry = 0;
|
|
12
|
+
constructor(config, store) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
this.store = store;
|
|
15
|
+
}
|
|
16
|
+
start() {
|
|
17
|
+
if (!this.config.enabled) {
|
|
18
|
+
console.error('[sync] auto-sync disabled');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
console.error(`[sync] starting — every ${this.config.intervalMinutes} minutes`);
|
|
22
|
+
this.syncOnce().catch(e => console.error('[sync] initial sync failed:', e));
|
|
23
|
+
this.timer = setInterval(() => this.syncOnce().catch(e => console.error('[sync] error:', e)), this.config.intervalMinutes * 60 * 1000);
|
|
24
|
+
}
|
|
25
|
+
stop() {
|
|
26
|
+
if (this.timer) {
|
|
27
|
+
clearInterval(this.timer);
|
|
28
|
+
this.timer = null;
|
|
29
|
+
}
|
|
30
|
+
console.error('[sync] stopped');
|
|
31
|
+
}
|
|
32
|
+
async syncOnce() {
|
|
33
|
+
if (this.syncing)
|
|
34
|
+
return { synced: 0, errors: 0 };
|
|
35
|
+
this.syncing = true;
|
|
36
|
+
let synced = 0;
|
|
37
|
+
let errors = 0;
|
|
38
|
+
try {
|
|
39
|
+
const unsynced = this.store.getUnsyncedPublicChunks(100);
|
|
40
|
+
if (unsynced.length === 0)
|
|
41
|
+
return { synced: 0, errors: 0 };
|
|
42
|
+
console.error(`[sync] ${unsynced.length} unsynced public chunk(s) found`);
|
|
43
|
+
const jwt = await this.getJwt();
|
|
44
|
+
const payload = [];
|
|
45
|
+
for (const chunk of unsynced) {
|
|
46
|
+
const embedding = this.store.getEmbedding(chunk.id);
|
|
47
|
+
if (!embedding)
|
|
48
|
+
continue;
|
|
49
|
+
payload.push({
|
|
50
|
+
chunkHash: chunk.id,
|
|
51
|
+
title: chunk.title,
|
|
52
|
+
summary: chunk.summary,
|
|
53
|
+
domain: chunk.domain,
|
|
54
|
+
categories: chunk.categories,
|
|
55
|
+
embedding: Array.from(embedding),
|
|
56
|
+
isPublic: true,
|
|
57
|
+
freshnessAt: chunk.updatedAt.toISOString(),
|
|
58
|
+
chunkTokens: Math.ceil(chunk.content.length / 4),
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
if (payload.length === 0)
|
|
62
|
+
return { synced: 0, errors: 0 };
|
|
63
|
+
const batchSize = 50;
|
|
64
|
+
for (let i = 0; i < payload.length; i += batchSize) {
|
|
65
|
+
const batch = payload.slice(i, i + batchSize);
|
|
66
|
+
try {
|
|
67
|
+
const res = await fetch(`${this.config.centralApiUrl}/api/v1/chunks/sync`, {
|
|
68
|
+
method: 'POST',
|
|
69
|
+
headers: {
|
|
70
|
+
Authorization: `Bearer ${jwt}`,
|
|
71
|
+
'Content-Type': 'application/json',
|
|
72
|
+
},
|
|
73
|
+
body: JSON.stringify({ chunks: batch }),
|
|
74
|
+
signal: AbortSignal.timeout(30_000),
|
|
75
|
+
});
|
|
76
|
+
if (res.ok) {
|
|
77
|
+
const result = await res.json();
|
|
78
|
+
synced += result.synced;
|
|
79
|
+
errors += result.errors.length;
|
|
80
|
+
for (const chunk of batch)
|
|
81
|
+
this.store.markSynced(chunk.chunkHash);
|
|
82
|
+
console.error(`[sync] batch synced: ${result.synced} chunk(s)`);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
const errorText = await res.text();
|
|
86
|
+
console.error(`[sync] batch failed: HTTP ${res.status} — ${errorText}`);
|
|
87
|
+
errors += batch.length;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
91
|
+
console.error(`[sync] batch request failed: ${e.message}`);
|
|
92
|
+
errors += batch.length;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
this.syncing = false;
|
|
98
|
+
}
|
|
99
|
+
return { synced, errors };
|
|
100
|
+
}
|
|
101
|
+
getStatus() {
|
|
102
|
+
return {
|
|
103
|
+
enabled: this.config.enabled,
|
|
104
|
+
intervalMinutes: this.config.intervalMinutes,
|
|
105
|
+
running: this.timer !== null,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
async getJwt() {
|
|
109
|
+
if (this.jwtToken && Date.now() < this.jwtExpiry)
|
|
110
|
+
return this.jwtToken;
|
|
111
|
+
const res = await fetch(`${this.config.centralApiUrl}/api/v1/nodes/auth`, {
|
|
112
|
+
method: 'POST',
|
|
113
|
+
headers: { Authorization: `Bearer ${this.config.centralApiKey}` },
|
|
114
|
+
});
|
|
115
|
+
if (!res.ok)
|
|
116
|
+
throw new Error(`Auth failed: HTTP ${res.status}`);
|
|
117
|
+
const { jwtToken } = await res.json();
|
|
118
|
+
this.jwtToken = jwtToken;
|
|
119
|
+
this.jwtExpiry = Date.now() + 55 * 60 * 1000;
|
|
120
|
+
return jwtToken;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=sync-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-service.js","sourceRoot":"","sources":["../src/sync-service.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@retrodeck/mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "RDK MCP server — exposes knowledge tools to Claude and other agents",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"peerDependencies": {
|
|
7
|
+
"@modelcontextprotocol/sdk": ">=1.0.0"
|
|
8
|
+
},
|
|
9
|
+
"devDependencies": {
|
|
10
|
+
"@modelcontextprotocol/sdk": "1.12.1",
|
|
11
|
+
"@types/express": "^5.0.1",
|
|
12
|
+
"@types/node": "^22.15.21",
|
|
13
|
+
"esbuild": "^0.28.0",
|
|
14
|
+
"express": "^4.21.2",
|
|
15
|
+
"typescript": "^5.8.3",
|
|
16
|
+
"@rdk/core": "1.0.0"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist/",
|
|
20
|
+
"package.json"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "esbuild src/index.ts --bundle --platform=node --format=cjs --target=node20 --outfile=dist/index.js --external:@modelcontextprotocol/sdk --external:better-sqlite3 --external:@xenova/transformers",
|
|
24
|
+
"dev": "tsc -p tsconfig.json --watch",
|
|
25
|
+
"start": "node dist/index.js",
|
|
26
|
+
"clean": "rm -rf dist"
|
|
27
|
+
}
|
|
28
|
+
}
|