@kongyo2/mcp-request-context 1.0.1 → 1.0.2
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/core/storage.js +271 -0
- package/dist/core/storage.js.map +1 -0
- package/dist/core/types.js +88 -0
- package/dist/core/types.js.map +1 -0
- package/dist/dashboard/server.js +269 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/index.js +116 -0
- package/dist/index.js.map +1 -0
- package/dist/server.js +134 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/get-context-response.js +83 -0
- package/dist/tools/get-context-response.js.map +1 -0
- package/dist/tools/index.js +4 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/request-context.js +115 -0
- package/dist/tools/request-context.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { promises as fs } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { ok, err } from 'neverthrow';
|
|
5
|
+
import chokidar from 'chokidar';
|
|
6
|
+
import { ContextRequestSchema, CreateContextRequestSchema, generateId } from './types.js';
|
|
7
|
+
// Error types
|
|
8
|
+
export class StorageError extends Error {
|
|
9
|
+
code;
|
|
10
|
+
constructor(message, code) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.code = code;
|
|
13
|
+
this.name = 'StorageError';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class ContextStorage extends EventEmitter {
|
|
17
|
+
storagePath;
|
|
18
|
+
watcher;
|
|
19
|
+
pendingEmit = null;
|
|
20
|
+
DEBOUNCE_MS = 300;
|
|
21
|
+
constructor(basePath) {
|
|
22
|
+
super();
|
|
23
|
+
this.storagePath = join(basePath, '.mcp-request-context', 'requests');
|
|
24
|
+
}
|
|
25
|
+
async initialize() {
|
|
26
|
+
try {
|
|
27
|
+
await fs.mkdir(this.storagePath, { recursive: true });
|
|
28
|
+
return ok(undefined);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
return err(new StorageError(`Failed to initialize storage: ${error instanceof Error ? error.message : String(error)}`, 'IO_ERROR'));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async start() {
|
|
35
|
+
const initResult = await this.initialize();
|
|
36
|
+
if (initResult.isErr()) {
|
|
37
|
+
return initResult;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
this.watcher = chokidar.watch(join(this.storagePath, '*.json'), {
|
|
41
|
+
ignoreInitial: true,
|
|
42
|
+
persistent: true,
|
|
43
|
+
ignorePermissionErrors: true
|
|
44
|
+
});
|
|
45
|
+
this.watcher.on('add', () => this.scheduleChangeEmit());
|
|
46
|
+
this.watcher.on('change', () => this.scheduleChangeEmit());
|
|
47
|
+
this.watcher.on('unlink', () => this.scheduleChangeEmit());
|
|
48
|
+
this.watcher.on('error', (error) => {
|
|
49
|
+
console.error('Storage watcher error:', error);
|
|
50
|
+
});
|
|
51
|
+
return ok(undefined);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
return err(new StorageError(`Failed to start file watcher: ${error instanceof Error ? error.message : String(error)}`, 'IO_ERROR'));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async stop() {
|
|
58
|
+
if (this.pendingEmit) {
|
|
59
|
+
clearTimeout(this.pendingEmit);
|
|
60
|
+
this.pendingEmit = null;
|
|
61
|
+
}
|
|
62
|
+
if (this.watcher) {
|
|
63
|
+
this.watcher.removeAllListeners();
|
|
64
|
+
await this.watcher.close();
|
|
65
|
+
this.watcher = undefined;
|
|
66
|
+
}
|
|
67
|
+
this.removeAllListeners();
|
|
68
|
+
}
|
|
69
|
+
scheduleChangeEmit() {
|
|
70
|
+
if (this.pendingEmit) {
|
|
71
|
+
clearTimeout(this.pendingEmit);
|
|
72
|
+
}
|
|
73
|
+
this.pendingEmit = setTimeout(() => {
|
|
74
|
+
this.pendingEmit = null;
|
|
75
|
+
this.emit('change');
|
|
76
|
+
}, this.DEBOUNCE_MS);
|
|
77
|
+
}
|
|
78
|
+
async createRequest(input) {
|
|
79
|
+
// Validate input
|
|
80
|
+
const parseResult = CreateContextRequestSchema.safeParse(input);
|
|
81
|
+
if (!parseResult.success) {
|
|
82
|
+
return err(new StorageError(`Validation error: ${parseResult.error.message}`, 'VALIDATION_ERROR'));
|
|
83
|
+
}
|
|
84
|
+
const now = new Date();
|
|
85
|
+
const id = generateId('ctx');
|
|
86
|
+
const request = {
|
|
87
|
+
id,
|
|
88
|
+
type: parseResult.data.type,
|
|
89
|
+
priority: parseResult.data.priority,
|
|
90
|
+
status: 'pending',
|
|
91
|
+
title: parseResult.data.title,
|
|
92
|
+
description: parseResult.data.description,
|
|
93
|
+
url: parseResult.data.url,
|
|
94
|
+
hints: parseResult.data.hints,
|
|
95
|
+
expectedFormat: parseResult.data.expectedFormat,
|
|
96
|
+
tags: parseResult.data.tags,
|
|
97
|
+
createdAt: now.toISOString(),
|
|
98
|
+
expiresAt: parseResult.data.expiresInMinutes
|
|
99
|
+
? new Date(now.getTime() + parseResult.data.expiresInMinutes * 60000).toISOString()
|
|
100
|
+
: undefined
|
|
101
|
+
};
|
|
102
|
+
// Validate the complete request
|
|
103
|
+
const validationResult = ContextRequestSchema.safeParse(request);
|
|
104
|
+
if (!validationResult.success) {
|
|
105
|
+
return err(new StorageError(`Request validation error: ${validationResult.error.message}`, 'VALIDATION_ERROR'));
|
|
106
|
+
}
|
|
107
|
+
// Save to file
|
|
108
|
+
const filePath = join(this.storagePath, `${id}.json`);
|
|
109
|
+
try {
|
|
110
|
+
await fs.writeFile(filePath, JSON.stringify(request, null, 2), 'utf-8');
|
|
111
|
+
this.emit('request-created', request);
|
|
112
|
+
return ok(request);
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
return err(new StorageError(`Failed to save request: ${error instanceof Error ? error.message : String(error)}`, 'IO_ERROR'));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async getRequest(id) {
|
|
119
|
+
const filePath = join(this.storagePath, `${id}.json`);
|
|
120
|
+
try {
|
|
121
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
122
|
+
const request = JSON.parse(content);
|
|
123
|
+
const validationResult = ContextRequestSchema.safeParse(request);
|
|
124
|
+
if (!validationResult.success) {
|
|
125
|
+
return err(new StorageError(`Invalid request data: ${validationResult.error.message}`, 'VALIDATION_ERROR'));
|
|
126
|
+
}
|
|
127
|
+
return ok(validationResult.data);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
if (error.code === 'ENOENT') {
|
|
131
|
+
return err(new StorageError(`Request not found: ${id}`, 'NOT_FOUND'));
|
|
132
|
+
}
|
|
133
|
+
return err(new StorageError(`Failed to read request: ${error instanceof Error ? error.message : String(error)}`, 'IO_ERROR'));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
async answerRequest(input) {
|
|
137
|
+
const requestResult = await this.getRequest(input.requestId);
|
|
138
|
+
if (requestResult.isErr()) {
|
|
139
|
+
return requestResult;
|
|
140
|
+
}
|
|
141
|
+
const request = requestResult.value;
|
|
142
|
+
if (request.status !== 'pending') {
|
|
143
|
+
return err(new StorageError(`Cannot answer request with status: ${request.status}`, 'ALREADY_ANSWERED'));
|
|
144
|
+
}
|
|
145
|
+
const updatedRequest = {
|
|
146
|
+
...request,
|
|
147
|
+
status: 'answered',
|
|
148
|
+
response: input.response,
|
|
149
|
+
answeredAt: new Date().toISOString()
|
|
150
|
+
};
|
|
151
|
+
const filePath = join(this.storagePath, `${input.requestId}.json`);
|
|
152
|
+
try {
|
|
153
|
+
await fs.writeFile(filePath, JSON.stringify(updatedRequest, null, 2), 'utf-8');
|
|
154
|
+
this.emit('request-answered', updatedRequest);
|
|
155
|
+
return ok(updatedRequest);
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
return err(new StorageError(`Failed to save response: ${error instanceof Error ? error.message : String(error)}`, 'IO_ERROR'));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
async cancelRequest(id) {
|
|
162
|
+
const requestResult = await this.getRequest(id);
|
|
163
|
+
if (requestResult.isErr()) {
|
|
164
|
+
return requestResult;
|
|
165
|
+
}
|
|
166
|
+
const request = requestResult.value;
|
|
167
|
+
if (request.status !== 'pending') {
|
|
168
|
+
return err(new StorageError(`Cannot cancel request with status: ${request.status}`, 'INVALID_STATUS'));
|
|
169
|
+
}
|
|
170
|
+
const updatedRequest = {
|
|
171
|
+
...request,
|
|
172
|
+
status: 'cancelled'
|
|
173
|
+
};
|
|
174
|
+
const filePath = join(this.storagePath, `${id}.json`);
|
|
175
|
+
try {
|
|
176
|
+
await fs.writeFile(filePath, JSON.stringify(updatedRequest, null, 2), 'utf-8');
|
|
177
|
+
this.emit('request-cancelled', updatedRequest);
|
|
178
|
+
return ok(updatedRequest);
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
return err(new StorageError(`Failed to cancel request: ${error instanceof Error ? error.message : String(error)}`, 'IO_ERROR'));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
async getAllRequests() {
|
|
185
|
+
try {
|
|
186
|
+
const files = await fs.readdir(this.storagePath);
|
|
187
|
+
const requests = [];
|
|
188
|
+
for (const file of files) {
|
|
189
|
+
if (file.endsWith('.json')) {
|
|
190
|
+
const id = file.replace('.json', '');
|
|
191
|
+
const result = await this.getRequest(id);
|
|
192
|
+
if (result.isOk()) {
|
|
193
|
+
requests.push(result.value);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Sort by createdAt descending (newest first)
|
|
198
|
+
requests.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
|
|
199
|
+
return ok(requests);
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
if (error.code === 'ENOENT') {
|
|
203
|
+
return ok([]);
|
|
204
|
+
}
|
|
205
|
+
return err(new StorageError(`Failed to list requests: ${error instanceof Error ? error.message : String(error)}`, 'IO_ERROR'));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
async getPendingRequests() {
|
|
209
|
+
const allResult = await this.getAllRequests();
|
|
210
|
+
if (allResult.isErr()) {
|
|
211
|
+
return allResult;
|
|
212
|
+
}
|
|
213
|
+
const pending = allResult.value.filter(r => r.status === 'pending');
|
|
214
|
+
return ok(pending);
|
|
215
|
+
}
|
|
216
|
+
async deleteRequest(id) {
|
|
217
|
+
const filePath = join(this.storagePath, `${id}.json`);
|
|
218
|
+
try {
|
|
219
|
+
await fs.unlink(filePath);
|
|
220
|
+
return ok(undefined);
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
if (error.code === 'ENOENT') {
|
|
224
|
+
return err(new StorageError(`Request not found: ${id}`, 'NOT_FOUND'));
|
|
225
|
+
}
|
|
226
|
+
return err(new StorageError(`Failed to delete request: ${error instanceof Error ? error.message : String(error)}`, 'IO_ERROR'));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
async cleanupExpired() {
|
|
230
|
+
const allResult = await this.getAllRequests();
|
|
231
|
+
if (allResult.isErr()) {
|
|
232
|
+
return err(allResult.error);
|
|
233
|
+
}
|
|
234
|
+
const now = new Date();
|
|
235
|
+
let cleaned = 0;
|
|
236
|
+
for (const request of allResult.value) {
|
|
237
|
+
if (request.status === 'pending' &&
|
|
238
|
+
request.expiresAt &&
|
|
239
|
+
new Date(request.expiresAt) < now) {
|
|
240
|
+
const updateResult = await this.updateStatus(request.id, 'expired');
|
|
241
|
+
if (updateResult.isOk()) {
|
|
242
|
+
cleaned++;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return ok(cleaned);
|
|
247
|
+
}
|
|
248
|
+
async updateStatus(id, status) {
|
|
249
|
+
const requestResult = await this.getRequest(id);
|
|
250
|
+
if (requestResult.isErr()) {
|
|
251
|
+
return requestResult;
|
|
252
|
+
}
|
|
253
|
+
const updatedRequest = {
|
|
254
|
+
...requestResult.value,
|
|
255
|
+
status
|
|
256
|
+
};
|
|
257
|
+
const filePath = join(this.storagePath, `${id}.json`);
|
|
258
|
+
try {
|
|
259
|
+
await fs.writeFile(filePath, JSON.stringify(updatedRequest, null, 2), 'utf-8');
|
|
260
|
+
this.emit('request-updated', updatedRequest);
|
|
261
|
+
return ok(updatedRequest);
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
return err(new StorageError(`Failed to update request: ${error instanceof Error ? error.message : String(error)}`, 'IO_ERROR'));
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
getStoragePath() {
|
|
268
|
+
return this.storagePath;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/core/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
// Context Request Types
|
|
3
|
+
export const ContextTypeSchema = z.enum([
|
|
4
|
+
'url_content', // エージェントがアクセスできないURLの内容
|
|
5
|
+
'documentation', // APIや依存関係のドキュメント
|
|
6
|
+
'dependency_info', // 依存関係の情報
|
|
7
|
+
'code_snippet', // 特定のコードスニペット
|
|
8
|
+
'configuration', // 設定ファイルの内容
|
|
9
|
+
'api_response', // APIレスポンスの例
|
|
10
|
+
'error_context', // エラーの追加コンテキスト
|
|
11
|
+
'custom' // その他のカスタムリクエスト
|
|
12
|
+
]);
|
|
13
|
+
export const ContextPrioritySchema = z.enum([
|
|
14
|
+
'critical', // ブロッキング - これがないと続行不可
|
|
15
|
+
'high', // 重要 - 早急に必要
|
|
16
|
+
'normal', // 通常の優先度
|
|
17
|
+
'low' // あれば助かる程度
|
|
18
|
+
]);
|
|
19
|
+
export const ContextRequestStatusSchema = z.enum([
|
|
20
|
+
'pending', // 回答待ち
|
|
21
|
+
'answered', // 回答済み
|
|
22
|
+
'cancelled', // キャンセル
|
|
23
|
+
'expired' // 期限切れ
|
|
24
|
+
]);
|
|
25
|
+
// Context Request Schema
|
|
26
|
+
export const ContextRequestSchema = z.object({
|
|
27
|
+
id: z.string(),
|
|
28
|
+
type: ContextTypeSchema,
|
|
29
|
+
priority: ContextPrioritySchema,
|
|
30
|
+
status: ContextRequestStatusSchema,
|
|
31
|
+
// リクエスト内容
|
|
32
|
+
title: z.string().min(1).max(200),
|
|
33
|
+
description: z.string().min(1).max(2000),
|
|
34
|
+
// オプショナルフィールド
|
|
35
|
+
url: z.string().url().optional(), // URL関連の場合
|
|
36
|
+
hints: z.array(z.string()).optional(), // 回答のヒント
|
|
37
|
+
expectedFormat: z.string().optional(), // 期待される回答形式
|
|
38
|
+
// メタデータ
|
|
39
|
+
createdAt: z.string().datetime(),
|
|
40
|
+
answeredAt: z.string().datetime().optional(),
|
|
41
|
+
expiresAt: z.string().datetime().optional(),
|
|
42
|
+
// 回答
|
|
43
|
+
response: z.string().optional(),
|
|
44
|
+
// タグ
|
|
45
|
+
tags: z.array(z.string()).optional()
|
|
46
|
+
});
|
|
47
|
+
// Create Request Input Schema
|
|
48
|
+
export const CreateContextRequestSchema = z.object({
|
|
49
|
+
type: ContextTypeSchema,
|
|
50
|
+
priority: ContextPrioritySchema.default('normal'),
|
|
51
|
+
title: z.string().min(1).max(200),
|
|
52
|
+
description: z.string().min(1).max(2000),
|
|
53
|
+
url: z.string().url().optional(),
|
|
54
|
+
hints: z.array(z.string()).optional(),
|
|
55
|
+
expectedFormat: z.string().optional(),
|
|
56
|
+
expiresInMinutes: z.number().positive().optional(),
|
|
57
|
+
tags: z.array(z.string()).optional()
|
|
58
|
+
});
|
|
59
|
+
// Response Input Schema
|
|
60
|
+
export const ContextResponseSchema = z.object({
|
|
61
|
+
requestId: z.string(),
|
|
62
|
+
response: z.string().min(1)
|
|
63
|
+
});
|
|
64
|
+
// WebSocket Message Types
|
|
65
|
+
export const WSMessageTypeSchema = z.enum([
|
|
66
|
+
'initial',
|
|
67
|
+
'request-created',
|
|
68
|
+
'request-updated',
|
|
69
|
+
'request-answered',
|
|
70
|
+
'request-cancelled',
|
|
71
|
+
'ping',
|
|
72
|
+
'pong'
|
|
73
|
+
]);
|
|
74
|
+
// Helper function to convert ToolResponse to MCP format
|
|
75
|
+
export function toMCPResponse(response, isError = false) {
|
|
76
|
+
return {
|
|
77
|
+
content: [{
|
|
78
|
+
type: 'text',
|
|
79
|
+
text: JSON.stringify(response, null, 2)
|
|
80
|
+
}],
|
|
81
|
+
isError
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
// Generate unique ID
|
|
85
|
+
export function generateId(prefix = 'ctx') {
|
|
86
|
+
return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,wBAAwB;AACxB,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,IAAI,CAAC;IACtC,aAAa,EAAY,wBAAwB;IACjD,eAAe,EAAU,kBAAkB;IAC3C,iBAAiB,EAAQ,UAAU;IACnC,cAAc,EAAW,cAAc;IACvC,eAAe,EAAU,YAAY;IACrC,cAAc,EAAW,aAAa;IACtC,eAAe,EAAU,eAAe;IACxC,QAAQ,CAAiB,gBAAgB;CAC1C,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,IAAI,CAAC;IAC1C,UAAU,EAAI,sBAAsB;IACpC,MAAM,EAAQ,aAAa;IAC3B,QAAQ,EAAM,SAAS;IACvB,KAAK,CAAS,WAAW;CAC1B,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,IAAI,CAAC;IAC/C,SAAS,EAAM,OAAO;IACtB,UAAU,EAAK,OAAO;IACtB,WAAW,EAAI,QAAQ;IACvB,SAAS,CAAM,OAAO;CACvB,CAAC,CAAC;AAIH,yBAAyB;AACzB,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,iBAAiB;IACvB,QAAQ,EAAE,qBAAqB;IAC/B,MAAM,EAAE,0BAA0B;IAElC,UAAU;IACV,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACjC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;IAExC,cAAc;IACd,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAY,WAAW;IACvD,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAO,SAAS;IACrD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAO,YAAY;IAExD,QAAQ;IACR,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC5C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAE3C,KAAK;IACL,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAE/B,KAAK;IACL,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CACrC,CAAC,CAAC;AAIH,8BAA8B;AAC9B,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,IAAI,EAAE,iBAAiB;IACvB,QAAQ,EAAE,qBAAqB,CAAC,OAAO,CAAC,QAAQ,CAAC;IACjD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACjC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;IACxC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAChC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACrC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACrC,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAClD,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CACrC,CAAC,CAAC;AAIH,wBAAwB;AACxB,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC5B,CAAC,CAAC;AA+BH,0BAA0B;AAC1B,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,IAAI,CAAC;IACxC,SAAS;IACT,iBAAiB;IACjB,iBAAiB;IACjB,kBAAkB;IAClB,mBAAmB;IACnB,MAAM;IACN,MAAM;CACP,CAAC,CAAC;AAUH,wDAAwD;AACxD,MAAM,UAAU,aAAa,CAAC,QAAsB,EAAE,OAAO,GAAG,KAAK;IACnE,OAAO;QACL,OAAO,EAAE,CAAC;gBACR,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;aACxC,CAAC;QACF,OAAO;KACR,CAAC;AACJ,CAAC;AAED,qBAAqB;AACrB,MAAM,UAAU,UAAU,CAAC,MAAM,GAAG,KAAK;IACvC,OAAO,GAAG,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AAClF,CAAC"}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import fastify from 'fastify';
|
|
2
|
+
import fastifyStatic from '@fastify/static';
|
|
3
|
+
import fastifyWebsocket from '@fastify/websocket';
|
|
4
|
+
import fastifyCors from '@fastify/cors';
|
|
5
|
+
import { join, dirname } from 'path';
|
|
6
|
+
import { promises as fs } from 'fs';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
import open from 'open';
|
|
9
|
+
import { WebSocket } from 'ws';
|
|
10
|
+
import { ContextStorage } from '../core/storage.js';
|
|
11
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
export class DashboardServer {
|
|
13
|
+
app;
|
|
14
|
+
storage;
|
|
15
|
+
projectPath;
|
|
16
|
+
options;
|
|
17
|
+
clients = new Set();
|
|
18
|
+
heartbeatInterval;
|
|
19
|
+
HEARTBEAT_INTERVAL_MS = 30000;
|
|
20
|
+
constructor(projectPath, options = {}) {
|
|
21
|
+
this.projectPath = projectPath;
|
|
22
|
+
this.options = options;
|
|
23
|
+
this.storage = new ContextStorage(projectPath);
|
|
24
|
+
this.app = fastify({ logger: false });
|
|
25
|
+
}
|
|
26
|
+
async start() {
|
|
27
|
+
// Initialize storage
|
|
28
|
+
const initResult = await this.storage.start();
|
|
29
|
+
if (initResult.isErr()) {
|
|
30
|
+
throw new Error(`Failed to initialize storage: ${initResult.error.message}`);
|
|
31
|
+
}
|
|
32
|
+
// Setup storage event listeners
|
|
33
|
+
this.setupStorageEvents();
|
|
34
|
+
// Register plugins
|
|
35
|
+
await this.app.register(fastifyCors, {
|
|
36
|
+
origin: true,
|
|
37
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE']
|
|
38
|
+
});
|
|
39
|
+
await this.app.register(fastifyStatic, {
|
|
40
|
+
root: join(__dirname, 'public'),
|
|
41
|
+
prefix: '/'
|
|
42
|
+
});
|
|
43
|
+
await this.app.register(fastifyWebsocket);
|
|
44
|
+
// WebSocket endpoint
|
|
45
|
+
await this.app.register(async (fastify) => {
|
|
46
|
+
fastify.get('/ws', { websocket: true }, (socket) => {
|
|
47
|
+
const connection = {
|
|
48
|
+
socket: socket,
|
|
49
|
+
isAlive: true
|
|
50
|
+
};
|
|
51
|
+
this.clients.add(connection);
|
|
52
|
+
socket.on('pong', () => {
|
|
53
|
+
connection.isAlive = true;
|
|
54
|
+
});
|
|
55
|
+
// Send initial data
|
|
56
|
+
this.sendInitialData(socket);
|
|
57
|
+
const cleanup = () => {
|
|
58
|
+
this.clients.delete(connection);
|
|
59
|
+
};
|
|
60
|
+
socket.on('close', cleanup);
|
|
61
|
+
socket.on('error', cleanup);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
// Register API routes
|
|
65
|
+
this.registerApiRoutes();
|
|
66
|
+
// Start server
|
|
67
|
+
const port = this.options.port ?? 5100;
|
|
68
|
+
await this.app.listen({ port, host: '127.0.0.1' });
|
|
69
|
+
// Start heartbeat
|
|
70
|
+
this.startHeartbeat();
|
|
71
|
+
// Save session info
|
|
72
|
+
const dashboardUrl = `http://localhost:${port}`;
|
|
73
|
+
await this.saveSession(dashboardUrl, port);
|
|
74
|
+
// Open browser if requested
|
|
75
|
+
if (this.options.autoOpen) {
|
|
76
|
+
await open(dashboardUrl);
|
|
77
|
+
}
|
|
78
|
+
console.log(`Dashboard running at: ${dashboardUrl}`);
|
|
79
|
+
return dashboardUrl;
|
|
80
|
+
}
|
|
81
|
+
setupStorageEvents() {
|
|
82
|
+
this.storage.on('request-created', (request) => {
|
|
83
|
+
this.broadcast({
|
|
84
|
+
type: 'request-created',
|
|
85
|
+
data: request,
|
|
86
|
+
timestamp: new Date().toISOString()
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
this.storage.on('request-answered', (request) => {
|
|
90
|
+
this.broadcast({
|
|
91
|
+
type: 'request-answered',
|
|
92
|
+
data: request,
|
|
93
|
+
timestamp: new Date().toISOString()
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
this.storage.on('request-cancelled', (request) => {
|
|
97
|
+
this.broadcast({
|
|
98
|
+
type: 'request-cancelled',
|
|
99
|
+
data: request,
|
|
100
|
+
timestamp: new Date().toISOString()
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
this.storage.on('change', async () => {
|
|
104
|
+
const result = await this.storage.getAllRequests();
|
|
105
|
+
if (result.isOk()) {
|
|
106
|
+
this.broadcast({
|
|
107
|
+
type: 'request-updated',
|
|
108
|
+
data: result.value,
|
|
109
|
+
timestamp: new Date().toISOString()
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
async sendInitialData(socket) {
|
|
115
|
+
const result = await this.storage.getAllRequests();
|
|
116
|
+
if (result.isOk()) {
|
|
117
|
+
const message = {
|
|
118
|
+
type: 'initial',
|
|
119
|
+
data: result.value,
|
|
120
|
+
timestamp: new Date().toISOString()
|
|
121
|
+
};
|
|
122
|
+
socket.send(JSON.stringify(message));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
registerApiRoutes() {
|
|
126
|
+
// Health check
|
|
127
|
+
this.app.get('/api/health', async () => {
|
|
128
|
+
return { status: 'ok', timestamp: new Date().toISOString() };
|
|
129
|
+
});
|
|
130
|
+
// Get all requests
|
|
131
|
+
this.app.get('/api/requests', async (_, reply) => {
|
|
132
|
+
const result = await this.storage.getAllRequests();
|
|
133
|
+
if (result.isErr()) {
|
|
134
|
+
return reply.code(500).send({ error: result.error.message });
|
|
135
|
+
}
|
|
136
|
+
return result.value;
|
|
137
|
+
});
|
|
138
|
+
// Get pending requests
|
|
139
|
+
this.app.get('/api/requests/pending', async (_, reply) => {
|
|
140
|
+
const result = await this.storage.getPendingRequests();
|
|
141
|
+
if (result.isErr()) {
|
|
142
|
+
return reply.code(500).send({ error: result.error.message });
|
|
143
|
+
}
|
|
144
|
+
return result.value;
|
|
145
|
+
});
|
|
146
|
+
// Get single request
|
|
147
|
+
this.app.get('/api/requests/:id', async (request, reply) => {
|
|
148
|
+
const result = await this.storage.getRequest(request.params.id);
|
|
149
|
+
if (result.isErr()) {
|
|
150
|
+
const code = result.error.code === 'NOT_FOUND' ? 404 : 500;
|
|
151
|
+
return reply.code(code).send({ error: result.error.message });
|
|
152
|
+
}
|
|
153
|
+
return result.value;
|
|
154
|
+
});
|
|
155
|
+
// Answer a request
|
|
156
|
+
this.app.post('/api/requests/:id/answer', async (request, reply) => {
|
|
157
|
+
const { id } = request.params;
|
|
158
|
+
const { response } = request.body;
|
|
159
|
+
if (!response || typeof response !== 'string') {
|
|
160
|
+
return reply.code(400).send({ error: 'Response is required' });
|
|
161
|
+
}
|
|
162
|
+
const result = await this.storage.answerRequest({
|
|
163
|
+
requestId: id,
|
|
164
|
+
response
|
|
165
|
+
});
|
|
166
|
+
if (result.isErr()) {
|
|
167
|
+
const code = result.error.code === 'NOT_FOUND' ? 404 : 500;
|
|
168
|
+
return reply.code(code).send({ error: result.error.message });
|
|
169
|
+
}
|
|
170
|
+
return { success: true, request: result.value };
|
|
171
|
+
});
|
|
172
|
+
// Cancel a request
|
|
173
|
+
this.app.post('/api/requests/:id/cancel', async (request, reply) => {
|
|
174
|
+
const result = await this.storage.cancelRequest(request.params.id);
|
|
175
|
+
if (result.isErr()) {
|
|
176
|
+
const code = result.error.code === 'NOT_FOUND' ? 404 : 500;
|
|
177
|
+
return reply.code(code).send({ error: result.error.message });
|
|
178
|
+
}
|
|
179
|
+
return { success: true, request: result.value };
|
|
180
|
+
});
|
|
181
|
+
// Delete a request
|
|
182
|
+
this.app.delete('/api/requests/:id', async (request, reply) => {
|
|
183
|
+
const result = await this.storage.deleteRequest(request.params.id);
|
|
184
|
+
if (result.isErr()) {
|
|
185
|
+
const code = result.error.code === 'NOT_FOUND' ? 404 : 500;
|
|
186
|
+
return reply.code(code).send({ error: result.error.message });
|
|
187
|
+
}
|
|
188
|
+
return { success: true };
|
|
189
|
+
});
|
|
190
|
+
// Project info
|
|
191
|
+
this.app.get('/api/project', async () => {
|
|
192
|
+
return {
|
|
193
|
+
projectPath: this.projectPath,
|
|
194
|
+
storagePath: this.storage.getStoragePath()
|
|
195
|
+
};
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
broadcast(message) {
|
|
199
|
+
const messageStr = JSON.stringify(message);
|
|
200
|
+
for (const connection of this.clients) {
|
|
201
|
+
try {
|
|
202
|
+
if (connection.socket.readyState === WebSocket.OPEN) {
|
|
203
|
+
connection.socket.send(messageStr);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
console.error('Error broadcasting:', error);
|
|
208
|
+
this.clients.delete(connection);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
startHeartbeat() {
|
|
213
|
+
this.heartbeatInterval = setInterval(() => {
|
|
214
|
+
for (const connection of this.clients) {
|
|
215
|
+
if (!connection.isAlive) {
|
|
216
|
+
connection.socket.terminate();
|
|
217
|
+
this.clients.delete(connection);
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
connection.isAlive = false;
|
|
221
|
+
connection.socket.ping();
|
|
222
|
+
}
|
|
223
|
+
}, this.HEARTBEAT_INTERVAL_MS);
|
|
224
|
+
}
|
|
225
|
+
async saveSession(url, port) {
|
|
226
|
+
const sessionPath = join(this.projectPath, '.mcp-request-context', 'dashboard-session.json');
|
|
227
|
+
const session = {
|
|
228
|
+
url,
|
|
229
|
+
port,
|
|
230
|
+
pid: process.pid,
|
|
231
|
+
startedAt: new Date().toISOString()
|
|
232
|
+
};
|
|
233
|
+
try {
|
|
234
|
+
await fs.mkdir(dirname(sessionPath), { recursive: true });
|
|
235
|
+
await fs.writeFile(sessionPath, JSON.stringify(session, null, 2), 'utf-8');
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
console.error('Failed to save session:', error);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
async stop() {
|
|
242
|
+
if (this.heartbeatInterval) {
|
|
243
|
+
clearInterval(this.heartbeatInterval);
|
|
244
|
+
}
|
|
245
|
+
for (const connection of this.clients) {
|
|
246
|
+
try {
|
|
247
|
+
connection.socket.close();
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
// Ignore
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
this.clients.clear();
|
|
254
|
+
await this.storage.stop();
|
|
255
|
+
await this.app.close();
|
|
256
|
+
// Remove session file
|
|
257
|
+
const sessionPath = join(this.projectPath, '.mcp-request-context', 'dashboard-session.json');
|
|
258
|
+
try {
|
|
259
|
+
await fs.unlink(sessionPath);
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
// Ignore
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
getStorage() {
|
|
266
|
+
return this.storage;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/dashboard/server.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { resolve } from 'path';
|
|
3
|
+
import { RequestContextMCPServer } from './server.js';
|
|
4
|
+
import { DashboardServer } from './dashboard/server.js';
|
|
5
|
+
function parseArgs() {
|
|
6
|
+
const args = process.argv.slice(2);
|
|
7
|
+
const result = {
|
|
8
|
+
projectPath: process.cwd(),
|
|
9
|
+
dashboard: false,
|
|
10
|
+
open: true
|
|
11
|
+
};
|
|
12
|
+
for (let i = 0; i < args.length; i++) {
|
|
13
|
+
const arg = args[i] ?? '';
|
|
14
|
+
if (arg === '--dashboard' || arg === '-d') {
|
|
15
|
+
result.dashboard = true;
|
|
16
|
+
}
|
|
17
|
+
else if (arg === '--port' || arg === '-p') {
|
|
18
|
+
const nextArg = args[i + 1] ?? '';
|
|
19
|
+
if (nextArg && !nextArg.startsWith('-')) {
|
|
20
|
+
result.port = parseInt(nextArg, 10);
|
|
21
|
+
i++;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else if (arg === '--no-open') {
|
|
25
|
+
result.open = false;
|
|
26
|
+
}
|
|
27
|
+
else if (arg === '--help' || arg === '-h') {
|
|
28
|
+
printHelp();
|
|
29
|
+
process.exit(0);
|
|
30
|
+
}
|
|
31
|
+
else if (arg && !arg.startsWith('-')) {
|
|
32
|
+
result.projectPath = resolve(arg);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
function printHelp() {
|
|
38
|
+
console.log(`
|
|
39
|
+
MCP Request Context - LLM agents request context from humans
|
|
40
|
+
|
|
41
|
+
Usage:
|
|
42
|
+
mcp-request-context [project-path] [options]
|
|
43
|
+
|
|
44
|
+
Options:
|
|
45
|
+
--dashboard, -d Start the dashboard server instead of MCP server
|
|
46
|
+
--port, -p <port> Dashboard port (default: 5100)
|
|
47
|
+
--no-open Don't auto-open browser for dashboard
|
|
48
|
+
--help, -h Show this help message
|
|
49
|
+
|
|
50
|
+
Examples:
|
|
51
|
+
# Start MCP server for current directory
|
|
52
|
+
mcp-request-context
|
|
53
|
+
|
|
54
|
+
# Start MCP server for specific project
|
|
55
|
+
mcp-request-context /path/to/project
|
|
56
|
+
|
|
57
|
+
# Start dashboard server
|
|
58
|
+
mcp-request-context --dashboard
|
|
59
|
+
|
|
60
|
+
# Start dashboard on custom port without auto-opening browser
|
|
61
|
+
mcp-request-context --dashboard --port 5200 --no-open
|
|
62
|
+
|
|
63
|
+
MCP Configuration:
|
|
64
|
+
Add to your MCP settings:
|
|
65
|
+
{
|
|
66
|
+
"mcpServers": {
|
|
67
|
+
"request-context": {
|
|
68
|
+
"command": "npx",
|
|
69
|
+
"args": ["-y", "mcp-request-context", "/path/to/project"]
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
`);
|
|
74
|
+
}
|
|
75
|
+
async function main() {
|
|
76
|
+
const args = parseArgs();
|
|
77
|
+
if (args.dashboard) {
|
|
78
|
+
// Start dashboard server
|
|
79
|
+
const dashboard = new DashboardServer(args.projectPath, {
|
|
80
|
+
port: args.port ?? 5100,
|
|
81
|
+
autoOpen: args.open
|
|
82
|
+
});
|
|
83
|
+
const handleShutdown = async () => {
|
|
84
|
+
console.log('\nShutting down dashboard...');
|
|
85
|
+
await dashboard.stop();
|
|
86
|
+
process.exit(0);
|
|
87
|
+
};
|
|
88
|
+
process.on('SIGINT', handleShutdown);
|
|
89
|
+
process.on('SIGTERM', handleShutdown);
|
|
90
|
+
try {
|
|
91
|
+
const url = await dashboard.start();
|
|
92
|
+
console.log(`\nDashboard running at: ${url}`);
|
|
93
|
+
console.log('Press Ctrl+C to stop\n');
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
console.error('Failed to start dashboard:', error);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
// Start MCP server
|
|
102
|
+
const server = new RequestContextMCPServer(args.projectPath);
|
|
103
|
+
try {
|
|
104
|
+
await server.initialize();
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
console.error('Failed to start MCP server:', error);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
main().catch((error) => {
|
|
113
|
+
console.error('Fatal error:', error);
|
|
114
|
+
process.exit(1);
|
|
115
|
+
});
|
|
116
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { ContextStorage } from './core/storage.js';
|
|
4
|
+
import { toMCPResponse } from './core/types.js';
|
|
5
|
+
import { RequestContextInputSchema, REQUEST_CONTEXT_TOOL_NAME, REQUEST_CONTEXT_TOOL_TITLE, REQUEST_CONTEXT_TOOL_DESCRIPTION, REQUEST_CONTEXT_ANNOTATIONS, requestContextHandler, GetContextResponseInputSchema, GET_CONTEXT_RESPONSE_TOOL_NAME, GET_CONTEXT_RESPONSE_TOOL_TITLE, GET_CONTEXT_RESPONSE_TOOL_DESCRIPTION, GET_CONTEXT_RESPONSE_ANNOTATIONS, getContextResponseHandler } from './tools/index.js';
|
|
6
|
+
import { readFileSync, existsSync } from 'fs';
|
|
7
|
+
import { join, dirname } from 'path';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
export class RequestContextMCPServer {
|
|
11
|
+
server;
|
|
12
|
+
storage;
|
|
13
|
+
projectPath;
|
|
14
|
+
dashboardUrl;
|
|
15
|
+
constructor(projectPath) {
|
|
16
|
+
this.projectPath = projectPath;
|
|
17
|
+
this.storage = new ContextStorage(projectPath);
|
|
18
|
+
// Get version from package.json
|
|
19
|
+
let version = '1.0.0';
|
|
20
|
+
try {
|
|
21
|
+
const packageJsonPath = join(__dirname, '..', 'package.json');
|
|
22
|
+
if (existsSync(packageJsonPath)) {
|
|
23
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
24
|
+
version = packageJson.version ?? version;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// Use default version
|
|
29
|
+
}
|
|
30
|
+
this.server = new McpServer({
|
|
31
|
+
name: 'mcp-request-context',
|
|
32
|
+
version
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
async initialize() {
|
|
36
|
+
// Initialize storage
|
|
37
|
+
const initResult = await this.storage.initialize();
|
|
38
|
+
if (initResult.isErr()) {
|
|
39
|
+
throw new Error(`Failed to initialize storage: ${initResult.error.message}`);
|
|
40
|
+
}
|
|
41
|
+
// Start storage watcher
|
|
42
|
+
const startResult = await this.storage.start();
|
|
43
|
+
if (startResult.isErr()) {
|
|
44
|
+
throw new Error(`Failed to start storage: ${startResult.error.message}`);
|
|
45
|
+
}
|
|
46
|
+
// Try to get dashboard URL from session file
|
|
47
|
+
try {
|
|
48
|
+
const sessionPath = join(this.projectPath, '.mcp-request-context', 'dashboard-session.json');
|
|
49
|
+
if (existsSync(sessionPath)) {
|
|
50
|
+
const sessionData = JSON.parse(readFileSync(sessionPath, 'utf-8'));
|
|
51
|
+
this.dashboardUrl = sessionData.url;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// Dashboard not running
|
|
56
|
+
}
|
|
57
|
+
// Register tools
|
|
58
|
+
this.registerTools();
|
|
59
|
+
// Connect to stdio transport
|
|
60
|
+
const transport = new StdioServerTransport();
|
|
61
|
+
await this.server.connect(transport);
|
|
62
|
+
// Handle transport close
|
|
63
|
+
transport.onclose = async () => {
|
|
64
|
+
await this.stop();
|
|
65
|
+
process.exit(0);
|
|
66
|
+
};
|
|
67
|
+
process.stdin.on('end', async () => {
|
|
68
|
+
await this.stop();
|
|
69
|
+
process.exit(0);
|
|
70
|
+
});
|
|
71
|
+
process.stdin.on('error', async (error) => {
|
|
72
|
+
console.error('stdin error:', error);
|
|
73
|
+
await this.stop();
|
|
74
|
+
process.exit(1);
|
|
75
|
+
});
|
|
76
|
+
console.error(`MCP Request Context server initialized for: ${this.projectPath}`);
|
|
77
|
+
if (this.dashboardUrl) {
|
|
78
|
+
console.error(`Dashboard available at: ${this.dashboardUrl}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
registerTools() {
|
|
82
|
+
// Register request_context tool
|
|
83
|
+
this.server.registerTool(REQUEST_CONTEXT_TOOL_NAME, {
|
|
84
|
+
title: REQUEST_CONTEXT_TOOL_TITLE,
|
|
85
|
+
description: REQUEST_CONTEXT_TOOL_DESCRIPTION,
|
|
86
|
+
inputSchema: RequestContextInputSchema,
|
|
87
|
+
annotations: REQUEST_CONTEXT_ANNOTATIONS
|
|
88
|
+
}, async (args) => {
|
|
89
|
+
try {
|
|
90
|
+
return await requestContextHandler(args, this.storage, this.dashboardUrl);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
94
|
+
const response = {
|
|
95
|
+
success: false,
|
|
96
|
+
message: `Tool execution failed: ${message}`
|
|
97
|
+
};
|
|
98
|
+
return toMCPResponse(response, true);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
// Register get_context_response tool
|
|
102
|
+
this.server.registerTool(GET_CONTEXT_RESPONSE_TOOL_NAME, {
|
|
103
|
+
title: GET_CONTEXT_RESPONSE_TOOL_TITLE,
|
|
104
|
+
description: GET_CONTEXT_RESPONSE_TOOL_DESCRIPTION,
|
|
105
|
+
inputSchema: GetContextResponseInputSchema,
|
|
106
|
+
annotations: GET_CONTEXT_RESPONSE_ANNOTATIONS
|
|
107
|
+
}, async (args) => {
|
|
108
|
+
try {
|
|
109
|
+
return await getContextResponseHandler(args, this.storage, this.dashboardUrl);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
113
|
+
const response = {
|
|
114
|
+
success: false,
|
|
115
|
+
message: `Tool execution failed: ${message}`
|
|
116
|
+
};
|
|
117
|
+
return toMCPResponse(response, true);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
async stop() {
|
|
122
|
+
try {
|
|
123
|
+
await this.storage.stop();
|
|
124
|
+
await this.server.close();
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
console.error('Error during shutdown:', error);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
getStorage() {
|
|
131
|
+
return this.storage;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
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,83 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { toMCPResponse } from '../core/types.js';
|
|
3
|
+
// Zod schema for input validation
|
|
4
|
+
export const GetContextResponseInputSchema = z.object({
|
|
5
|
+
requestId: z.string()
|
|
6
|
+
.min(1, 'Request ID is required')
|
|
7
|
+
.describe('The ID of the context request to check')
|
|
8
|
+
}).strict();
|
|
9
|
+
export const GET_CONTEXT_RESPONSE_TOOL_NAME = 'get_context_response';
|
|
10
|
+
export const GET_CONTEXT_RESPONSE_TOOL_TITLE = 'Get Context Response';
|
|
11
|
+
export const GET_CONTEXT_RESPONSE_TOOL_DESCRIPTION = `Check the status of a context request and retrieve the human's response.
|
|
12
|
+
|
|
13
|
+
Use this tool to poll for responses after creating a context request with 'request_context'.
|
|
14
|
+
|
|
15
|
+
## Status Values
|
|
16
|
+
- pending: Human has not yet responded
|
|
17
|
+
- answered: Human has provided the requested information
|
|
18
|
+
- cancelled: Request was cancelled
|
|
19
|
+
- expired: Request expired without a response
|
|
20
|
+
|
|
21
|
+
When status is 'answered', the response field contains the information provided by the human.`;
|
|
22
|
+
export const GET_CONTEXT_RESPONSE_ANNOTATIONS = {
|
|
23
|
+
readOnlyHint: true,
|
|
24
|
+
destructiveHint: false,
|
|
25
|
+
idempotentHint: true,
|
|
26
|
+
openWorldHint: false
|
|
27
|
+
};
|
|
28
|
+
export async function getContextResponseHandler(args, storage, dashboardUrl) {
|
|
29
|
+
const result = await storage.getRequest(args.requestId);
|
|
30
|
+
if (result.isErr()) {
|
|
31
|
+
const response = {
|
|
32
|
+
success: false,
|
|
33
|
+
message: `Failed to get context request: ${result.error.message}`
|
|
34
|
+
};
|
|
35
|
+
return toMCPResponse(response, true);
|
|
36
|
+
}
|
|
37
|
+
const request = result.value;
|
|
38
|
+
const isAnswered = request.status === 'answered';
|
|
39
|
+
const isPending = request.status === 'pending';
|
|
40
|
+
const canProceed = isAnswered;
|
|
41
|
+
const nextSteps = [];
|
|
42
|
+
if (isPending) {
|
|
43
|
+
nextSteps.push('BLOCKED - Human has not yet responded');
|
|
44
|
+
nextSteps.push('Continue polling with get-context-response');
|
|
45
|
+
if (dashboardUrl) {
|
|
46
|
+
nextSteps.push(`Human should respond at: ${dashboardUrl}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else if (isAnswered) {
|
|
50
|
+
nextSteps.push('UNBLOCKED - Response received');
|
|
51
|
+
nextSteps.push('Use the response data to proceed with your task');
|
|
52
|
+
}
|
|
53
|
+
else if (request.status === 'cancelled') {
|
|
54
|
+
nextSteps.push('Request was cancelled by human');
|
|
55
|
+
nextSteps.push('Consider creating a new request if still needed');
|
|
56
|
+
}
|
|
57
|
+
else if (request.status === 'expired') {
|
|
58
|
+
nextSteps.push('Request expired without response');
|
|
59
|
+
nextSteps.push('Create a new request if still needed');
|
|
60
|
+
}
|
|
61
|
+
const response = {
|
|
62
|
+
success: true,
|
|
63
|
+
message: isAnswered
|
|
64
|
+
? 'Context response received from human'
|
|
65
|
+
: `Request status: ${request.status}`,
|
|
66
|
+
data: {
|
|
67
|
+
requestId: request.id,
|
|
68
|
+
type: request.type,
|
|
69
|
+
priority: request.priority,
|
|
70
|
+
title: request.title,
|
|
71
|
+
status: request.status,
|
|
72
|
+
createdAt: request.createdAt,
|
|
73
|
+
answeredAt: request.answeredAt,
|
|
74
|
+
expiresAt: request.expiresAt,
|
|
75
|
+
response: request.response,
|
|
76
|
+
canProceed,
|
|
77
|
+
mustWait: isPending
|
|
78
|
+
},
|
|
79
|
+
nextSteps
|
|
80
|
+
};
|
|
81
|
+
return toMCPResponse(response);
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=get-context-response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-context-response.js","sourceRoot":"","sources":["../../src/tools/get-context-response.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// Re-export tool definitions
|
|
2
|
+
export { RequestContextInputSchema, REQUEST_CONTEXT_TOOL_NAME, REQUEST_CONTEXT_TOOL_TITLE, REQUEST_CONTEXT_TOOL_DESCRIPTION, REQUEST_CONTEXT_ANNOTATIONS, requestContextHandler } from './request-context.js';
|
|
3
|
+
export { GetContextResponseInputSchema, GET_CONTEXT_RESPONSE_TOOL_NAME, GET_CONTEXT_RESPONSE_TOOL_TITLE, GET_CONTEXT_RESPONSE_TOOL_DESCRIPTION, GET_CONTEXT_RESPONSE_ANNOTATIONS, getContextResponseHandler } from './get-context-response.js';
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAEA,6BAA6B;AAC7B,OAAO,EACL,yBAAyB,EAEzB,yBAAyB,EACzB,0BAA0B,EAC1B,gCAAgC,EAChC,2BAA2B,EAC3B,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,6BAA6B,EAE7B,8BAA8B,EAC9B,+BAA+B,EAC/B,qCAAqC,EACrC,gCAAgC,EAChC,yBAAyB,EAC1B,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { toMCPResponse, ContextTypeSchema, ContextPrioritySchema } from '../core/types.js';
|
|
3
|
+
// Zod schema for input validation
|
|
4
|
+
export const RequestContextInputSchema = z.object({
|
|
5
|
+
type: ContextTypeSchema
|
|
6
|
+
.describe('The type of context being requested'),
|
|
7
|
+
priority: ContextPrioritySchema
|
|
8
|
+
.default('normal')
|
|
9
|
+
.describe('Priority level of the request'),
|
|
10
|
+
title: z.string()
|
|
11
|
+
.min(1, 'Title is required')
|
|
12
|
+
.max(200, 'Title must not exceed 200 characters')
|
|
13
|
+
.describe('Brief title describing what information is needed'),
|
|
14
|
+
description: z.string()
|
|
15
|
+
.min(1, 'Description is required')
|
|
16
|
+
.max(2000, 'Description must not exceed 2000 characters')
|
|
17
|
+
.describe('Detailed description of what information is needed and why'),
|
|
18
|
+
url: z.string()
|
|
19
|
+
.url('Must be a valid URL')
|
|
20
|
+
.optional()
|
|
21
|
+
.describe('URL to fetch content from (for url_content type)'),
|
|
22
|
+
hints: z.array(z.string())
|
|
23
|
+
.optional()
|
|
24
|
+
.describe('Hints to help the human provide the right information'),
|
|
25
|
+
expectedFormat: z.string()
|
|
26
|
+
.optional()
|
|
27
|
+
.describe('Description of the expected response format'),
|
|
28
|
+
expiresInMinutes: z.number()
|
|
29
|
+
.positive('Must be a positive number')
|
|
30
|
+
.optional()
|
|
31
|
+
.describe('Request expiration time in minutes'),
|
|
32
|
+
tags: z.array(z.string())
|
|
33
|
+
.optional()
|
|
34
|
+
.describe('Tags to categorize the request')
|
|
35
|
+
}).strict();
|
|
36
|
+
export const REQUEST_CONTEXT_TOOL_NAME = 'request_context';
|
|
37
|
+
export const REQUEST_CONTEXT_TOOL_TITLE = 'Request Context from Human';
|
|
38
|
+
export const REQUEST_CONTEXT_TOOL_DESCRIPTION = `Request context/information from a human operator.
|
|
39
|
+
|
|
40
|
+
Use this tool when you need information that:
|
|
41
|
+
- Is behind a URL you cannot access
|
|
42
|
+
- Requires reading documentation that is difficult to parse
|
|
43
|
+
- Involves dependency/API information the human can provide faster
|
|
44
|
+
- Would take multiple turns to gather but the human can provide directly
|
|
45
|
+
|
|
46
|
+
The human will see your request in a dashboard UI and can respond with the needed information.
|
|
47
|
+
|
|
48
|
+
## Context Types
|
|
49
|
+
- url_content: Content from a URL you cannot access
|
|
50
|
+
- documentation: API/library documentation content
|
|
51
|
+
- dependency_info: Package/dependency information
|
|
52
|
+
- code_snippet: Specific code snippets
|
|
53
|
+
- configuration: Configuration file contents
|
|
54
|
+
- api_response: Example API responses
|
|
55
|
+
- error_context: Additional error context
|
|
56
|
+
- custom: Any other type of context
|
|
57
|
+
|
|
58
|
+
## Priority Levels
|
|
59
|
+
- critical: Blocking - cannot proceed without this
|
|
60
|
+
- high: Important - needed soon
|
|
61
|
+
- normal: Standard priority
|
|
62
|
+
- low: Nice to have
|
|
63
|
+
|
|
64
|
+
After creating a request, poll the status using 'get_context_response' tool.`;
|
|
65
|
+
export const REQUEST_CONTEXT_ANNOTATIONS = {
|
|
66
|
+
readOnlyHint: false,
|
|
67
|
+
destructiveHint: false,
|
|
68
|
+
idempotentHint: false,
|
|
69
|
+
openWorldHint: false
|
|
70
|
+
};
|
|
71
|
+
export async function requestContextHandler(args, storage, dashboardUrl) {
|
|
72
|
+
const result = await storage.createRequest({
|
|
73
|
+
type: args.type,
|
|
74
|
+
priority: args.priority ?? 'normal',
|
|
75
|
+
title: args.title,
|
|
76
|
+
description: args.description,
|
|
77
|
+
url: args.url,
|
|
78
|
+
hints: args.hints,
|
|
79
|
+
expectedFormat: args.expectedFormat,
|
|
80
|
+
expiresInMinutes: args.expiresInMinutes,
|
|
81
|
+
tags: args.tags
|
|
82
|
+
});
|
|
83
|
+
if (result.isErr()) {
|
|
84
|
+
const response = {
|
|
85
|
+
success: false,
|
|
86
|
+
message: `Failed to create context request: ${result.error.message}`
|
|
87
|
+
};
|
|
88
|
+
return toMCPResponse(response, true);
|
|
89
|
+
}
|
|
90
|
+
const request = result.value;
|
|
91
|
+
const response = {
|
|
92
|
+
success: true,
|
|
93
|
+
message: `Context request created successfully. Human will respond via dashboard.`,
|
|
94
|
+
data: {
|
|
95
|
+
requestId: request.id,
|
|
96
|
+
type: request.type,
|
|
97
|
+
priority: request.priority,
|
|
98
|
+
title: request.title,
|
|
99
|
+
status: request.status,
|
|
100
|
+
createdAt: request.createdAt,
|
|
101
|
+
expiresAt: request.expiresAt,
|
|
102
|
+
dashboardUrl
|
|
103
|
+
},
|
|
104
|
+
nextSteps: [
|
|
105
|
+
'BLOCKING - Wait for human response',
|
|
106
|
+
dashboardUrl
|
|
107
|
+
? `Human should respond at: ${dashboardUrl}`
|
|
108
|
+
: 'Start dashboard with: mcp-request-context --dashboard',
|
|
109
|
+
`Poll status with: get-context-response requestId:"${request.id}"`,
|
|
110
|
+
'Do NOT proceed until response is received'
|
|
111
|
+
]
|
|
112
|
+
};
|
|
113
|
+
return toMCPResponse(response);
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=request-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-context.js","sourceRoot":"","sources":["../../src/tools/request-context.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED