@attrove/mcp 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +101 -3
- package/cjs/index.js +6 -1
- package/cjs/server.js +115 -56
- package/cjs/tools/events.js +134 -0
- package/cjs/tools/index.js +9 -1
- package/cjs/tools/integrations.js +11 -4
- package/cjs/tools/meetings.js +149 -0
- package/cjs/tools/query.js +12 -5
- package/cjs/tools/search.js +21 -7
- package/cjs/transport/http.js +192 -0
- package/esm/index.d.ts +3 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +3 -1
- package/esm/index.js.map +1 -1
- package/esm/server.d.ts +7 -5
- package/esm/server.d.ts.map +1 -1
- package/esm/server.js +116 -57
- package/esm/server.js.map +1 -1
- package/esm/tools/events.d.ts +24 -0
- package/esm/tools/events.d.ts.map +1 -0
- package/esm/tools/events.js +131 -0
- package/esm/tools/events.js.map +1 -0
- package/esm/tools/index.d.ts +6 -69
- package/esm/tools/index.d.ts.map +1 -1
- package/esm/tools/index.js +5 -2
- package/esm/tools/index.js.map +1 -1
- package/esm/tools/integrations.d.ts +3 -10
- package/esm/tools/integrations.d.ts.map +1 -1
- package/esm/tools/integrations.js +11 -4
- package/esm/tools/integrations.js.map +1 -1
- package/esm/tools/meetings.d.ts +26 -0
- package/esm/tools/meetings.d.ts.map +1 -0
- package/esm/tools/meetings.js +146 -0
- package/esm/tools/meetings.js.map +1 -0
- package/esm/tools/query.d.ts +3 -27
- package/esm/tools/query.d.ts.map +1 -1
- package/esm/tools/query.js +12 -5
- package/esm/tools/query.js.map +1 -1
- package/esm/tools/search.d.ts +3 -35
- package/esm/tools/search.d.ts.map +1 -1
- package/esm/tools/search.js +21 -7
- package/esm/tools/search.js.map +1 -1
- package/esm/transport/http.d.ts +63 -0
- package/esm/transport/http.d.ts.map +1 -0
- package/esm/transport/http.js +189 -0
- package/esm/transport/http.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Transport for Attrove MCP Server
|
|
3
|
+
*
|
|
4
|
+
* Provides HTTP-based transport for the MCP server, enabling AI assistants
|
|
5
|
+
* like ChatGPT to connect via HTTP endpoints instead of stdio.
|
|
6
|
+
*/
|
|
7
|
+
import { randomUUID } from "node:crypto";
|
|
8
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
9
|
+
import { createServer } from "../server.js";
|
|
10
|
+
/**
|
|
11
|
+
* Create an HTTP request handler for the MCP server.
|
|
12
|
+
*
|
|
13
|
+
* Each call to handleRequest creates new server and transport instances,
|
|
14
|
+
* providing complete isolation between requests. Callers should create
|
|
15
|
+
* a new handler when the config (API key/user ID) changes.
|
|
16
|
+
*
|
|
17
|
+
* @param config - MCP server configuration with API key and user ID
|
|
18
|
+
* @param options - Optional handler configuration
|
|
19
|
+
* @returns Object with handleRequest method for processing HTTP requests
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* // In a Fastify route handler
|
|
24
|
+
* const handler = createHttpHandler({
|
|
25
|
+
* apiKey: 'sk_...',
|
|
26
|
+
* userId: 'user-uuid',
|
|
27
|
+
* baseUrl: 'https://api.attrove.com', // optional, SDK has its own default
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* // Handle POST request
|
|
31
|
+
* const result = await handler.handleRequest(req.raw, reply.raw, req.body);
|
|
32
|
+
* if (!result.handled) {
|
|
33
|
+
* // No response sent - caller must send error response
|
|
34
|
+
* res.status(500).json({ error: result.error });
|
|
35
|
+
* }
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
/**
|
|
39
|
+
* Type guard for Node.js system errors with error codes.
|
|
40
|
+
*/
|
|
41
|
+
function isNodeError(error) {
|
|
42
|
+
return error instanceof Error && "code" in error;
|
|
43
|
+
}
|
|
44
|
+
export function createHttpHandler(config, options = {}) {
|
|
45
|
+
const { enableJsonResponse = true, timeoutMs = 30000 } = options;
|
|
46
|
+
// Validate timeoutMs to prevent unexpected behavior
|
|
47
|
+
if (timeoutMs <= 0) {
|
|
48
|
+
throw new Error("timeoutMs must be a positive number");
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
/**
|
|
52
|
+
* Handle an incoming HTTP request.
|
|
53
|
+
*
|
|
54
|
+
* @param req - Node.js IncomingMessage (or Fastify raw request)
|
|
55
|
+
* @param res - Node.js ServerResponse (or Fastify raw reply)
|
|
56
|
+
* @param parsedBody - Pre-parsed request body (optional, Fastify provides this)
|
|
57
|
+
* @returns Promise resolving to handler result indicating if request was processed
|
|
58
|
+
*/
|
|
59
|
+
handleRequest: async (req, res, parsedBody) => {
|
|
60
|
+
let server;
|
|
61
|
+
let timeoutId;
|
|
62
|
+
let result;
|
|
63
|
+
let cleanupFailed = false;
|
|
64
|
+
let timeoutOccurred = false;
|
|
65
|
+
// Correlation ID links timeout errors with subsequent suppressed errors for debugging
|
|
66
|
+
const correlationId = randomUUID().slice(0, 8);
|
|
67
|
+
try {
|
|
68
|
+
server = createServer(config);
|
|
69
|
+
const transport = new StreamableHTTPServerTransport({
|
|
70
|
+
sessionIdGenerator: undefined, // Stateless mode - no session tracking needed
|
|
71
|
+
enableJsonResponse,
|
|
72
|
+
});
|
|
73
|
+
await server.connect(transport);
|
|
74
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
75
|
+
timeoutId = setTimeout(() => {
|
|
76
|
+
timeoutOccurred = true;
|
|
77
|
+
reject(new Error(`MCP request timed out after ${timeoutMs}ms`));
|
|
78
|
+
}, timeoutMs);
|
|
79
|
+
});
|
|
80
|
+
// Store reference to transport promise so we can attach a catch handler.
|
|
81
|
+
// This prevents unhandled rejection if timeout wins the race and server.close()
|
|
82
|
+
// later causes the transport to reject.
|
|
83
|
+
const transportPromise = transport.handleRequest(req, res, parsedBody);
|
|
84
|
+
// When timeout occurs, Promise.race exits with the timeout error (caught below),
|
|
85
|
+
// but transportPromise may reject later when server.close() interrupts it.
|
|
86
|
+
// Only log here if a timeout actually occurred - otherwise Promise.race will
|
|
87
|
+
// propagate the rejection to the main catch block and logging here would be duplicate.
|
|
88
|
+
transportPromise.catch((suppressedError) => {
|
|
89
|
+
if (!timeoutOccurred) {
|
|
90
|
+
// No timeout - Promise.race will handle this rejection via the main catch block
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const errorMsg = suppressedError instanceof Error
|
|
94
|
+
? suppressedError.message
|
|
95
|
+
: String(suppressedError);
|
|
96
|
+
// Critical errors that indicate systemic issues (not just slow requests)
|
|
97
|
+
const isCritical = /SSL|certificate|ENOTFOUND|ECONNREFUSED|auth/i.test(errorMsg);
|
|
98
|
+
const logData = {
|
|
99
|
+
level: isCritical ? "error" : "warn",
|
|
100
|
+
msg: "MCP transport rejected after timeout - suppressed to prevent unhandled rejection",
|
|
101
|
+
errorId: isCritical
|
|
102
|
+
? "MCP_HTTP_SUPPRESSED_CRITICAL_ERROR"
|
|
103
|
+
: "MCP_HTTP_SUPPRESSED_POST_TIMEOUT",
|
|
104
|
+
correlationId,
|
|
105
|
+
error: errorMsg,
|
|
106
|
+
userId: config.userId,
|
|
107
|
+
};
|
|
108
|
+
// prettier-ignore
|
|
109
|
+
console.error("[AttroveMCP]", JSON.stringify(logData));
|
|
110
|
+
});
|
|
111
|
+
await Promise.race([transportPromise, timeoutPromise]);
|
|
112
|
+
result = { handled: true };
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
// Preserve context for non-Error values (e.g., throw "string", throw { code: ... })
|
|
116
|
+
const message = error instanceof Error
|
|
117
|
+
? error.message
|
|
118
|
+
: typeof error === "object" && error !== null
|
|
119
|
+
? `Unknown error: ${JSON.stringify(error)}`
|
|
120
|
+
: `Unknown error: ${String(error)}`;
|
|
121
|
+
const stack = error instanceof Error ? error.stack : undefined;
|
|
122
|
+
const isTimeout = error instanceof Error && error.message.includes("timed out");
|
|
123
|
+
// Classify error type for appropriate logging level
|
|
124
|
+
// Use error.code for socket errors (more precise than string matching)
|
|
125
|
+
const isSocketError = isNodeError(error) &&
|
|
126
|
+
(error.code === "ECONNRESET" ||
|
|
127
|
+
error.code === "EPIPE" ||
|
|
128
|
+
error.code === "ECONNABORTED");
|
|
129
|
+
const isExpectedError = isTimeout || isSocketError;
|
|
130
|
+
// Log with structured JSON for observability (callers should also log via their infrastructure)
|
|
131
|
+
const errorId = isTimeout
|
|
132
|
+
? "MCP_HTTP_TIMEOUT"
|
|
133
|
+
: isSocketError
|
|
134
|
+
? "MCP_HTTP_SOCKET_ERROR"
|
|
135
|
+
: "MCP_HTTP_UNEXPECTED_ERROR";
|
|
136
|
+
const logData = {
|
|
137
|
+
level: isExpectedError ? "warn" : "error",
|
|
138
|
+
msg: isExpectedError
|
|
139
|
+
? "MCP HTTP handler operational failure"
|
|
140
|
+
: "MCP HTTP handler unexpected failure",
|
|
141
|
+
errorId,
|
|
142
|
+
correlationId,
|
|
143
|
+
error: message,
|
|
144
|
+
isTimeout,
|
|
145
|
+
userId: config.userId,
|
|
146
|
+
...(stack && !isExpectedError && { stack }),
|
|
147
|
+
...(!isExpectedError && { errorType: error?.constructor?.name }),
|
|
148
|
+
};
|
|
149
|
+
// prettier-ignore
|
|
150
|
+
console.error("[AttroveMCP]", JSON.stringify(logData));
|
|
151
|
+
result = { handled: false, error: message, stack, isTimeout };
|
|
152
|
+
}
|
|
153
|
+
finally {
|
|
154
|
+
// Clear timeout to prevent timer accumulation under load
|
|
155
|
+
if (timeoutId !== undefined) {
|
|
156
|
+
clearTimeout(timeoutId);
|
|
157
|
+
}
|
|
158
|
+
if (server) {
|
|
159
|
+
try {
|
|
160
|
+
await server.close();
|
|
161
|
+
}
|
|
162
|
+
catch (cleanupError) {
|
|
163
|
+
cleanupFailed = true;
|
|
164
|
+
// Cleanup failures could indicate resource leaks - always log for monitoring
|
|
165
|
+
const cleanupLogData = {
|
|
166
|
+
level: "error",
|
|
167
|
+
msg: "MCP server cleanup failed - potential resource leak",
|
|
168
|
+
errorId: "MCP_CLEANUP_FAILURE",
|
|
169
|
+
correlationId,
|
|
170
|
+
error: cleanupError instanceof Error
|
|
171
|
+
? cleanupError.message
|
|
172
|
+
: String(cleanupError),
|
|
173
|
+
stack: cleanupError instanceof Error ? cleanupError.stack : undefined,
|
|
174
|
+
userId: config.userId,
|
|
175
|
+
};
|
|
176
|
+
// prettier-ignore
|
|
177
|
+
console.error("[AttroveMCP]", JSON.stringify(cleanupLogData));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Include cleanup failure warning in success result for monitoring
|
|
182
|
+
if (result.handled && cleanupFailed) {
|
|
183
|
+
return { handled: true, cleanupFailed: true };
|
|
184
|
+
}
|
|
185
|
+
return result;
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../../../packages/mcp/src/transport/http.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@attrove/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "MCP server for Attrove - AI-powered context retrieval for Claude and Cursor",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./cjs/index.js",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
61
|
-
"@attrove/sdk": "0.1.
|
|
61
|
+
"@attrove/sdk": "0.1.8",
|
|
62
62
|
"tslib": "^2.6.0"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|