@intangle/mcp-server 2.5.3 → 2.5.5
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/index.js +88 -12
- package/dist/tool-definitions.js +34 -25
- package/index.ts +129 -20
- package/package.json +51 -51
- package/tool-definitions.ts +38 -25
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { dirname, join } from "path";
|
|
|
7
7
|
import { fileURLToPath } from "url";
|
|
8
8
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
9
9
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
10
|
-
import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from "@modelcontextprotocol/sdk/types.js";
|
|
10
|
+
import { CallToolRequestSchema, ErrorCode, ListResourceTemplatesRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, McpError, ReadResourceRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
11
11
|
import { config } from "dotenv";
|
|
12
12
|
import fetch from "node-fetch";
|
|
13
13
|
import { TOOLS } from "./tool-definitions.js";
|
|
@@ -101,6 +101,13 @@ try {
|
|
|
101
101
|
}
|
|
102
102
|
return url.toString();
|
|
103
103
|
}
|
|
104
|
+
function buildRemoteApiUrl() {
|
|
105
|
+
const url = new URL("/api/mcp-remote", API_BASE_URL);
|
|
106
|
+
if (VERCEL_BYPASS_TOKEN) {
|
|
107
|
+
url.searchParams.set("x-vercel-protection-bypass", VERCEL_BYPASS_TOKEN);
|
|
108
|
+
}
|
|
109
|
+
return url.toString();
|
|
110
|
+
}
|
|
104
111
|
async function makeApiCall(endpoint, data, timeoutMs) {
|
|
105
112
|
// Ensure we have client info before making requests
|
|
106
113
|
ensureClientInfo();
|
|
@@ -160,6 +167,57 @@ try {
|
|
|
160
167
|
clearTimeout(timeoutId);
|
|
161
168
|
}
|
|
162
169
|
}
|
|
170
|
+
async function makeRemoteRpcCall(method, params) {
|
|
171
|
+
ensureClientInfo();
|
|
172
|
+
const headers = {
|
|
173
|
+
"Content-Type": "application/json",
|
|
174
|
+
Authorization: `Bearer ${MCP_API_KEY}`,
|
|
175
|
+
"User-Agent": mcpClientName
|
|
176
|
+
? `${mcpClientName}/${mcpClientVersion || "unknown"} (mcp-stdio)`
|
|
177
|
+
: "MCP-Client-Stdio/1.1.2 (mcp)",
|
|
178
|
+
};
|
|
179
|
+
if (mcpClientName) {
|
|
180
|
+
headers["X-MCP-Client-Name"] = mcpClientName;
|
|
181
|
+
}
|
|
182
|
+
if (mcpClientVersion) {
|
|
183
|
+
headers["X-MCP-Client-Version"] = mcpClientVersion;
|
|
184
|
+
}
|
|
185
|
+
if (VERCEL_BYPASS_TOKEN) {
|
|
186
|
+
headers["x-vercel-protection-bypass"] = VERCEL_BYPASS_TOKEN;
|
|
187
|
+
}
|
|
188
|
+
const requestId = Date.now();
|
|
189
|
+
const rpcBody = {
|
|
190
|
+
jsonrpc: "2.0",
|
|
191
|
+
id: requestId,
|
|
192
|
+
method,
|
|
193
|
+
params,
|
|
194
|
+
};
|
|
195
|
+
const response = await fetch(buildRemoteApiUrl(), {
|
|
196
|
+
method: "POST",
|
|
197
|
+
headers,
|
|
198
|
+
body: JSON.stringify(rpcBody),
|
|
199
|
+
});
|
|
200
|
+
const responseText = await response.text();
|
|
201
|
+
let responseJson = {};
|
|
202
|
+
try {
|
|
203
|
+
responseJson = responseText ? JSON.parse(responseText) : {};
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
throw new Error(`Failed to parse MCP remote ${method} response`);
|
|
207
|
+
}
|
|
208
|
+
if (!response.ok) {
|
|
209
|
+
const message = responseJson?.error?.message ||
|
|
210
|
+
responseJson?.message ||
|
|
211
|
+
`${response.status} ${response.statusText}`;
|
|
212
|
+
throw new Error(`MCP remote ${method} failed: ${message}`);
|
|
213
|
+
}
|
|
214
|
+
if (responseJson?.error) {
|
|
215
|
+
const code = responseJson.error.code;
|
|
216
|
+
const message = responseJson.error.message || "Unknown MCP remote error";
|
|
217
|
+
throw new Error(`MCP remote ${method} error (${code}): ${message}`);
|
|
218
|
+
}
|
|
219
|
+
return responseJson?.result ?? {};
|
|
220
|
+
}
|
|
163
221
|
const server = new Server({
|
|
164
222
|
name: "intangle-context",
|
|
165
223
|
version: "1.0.0",
|
|
@@ -171,12 +229,33 @@ try {
|
|
|
171
229
|
],
|
|
172
230
|
}, {
|
|
173
231
|
capabilities: {
|
|
232
|
+
resources: {},
|
|
174
233
|
tools: {},
|
|
175
234
|
},
|
|
176
235
|
});
|
|
177
236
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
178
237
|
tools: TOOLS,
|
|
179
238
|
}));
|
|
239
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
240
|
+
const result = await makeRemoteRpcCall("resources/list", {});
|
|
241
|
+
return {
|
|
242
|
+
resources: Array.isArray(result?.resources) ? result.resources : [],
|
|
243
|
+
nextCursor: typeof result?.nextCursor === "string" ? result.nextCursor : undefined,
|
|
244
|
+
};
|
|
245
|
+
});
|
|
246
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
247
|
+
const uri = request?.params?.uri;
|
|
248
|
+
if (!uri || typeof uri !== "string") {
|
|
249
|
+
throw new McpError(ErrorCode.InvalidParams, "uri is required for resources/read");
|
|
250
|
+
}
|
|
251
|
+
const result = await makeRemoteRpcCall("resources/read", { uri });
|
|
252
|
+
return {
|
|
253
|
+
contents: Array.isArray(result?.contents) ? result.contents : [],
|
|
254
|
+
};
|
|
255
|
+
});
|
|
256
|
+
server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => ({
|
|
257
|
+
resourceTemplates: [],
|
|
258
|
+
}));
|
|
180
259
|
async function handleSearchContext(args) {
|
|
181
260
|
const { space_id, query, topics } = args;
|
|
182
261
|
// Require space_id
|
|
@@ -251,18 +330,15 @@ try {
|
|
|
251
330
|
});
|
|
252
331
|
}
|
|
253
332
|
async function handleMessage(args) {
|
|
254
|
-
if (!args.
|
|
255
|
-
throw new Error("
|
|
333
|
+
if (!args.space_id || !args.content) {
|
|
334
|
+
throw new Error("space_id and content are required");
|
|
256
335
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
return makeApiCall("message",
|
|
263
|
-
...args,
|
|
264
|
-
session_id: sessionId,
|
|
265
|
-
});
|
|
336
|
+
const timeoutMs = typeof args.timeout_ms === "number" && Number.isFinite(args.timeout_ms)
|
|
337
|
+
? Math.max(10_000, Math.min(300_000, Math.trunc(args.timeout_ms)))
|
|
338
|
+
: undefined;
|
|
339
|
+
// Give backend a little extra headroom beyond requested assistant timeout.
|
|
340
|
+
const requestTimeout = timeoutMs ? timeoutMs + 10_000 : undefined;
|
|
341
|
+
return makeApiCall("message", args, requestTimeout);
|
|
266
342
|
}
|
|
267
343
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
268
344
|
const { name, arguments: args } = request.params;
|
package/dist/tool-definitions.js
CHANGED
|
@@ -311,42 +311,51 @@ export const TOOLS = [
|
|
|
311
311
|
},
|
|
312
312
|
{
|
|
313
313
|
name: "message",
|
|
314
|
-
title: "
|
|
315
|
-
description: "Send a
|
|
314
|
+
title: "Message Assistant",
|
|
315
|
+
description: "Primary orchestration tool. Send a request to the Intangle assistant and wait for one assistant turn to complete. Returns assistant text plus continuity IDs (`session_id`, `conversation_id`) so callers can continue the same thread reliably across turns.",
|
|
316
316
|
inputSchema: {
|
|
317
317
|
type: "object",
|
|
318
318
|
properties: {
|
|
319
|
-
|
|
319
|
+
space_id: {
|
|
320
320
|
type: "string",
|
|
321
|
-
|
|
322
|
-
description: "Message type. 'approval' and 'question' block until the user responds. 'notification', 'completion', and 'error' return immediately."
|
|
321
|
+
description: "Space to run the assistant turn in (use view_spaces first)."
|
|
323
322
|
},
|
|
324
323
|
content: {
|
|
325
324
|
type: "string",
|
|
326
|
-
description: "
|
|
325
|
+
description: "User message content to send to the assistant."
|
|
327
326
|
},
|
|
328
|
-
|
|
329
|
-
type: "
|
|
330
|
-
description: "Optional
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
327
|
+
provider: {
|
|
328
|
+
type: "string",
|
|
329
|
+
description: "Optional provider alias (defaults to 'tan')."
|
|
330
|
+
},
|
|
331
|
+
conversation_id: {
|
|
332
|
+
type: "string",
|
|
333
|
+
description: "Optional existing conversation/chat summary ID to resume a specific conversation. If omitted, Intangle uses/creates the active conversation for this space."
|
|
334
|
+
},
|
|
335
|
+
session_id: {
|
|
336
|
+
type: "string",
|
|
337
|
+
description: "Optional runtime session ID to reuse across calls. Reuse the returned session_id for best continuity and lower warm-up overhead."
|
|
338
|
+
},
|
|
339
|
+
project_id: {
|
|
340
|
+
type: "string",
|
|
341
|
+
description: "Optional project scope for the assistant turn."
|
|
342
|
+
},
|
|
343
|
+
organization_id: {
|
|
344
|
+
type: "string",
|
|
345
|
+
description: "Optional Clerk org ID when the space belongs to an organization graph."
|
|
346
|
+
},
|
|
347
|
+
timeout_ms: {
|
|
348
|
+
type: "integer",
|
|
349
|
+
description: "Optional timeout in milliseconds (10,000 to 300,000; default 120,000)."
|
|
350
|
+
},
|
|
351
|
+
timezone: {
|
|
352
|
+
type: "string",
|
|
353
|
+
description: "Optional IANA timezone for assistant context."
|
|
345
354
|
}
|
|
346
355
|
},
|
|
347
|
-
required: ["
|
|
356
|
+
required: ["space_id", "content"]
|
|
348
357
|
}
|
|
349
|
-
}
|
|
358
|
+
}
|
|
350
359
|
// DISABLED: memory_action tool is broken and causing errors.
|
|
351
360
|
// Pending OHM protocol fix. Use update_space, search, or fetch_items instead.
|
|
352
361
|
// {
|
package/index.ts
CHANGED
|
@@ -12,8 +12,11 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
12
12
|
import {
|
|
13
13
|
CallToolRequestSchema,
|
|
14
14
|
ErrorCode,
|
|
15
|
+
ListResourceTemplatesRequestSchema,
|
|
16
|
+
ListResourcesRequestSchema,
|
|
15
17
|
ListToolsRequestSchema,
|
|
16
18
|
McpError,
|
|
19
|
+
ReadResourceRequestSchema,
|
|
17
20
|
} from "@modelcontextprotocol/sdk/types.js"
|
|
18
21
|
import { config } from "dotenv"
|
|
19
22
|
import fetch from "node-fetch"
|
|
@@ -134,6 +137,16 @@ try {
|
|
|
134
137
|
return url.toString()
|
|
135
138
|
}
|
|
136
139
|
|
|
140
|
+
function buildRemoteApiUrl() {
|
|
141
|
+
const url = new URL("/api/mcp-remote", API_BASE_URL)
|
|
142
|
+
|
|
143
|
+
if (VERCEL_BYPASS_TOKEN) {
|
|
144
|
+
url.searchParams.set("x-vercel-protection-bypass", VERCEL_BYPASS_TOKEN)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return url.toString()
|
|
148
|
+
}
|
|
149
|
+
|
|
137
150
|
async function makeApiCall(endpoint: string, data: any, timeoutMs?: number) {
|
|
138
151
|
// Ensure we have client info before making requests
|
|
139
152
|
ensureClientInfo()
|
|
@@ -187,7 +200,9 @@ try {
|
|
|
187
200
|
)
|
|
188
201
|
}
|
|
189
202
|
|
|
190
|
-
throw new Error(
|
|
203
|
+
throw new Error(
|
|
204
|
+
`API call failed: ${response.status} ${response.statusText}`
|
|
205
|
+
)
|
|
191
206
|
}
|
|
192
207
|
|
|
193
208
|
if (responseBody.trim() === "") {
|
|
@@ -207,6 +222,70 @@ try {
|
|
|
207
222
|
}
|
|
208
223
|
}
|
|
209
224
|
|
|
225
|
+
async function makeRemoteRpcCall(
|
|
226
|
+
method: string,
|
|
227
|
+
params: Record<string, unknown>
|
|
228
|
+
) {
|
|
229
|
+
ensureClientInfo()
|
|
230
|
+
|
|
231
|
+
const headers: Record<string, string> = {
|
|
232
|
+
"Content-Type": "application/json",
|
|
233
|
+
Authorization: `Bearer ${MCP_API_KEY}`,
|
|
234
|
+
"User-Agent": mcpClientName
|
|
235
|
+
? `${mcpClientName}/${mcpClientVersion || "unknown"} (mcp-stdio)`
|
|
236
|
+
: "MCP-Client-Stdio/1.1.2 (mcp)",
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (mcpClientName) {
|
|
240
|
+
headers["X-MCP-Client-Name"] = mcpClientName
|
|
241
|
+
}
|
|
242
|
+
if (mcpClientVersion) {
|
|
243
|
+
headers["X-MCP-Client-Version"] = mcpClientVersion
|
|
244
|
+
}
|
|
245
|
+
if (VERCEL_BYPASS_TOKEN) {
|
|
246
|
+
headers["x-vercel-protection-bypass"] = VERCEL_BYPASS_TOKEN
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const requestId = Date.now()
|
|
250
|
+
const rpcBody = {
|
|
251
|
+
jsonrpc: "2.0",
|
|
252
|
+
id: requestId,
|
|
253
|
+
method,
|
|
254
|
+
params,
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const response = await fetch(buildRemoteApiUrl(), {
|
|
258
|
+
method: "POST",
|
|
259
|
+
headers,
|
|
260
|
+
body: JSON.stringify(rpcBody),
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
const responseText = await response.text()
|
|
264
|
+
let responseJson: any = {}
|
|
265
|
+
|
|
266
|
+
try {
|
|
267
|
+
responseJson = responseText ? JSON.parse(responseText) : {}
|
|
268
|
+
} catch {
|
|
269
|
+
throw new Error(`Failed to parse MCP remote ${method} response`)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (!response.ok) {
|
|
273
|
+
const message =
|
|
274
|
+
responseJson?.error?.message ||
|
|
275
|
+
responseJson?.message ||
|
|
276
|
+
`${response.status} ${response.statusText}`
|
|
277
|
+
throw new Error(`MCP remote ${method} failed: ${message}`)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (responseJson?.error) {
|
|
281
|
+
const code = responseJson.error.code
|
|
282
|
+
const message = responseJson.error.message || "Unknown MCP remote error"
|
|
283
|
+
throw new Error(`MCP remote ${method} error (${code}): ${message}`)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return responseJson?.result ?? {}
|
|
287
|
+
}
|
|
288
|
+
|
|
210
289
|
const server = new Server(
|
|
211
290
|
{
|
|
212
291
|
name: "intangle-context",
|
|
@@ -220,6 +299,7 @@ try {
|
|
|
220
299
|
},
|
|
221
300
|
{
|
|
222
301
|
capabilities: {
|
|
302
|
+
resources: {},
|
|
223
303
|
tools: {},
|
|
224
304
|
},
|
|
225
305
|
}
|
|
@@ -229,6 +309,34 @@ try {
|
|
|
229
309
|
tools: TOOLS,
|
|
230
310
|
}))
|
|
231
311
|
|
|
312
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
313
|
+
const result = await makeRemoteRpcCall("resources/list", {})
|
|
314
|
+
return {
|
|
315
|
+
resources: Array.isArray(result?.resources) ? result.resources : [],
|
|
316
|
+
nextCursor:
|
|
317
|
+
typeof result?.nextCursor === "string" ? result.nextCursor : undefined,
|
|
318
|
+
}
|
|
319
|
+
})
|
|
320
|
+
|
|
321
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request: any) => {
|
|
322
|
+
const uri = request?.params?.uri
|
|
323
|
+
if (!uri || typeof uri !== "string") {
|
|
324
|
+
throw new McpError(
|
|
325
|
+
ErrorCode.InvalidParams,
|
|
326
|
+
"uri is required for resources/read"
|
|
327
|
+
)
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const result = await makeRemoteRpcCall("resources/read", { uri })
|
|
331
|
+
return {
|
|
332
|
+
contents: Array.isArray(result?.contents) ? result.contents : [],
|
|
333
|
+
}
|
|
334
|
+
})
|
|
335
|
+
|
|
336
|
+
server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => ({
|
|
337
|
+
resourceTemplates: [],
|
|
338
|
+
}))
|
|
339
|
+
|
|
232
340
|
async function handleSearchContext(args: any) {
|
|
233
341
|
const { space_id, query, topics } = args as {
|
|
234
342
|
space_id: string
|
|
@@ -278,11 +386,15 @@ try {
|
|
|
278
386
|
}
|
|
279
387
|
|
|
280
388
|
if (!project_id && !slug) {
|
|
281
|
-
throw new Error(
|
|
389
|
+
throw new Error(
|
|
390
|
+
"Either project_id or slug (with space_id) is required. Use view_projects to get valid IDs."
|
|
391
|
+
)
|
|
282
392
|
}
|
|
283
393
|
|
|
284
394
|
if (slug && !space_id) {
|
|
285
|
-
throw new Error(
|
|
395
|
+
throw new Error(
|
|
396
|
+
"space_id is required when using slug. Use view_spaces to see available options."
|
|
397
|
+
)
|
|
286
398
|
}
|
|
287
399
|
|
|
288
400
|
return makeApiCall("view-project", { project_id, space_id, slug })
|
|
@@ -310,9 +422,7 @@ try {
|
|
|
310
422
|
}
|
|
311
423
|
|
|
312
424
|
if (!args.add && !args.update && !args.delete) {
|
|
313
|
-
throw new Error(
|
|
314
|
-
"At least one operation must be provided"
|
|
315
|
-
)
|
|
425
|
+
throw new Error("At least one operation must be provided")
|
|
316
426
|
}
|
|
317
427
|
|
|
318
428
|
// Ensure all add items have a type field to prevent classification timeout
|
|
@@ -320,7 +430,9 @@ try {
|
|
|
320
430
|
if (add?.items && Array.isArray(add.items)) {
|
|
321
431
|
for (const item of add.items) {
|
|
322
432
|
if (!item.type) {
|
|
323
|
-
log(
|
|
433
|
+
log(
|
|
434
|
+
`WARNING: Item "${item.title}" missing type field, defaulting to "context" to prevent classification timeout`
|
|
435
|
+
)
|
|
324
436
|
item.type = "context"
|
|
325
437
|
}
|
|
326
438
|
}
|
|
@@ -337,22 +449,19 @@ try {
|
|
|
337
449
|
}
|
|
338
450
|
|
|
339
451
|
async function handleMessage(args: any) {
|
|
340
|
-
if (!args.
|
|
341
|
-
throw new Error("
|
|
452
|
+
if (!args.space_id || !args.content) {
|
|
453
|
+
throw new Error("space_id and content are required")
|
|
342
454
|
}
|
|
343
455
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
"INTANGLE_SESSION_ID environment variable is required for the message tool"
|
|
349
|
-
)
|
|
350
|
-
}
|
|
456
|
+
const timeoutMs =
|
|
457
|
+
typeof args.timeout_ms === "number" && Number.isFinite(args.timeout_ms)
|
|
458
|
+
? Math.max(10_000, Math.min(300_000, Math.trunc(args.timeout_ms)))
|
|
459
|
+
: undefined
|
|
351
460
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
461
|
+
// Give backend a little extra headroom beyond requested assistant timeout.
|
|
462
|
+
const requestTimeout = timeoutMs ? timeoutMs + 10_000 : undefined
|
|
463
|
+
|
|
464
|
+
return makeApiCall("message", args, requestTimeout)
|
|
356
465
|
}
|
|
357
466
|
|
|
358
467
|
server.setRequestHandler(CallToolRequestSchema, async (request: any) => {
|
package/package.json
CHANGED
|
@@ -1,53 +1,53 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
2
|
+
"name": "@intangle/mcp-server",
|
|
3
|
+
"version": "2.5.5",
|
|
4
|
+
"description": "Model Context Protocol server for Intangle - AI context that persists across conversations",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"start": "node dist/index.js",
|
|
9
|
+
"dev": "tsx watch index.ts",
|
|
10
|
+
"prebuild": "cp ../web/src/app/api/mcp-remote/tool-definitions.ts ./tool-definitions.ts",
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"lint": "biome check .",
|
|
13
|
+
"lint:fix": "biome check --fix .",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"bin": {
|
|
17
|
+
"intangle-mcp": "dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mcp",
|
|
21
|
+
"model-context-protocol",
|
|
22
|
+
"claude",
|
|
23
|
+
"claude-code",
|
|
24
|
+
"ai",
|
|
25
|
+
"context",
|
|
26
|
+
"knowledge-management",
|
|
27
|
+
"intangle",
|
|
28
|
+
"claude-desktop",
|
|
29
|
+
"anthropic"
|
|
30
|
+
],
|
|
31
|
+
"author": "Intangle",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/intangle/mcp-server.git"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://intangle.app",
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18.0.0"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
43
|
+
"dotenv": "^17.2.0",
|
|
44
|
+
"node-fetch": "^3.3.2"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@biomejs/biome": "^1.9.4",
|
|
48
|
+
"@types/node": "^22.0.0",
|
|
49
|
+
"@types/node-fetch": "^2.6.12",
|
|
50
|
+
"tsx": "^4.0.0",
|
|
51
|
+
"typescript": "^5.0.0"
|
|
52
|
+
}
|
|
53
53
|
}
|
package/tool-definitions.ts
CHANGED
|
@@ -344,44 +344,57 @@ export const TOOLS = [
|
|
|
344
344
|
},
|
|
345
345
|
{
|
|
346
346
|
name: "message",
|
|
347
|
-
title: "
|
|
347
|
+
title: "Message Assistant",
|
|
348
348
|
description:
|
|
349
|
-
"Send a
|
|
349
|
+
"Primary orchestration tool. Send a request to the Intangle assistant and wait for one assistant turn to complete. Returns assistant text plus continuity IDs (`session_id`, `conversation_id`) so callers can continue the same thread reliably across turns.",
|
|
350
350
|
inputSchema: {
|
|
351
351
|
type: "object",
|
|
352
352
|
properties: {
|
|
353
|
-
|
|
353
|
+
space_id: {
|
|
354
354
|
type: "string",
|
|
355
|
-
enum: ["approval", "question", "notification", "completion", "error"],
|
|
356
355
|
description:
|
|
357
|
-
"
|
|
356
|
+
"Space to run the assistant turn in (use view_spaces first)."
|
|
358
357
|
},
|
|
359
358
|
content: {
|
|
360
359
|
type: "string",
|
|
361
|
-
description: "
|
|
360
|
+
description: "User message content to send to the assistant."
|
|
362
361
|
},
|
|
363
|
-
|
|
364
|
-
type: "
|
|
365
|
-
description: "Optional
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
362
|
+
provider: {
|
|
363
|
+
type: "string",
|
|
364
|
+
description: "Optional provider alias (defaults to 'tan')."
|
|
365
|
+
},
|
|
366
|
+
conversation_id: {
|
|
367
|
+
type: "string",
|
|
368
|
+
description:
|
|
369
|
+
"Optional existing conversation/chat summary ID to resume a specific conversation. If omitted, Intangle uses/creates the active conversation for this space."
|
|
370
|
+
},
|
|
371
|
+
session_id: {
|
|
372
|
+
type: "string",
|
|
373
|
+
description:
|
|
374
|
+
"Optional runtime session ID to reuse across calls. Reuse the returned session_id for best continuity and lower warm-up overhead."
|
|
375
|
+
},
|
|
376
|
+
project_id: {
|
|
377
|
+
type: "string",
|
|
378
|
+
description: "Optional project scope for the assistant turn."
|
|
379
|
+
},
|
|
380
|
+
organization_id: {
|
|
381
|
+
type: "string",
|
|
382
|
+
description:
|
|
383
|
+
"Optional Clerk org ID when the space belongs to an organization graph."
|
|
384
|
+
},
|
|
385
|
+
timeout_ms: {
|
|
386
|
+
type: "integer",
|
|
387
|
+
description:
|
|
388
|
+
"Optional timeout in milliseconds (10,000 to 300,000; default 120,000)."
|
|
389
|
+
},
|
|
390
|
+
timezone: {
|
|
391
|
+
type: "string",
|
|
392
|
+
description: "Optional IANA timezone for assistant context."
|
|
380
393
|
}
|
|
381
394
|
},
|
|
382
|
-
required: ["
|
|
395
|
+
required: ["space_id", "content"]
|
|
383
396
|
}
|
|
384
|
-
}
|
|
397
|
+
}
|
|
385
398
|
// DISABLED: memory_action tool is broken and causing errors.
|
|
386
399
|
// Pending OHM protocol fix. Use update_space, search, or fetch_items instead.
|
|
387
400
|
// {
|