@meetbot/mcp 1.1.1 → 1.2.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/cli-http.js +11 -21
- package/dist/cli-http.js.map +1 -1
- package/dist/cli-streamable.d.ts +3 -0
- package/dist/cli-streamable.d.ts.map +1 -0
- package/dist/cli-streamable.js +36 -0
- package/dist/cli-streamable.js.map +1 -0
- package/dist/in-memory-event-store.d.ts +14 -0
- package/dist/in-memory-event-store.d.ts.map +1 -0
- package/dist/in-memory-event-store.js +33 -0
- package/dist/in-memory-event-store.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-server-streamable.d.ts +16 -0
- package/dist/mcp-server-streamable.d.ts.map +1 -0
- package/dist/mcp-server-streamable.js +347 -0
- package/dist/mcp-server-streamable.js.map +1 -0
- package/package.json +11 -7
- package/dist/mcp-server-http.d.ts +0 -26
- package/dist/mcp-server-http.d.ts.map +0 -1
- package/dist/mcp-server-http.js +0 -346
- package/dist/mcp-server-http.js.map +0 -1
package/dist/cli-http.js
CHANGED
|
@@ -1,29 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createServer } from 'http';
|
|
3
|
-
import {
|
|
3
|
+
import { MeetbotMCPStreamable } from './mcp-server-streamable.js';
|
|
4
4
|
const PORT = parseInt(process.env['PORT'] || '3000', 10);
|
|
5
5
|
async function main() {
|
|
6
|
-
const mcpServer = new
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
await mcpServer.handleRequest(req, res);
|
|
10
|
-
}
|
|
11
|
-
catch (error) {
|
|
12
|
-
console.error('Request handling error:', error);
|
|
13
|
-
if (!res.headersSent) {
|
|
14
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
15
|
-
res.end(JSON.stringify({
|
|
16
|
-
error: 'Internal server error',
|
|
17
|
-
message: error instanceof Error ? error.message : 'Unknown error',
|
|
18
|
-
}));
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
});
|
|
6
|
+
const mcpServer = new MeetbotMCPStreamable();
|
|
7
|
+
const app = mcpServer.createApp();
|
|
8
|
+
const httpServer = createServer(app);
|
|
22
9
|
httpServer.listen(PORT, () => {
|
|
23
|
-
console.log(`Meet.bot MCP HTTP server listening on port ${PORT}`);
|
|
24
|
-
console.log(
|
|
25
|
-
console.log(`
|
|
26
|
-
console.log(
|
|
10
|
+
console.log(`Meet.bot MCP Streamable HTTP server listening on port ${PORT}`);
|
|
11
|
+
console.log(`\nEndpoints:`);
|
|
12
|
+
console.log(` POST / → MCP client-to-server messages`);
|
|
13
|
+
console.log(` GET / → MCP server-to-client SSE stream`);
|
|
14
|
+
console.log(` DELETE / → Terminate session`);
|
|
15
|
+
console.log(` GET /health → Health check`);
|
|
16
|
+
console.log(`\nAuthentication: Use configure_meetbot tool with your API token`);
|
|
27
17
|
});
|
|
28
18
|
// Graceful shutdown
|
|
29
19
|
process.on('SIGINT', () => {
|
package/dist/cli-http.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-http.js","sourceRoot":"","sources":["../src/cli-http.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"cli-http.js","sourceRoot":"","sources":["../src/cli-http.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAElE,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAEzD,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,GAAG,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC;IAElC,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAErC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;QAC3B,OAAO,CAAC,GAAG,CAAC,yDAAyD,IAAI,EAAE,CAAC,CAAC;QAC7E,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;QACjE,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAC;IAClF,CAAC,CAAC,CAAC;IAEH,oBAAoB;IACpB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC7C,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE;YACpB,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QACzB,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC7C,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE;YACpB,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;IACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-streamable.d.ts","sourceRoot":"","sources":["../src/cli-streamable.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { MeetbotMCPStreamable } from './mcp-server-streamable.js';
|
|
3
|
+
const PORT = parseInt(process.env['PORT'] || '3000', 10);
|
|
4
|
+
async function main() {
|
|
5
|
+
const mcpServer = new MeetbotMCPStreamable();
|
|
6
|
+
const app = mcpServer.createApp();
|
|
7
|
+
const server = app.listen(PORT, () => {
|
|
8
|
+
console.log(`Meet.bot MCP Streamable HTTP server listening on port ${PORT}`);
|
|
9
|
+
console.log(`\nEndpoints:`);
|
|
10
|
+
console.log(` POST / → MCP client-to-server messages`);
|
|
11
|
+
console.log(` GET / → MCP server-to-client SSE stream`);
|
|
12
|
+
console.log(` DELETE / → Terminate session`);
|
|
13
|
+
console.log(` GET /health → Health check`);
|
|
14
|
+
console.log(`\nAuthentication: Use configure_meetbot tool with your API token`);
|
|
15
|
+
});
|
|
16
|
+
// Graceful shutdown
|
|
17
|
+
process.on('SIGINT', () => {
|
|
18
|
+
console.log('\nShutting down MCP server...');
|
|
19
|
+
server.close(() => {
|
|
20
|
+
console.log('Server closed');
|
|
21
|
+
process.exit(0);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
process.on('SIGTERM', () => {
|
|
25
|
+
console.log('\nShutting down MCP server...');
|
|
26
|
+
server.close(() => {
|
|
27
|
+
console.log('Server closed');
|
|
28
|
+
process.exit(0);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
main().catch((error) => {
|
|
33
|
+
console.error('Failed to start MCP server:', error);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=cli-streamable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-streamable.js","sourceRoot":"","sources":["../src/cli-streamable.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAElE,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAEzD,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,GAAG,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC;IAElC,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;QACnC,OAAO,CAAC,GAAG,CAAC,yDAAyD,IAAI,EAAE,CAAC,CAAC;QAC7E,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;QACjE,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAC;IAClF,CAAC,CAAC,CAAC;IAEH,oBAAoB;IACpB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE;YAChB,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QACzB,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE;YAChB,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;IACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { EventStore, StreamId, EventId } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
2
|
+
import type { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Simple in-memory event store for MCP session resumability
|
|
5
|
+
*/
|
|
6
|
+
export declare class InMemoryEventStore implements EventStore {
|
|
7
|
+
private events;
|
|
8
|
+
storeEvent(streamId: StreamId, message: JSONRPCMessage): Promise<EventId>;
|
|
9
|
+
replayEventsAfter(lastEventId: EventId, { send }: {
|
|
10
|
+
send: (eventId: EventId, message: JSONRPCMessage) => Promise<void>;
|
|
11
|
+
}): Promise<StreamId>;
|
|
12
|
+
clearSession(streamId: StreamId): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=in-memory-event-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-event-store.d.ts","sourceRoot":"","sources":["../src/in-memory-event-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,oDAAoD,CAAC;AACxG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE;;GAEG;AACH,qBAAa,kBAAmB,YAAW,UAAU;IACnD,OAAO,CAAC,MAAM,CAA6E;IAErF,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IASzE,iBAAiB,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE;QACtD,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACpE,GAAG,OAAO,CAAC,QAAQ,CAAC;IAgBf,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAGtD"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple in-memory event store for MCP session resumability
|
|
3
|
+
*/
|
|
4
|
+
export class InMemoryEventStore {
|
|
5
|
+
events = new Map();
|
|
6
|
+
async storeEvent(streamId, message) {
|
|
7
|
+
if (!this.events.has(streamId)) {
|
|
8
|
+
this.events.set(streamId, []);
|
|
9
|
+
}
|
|
10
|
+
const eventId = `event_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
11
|
+
this.events.get(streamId).push({ id: eventId, message });
|
|
12
|
+
return eventId;
|
|
13
|
+
}
|
|
14
|
+
async replayEventsAfter(lastEventId, { send }) {
|
|
15
|
+
// Find the stream that contains the lastEventId
|
|
16
|
+
for (const [streamId, events] of this.events.entries()) {
|
|
17
|
+
const eventIndex = events.findIndex(event => event.id === lastEventId);
|
|
18
|
+
if (eventIndex >= 0) {
|
|
19
|
+
// Replay events after the lastEventId
|
|
20
|
+
const eventsToReplay = events.slice(eventIndex + 1);
|
|
21
|
+
for (const event of eventsToReplay) {
|
|
22
|
+
await send(event.id, event.message);
|
|
23
|
+
}
|
|
24
|
+
return streamId;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
throw new Error(`Event ID ${lastEventId} not found`);
|
|
28
|
+
}
|
|
29
|
+
async clearSession(streamId) {
|
|
30
|
+
this.events.delete(streamId);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=in-memory-event-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-event-store.js","sourceRoot":"","sources":["../src/in-memory-event-store.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,OAAO,kBAAkB;IACrB,MAAM,GAAmE,IAAI,GAAG,EAAE,CAAC;IAE3F,KAAK,CAAC,UAAU,CAAC,QAAkB,EAAE,OAAuB;QAC1D,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAChC,CAAC;QACD,MAAM,OAAO,GAAG,SAAS,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACjF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC1D,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,WAAoB,EAAE,EAAE,IAAI,EAEnD;QACC,gDAAgD;QAChD,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;YACvD,MAAM,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,WAAW,CAAC,CAAC;YACvE,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;gBACpB,sCAAsC;gBACtC,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;gBACpD,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;oBACnC,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;gBACtC,CAAC;gBACD,OAAO,QAAQ,CAAC;YAClB,CAAC;QACH,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,YAAY,WAAW,YAAY,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,QAAkB;QACnC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;CACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Model Context Protocol server for Meet.bot Booking Page API
|
|
4
4
|
*/
|
|
5
5
|
export { MeetbotMCPServer } from './mcp-server.js';
|
|
6
|
-
export { MeetbotMCPServerHTTP } from './mcp-server-
|
|
6
|
+
export { MeetbotMCPStreamable as MeetbotMCPServerHTTP } from './mcp-server-streamable.js';
|
|
7
7
|
export { MeetbotClient } from './meetbot-client.js';
|
|
8
8
|
export type { BookSlot, BookSlotRequest, GetSlotsParams, GetInfoParams, PageInfo, Pages, SchedulingPage, Slots, SlotDetails, MeetbotConfig, ApiError, ApiResponse, } from './types.js';
|
|
9
9
|
export { BookSlotSchema, BookSlotRequestSchema, GetSlotsParamsSchema, GetInfoParamsSchema, PageInfoSchema, PagesSchema, SchedulingPageSchema, SlotsSchema, SlotDetailsSchema, MeetbotConfigSchema, ApiErrorSchema, } from './schemas.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,oBAAoB,IAAI,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,YAAY,EACV,QAAQ,EACR,eAAe,EACf,cAAc,EACd,aAAa,EACb,QAAQ,EACR,KAAK,EACL,cAAc,EACd,KAAK,EACL,WAAW,EACX,aAAa,EACb,QAAQ,EACR,WAAW,GACZ,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACd,WAAW,EACX,oBAAoB,EACpB,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,GACf,MAAM,cAAc,CAAC;AAGtB,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,cAAc,EACd,cAAc,EACd,wBAAwB,EACxB,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
// Export main classes
|
|
6
6
|
export { MeetbotMCPServer } from './mcp-server.js';
|
|
7
|
-
export { MeetbotMCPServerHTTP } from './mcp-server-
|
|
7
|
+
export { MeetbotMCPStreamable as MeetbotMCPServerHTTP } from './mcp-server-streamable.js';
|
|
8
8
|
export { MeetbotClient } from './meetbot-client.js';
|
|
9
9
|
// Export schemas
|
|
10
10
|
export { BookSlotSchema, BookSlotRequestSchema, GetSlotsParamsSchema, GetInfoParamsSchema, PageInfoSchema, PagesSchema, SchedulingPageSchema, SlotsSchema, SlotDetailsSchema, MeetbotConfigSchema, ApiErrorSchema, } from './schemas.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,sBAAsB;AACtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,sBAAsB;AACtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,oBAAoB,IAAI,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAkBpD,iBAAiB;AACjB,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACd,WAAW,EACX,oBAAoB,EACpB,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,GACf,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
/**
|
|
3
|
+
* Streamable HTTP MCP Server implementation
|
|
4
|
+
*/
|
|
5
|
+
export declare class MeetbotMCPStreamable {
|
|
6
|
+
private server;
|
|
7
|
+
private transports;
|
|
8
|
+
private clients;
|
|
9
|
+
constructor();
|
|
10
|
+
private setupToolHandlers;
|
|
11
|
+
/**
|
|
12
|
+
* Create Express app with MCP endpoints
|
|
13
|
+
*/
|
|
14
|
+
createApp(): express.Application;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=mcp-server-streamable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server-streamable.d.ts","sourceRoot":"","sources":["../src/mcp-server-streamable.ts"],"names":[],"mappings":"AAAA,OAAO,OAA4C,MAAM,SAAS,CAAC;AASnE;;GAEG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,UAAU,CAAyD;IAC3E,OAAO,CAAC,OAAO,CAAyC;;IAYxD,OAAO,CAAC,iBAAiB;IAyOzB;;OAEG;IACH,SAAS,IAAI,OAAO,CAAC,WAAW;CA0IjC"}
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
6
|
+
import { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';
|
|
7
|
+
import { MeetbotClient } from './meetbot-client.js';
|
|
8
|
+
import { InMemoryEventStore } from './in-memory-event-store.js';
|
|
9
|
+
/**
|
|
10
|
+
* Streamable HTTP MCP Server implementation
|
|
11
|
+
*/
|
|
12
|
+
export class MeetbotMCPStreamable {
|
|
13
|
+
server;
|
|
14
|
+
transports = new Map();
|
|
15
|
+
clients = new Map();
|
|
16
|
+
constructor() {
|
|
17
|
+
this.server = new McpServer({
|
|
18
|
+
name: 'meetbot-mcp',
|
|
19
|
+
version: '1.1.1',
|
|
20
|
+
description: 'Meet.bot MCP Server for scheduling and booking',
|
|
21
|
+
});
|
|
22
|
+
this.setupToolHandlers();
|
|
23
|
+
}
|
|
24
|
+
setupToolHandlers() {
|
|
25
|
+
// Configure Meet.bot authentication tool
|
|
26
|
+
this.server.registerTool('configure_meetbot', {
|
|
27
|
+
title: 'Configure Meet.bot Authentication',
|
|
28
|
+
description: 'Configure Meet.bot API authentication (required before using other tools)',
|
|
29
|
+
inputSchema: {
|
|
30
|
+
authToken: z.string().describe('Your Meet.bot API token'),
|
|
31
|
+
},
|
|
32
|
+
}, async ({ authToken }, extra) => {
|
|
33
|
+
console.log('🔧 Configure Meetbot called for session:', extra.sessionId);
|
|
34
|
+
console.log('🔧 Auth token provided:', authToken ? 'YES' : 'NO');
|
|
35
|
+
if (!extra.sessionId) {
|
|
36
|
+
throw new Error('Session ID is required');
|
|
37
|
+
}
|
|
38
|
+
if (!authToken) {
|
|
39
|
+
throw new Error('Auth token is required');
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const client = new MeetbotClient({ authToken });
|
|
43
|
+
this.clients.set(extra.sessionId, client);
|
|
44
|
+
console.log('🔧 Client configured successfully for session:', extra.sessionId);
|
|
45
|
+
// Test the connection
|
|
46
|
+
const isHealthy = await client.healthCheck();
|
|
47
|
+
return {
|
|
48
|
+
content: [
|
|
49
|
+
{
|
|
50
|
+
type: 'text',
|
|
51
|
+
text: isHealthy
|
|
52
|
+
? '✅ Meet.bot authentication configured successfully! You can now use all Meet.bot tools.'
|
|
53
|
+
: '⚠️ Meet.bot authentication configured, but API connection test failed. Please check your token.',
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.log('🔧 Configuration failed:', error);
|
|
60
|
+
throw new Error(`Failed to configure Meet.bot client: ${error instanceof Error ? error.message : String(error)}`);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
// Get scheduling pages tool
|
|
64
|
+
this.server.registerTool('get_scheduling_pages', {
|
|
65
|
+
title: 'Get Scheduling Pages',
|
|
66
|
+
description: 'Get all scheduling pages for the authenticated user',
|
|
67
|
+
inputSchema: {},
|
|
68
|
+
}, async (_, extra) => {
|
|
69
|
+
if (!extra.sessionId) {
|
|
70
|
+
throw new Error('Session ID is required');
|
|
71
|
+
}
|
|
72
|
+
if (!extra.sessionId) {
|
|
73
|
+
throw new Error('Session ID is required');
|
|
74
|
+
}
|
|
75
|
+
const client = this.clients.get(extra.sessionId);
|
|
76
|
+
if (!client) {
|
|
77
|
+
throw new Error('Meet.bot client not configured. Please use configure_meetbot first.');
|
|
78
|
+
}
|
|
79
|
+
const pages = await client.getPages();
|
|
80
|
+
return {
|
|
81
|
+
content: [
|
|
82
|
+
{
|
|
83
|
+
type: 'text',
|
|
84
|
+
text: `Found ${pages.pages.length} scheduling pages for ${pages.email}:\n\n${pages.pages
|
|
85
|
+
.map((page) => `• ${page.title} (${page.duration} min) - ${page.url}`)
|
|
86
|
+
.join('\n')}`,
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
// Get page info tool
|
|
92
|
+
this.server.registerTool('get_page_info', {
|
|
93
|
+
title: 'Get Page Information',
|
|
94
|
+
description: 'Get information about a specific scheduling page',
|
|
95
|
+
inputSchema: {
|
|
96
|
+
page: z.string().describe('The URL of the scheduling page'),
|
|
97
|
+
},
|
|
98
|
+
}, async ({ page }, extra) => {
|
|
99
|
+
if (!extra.sessionId) {
|
|
100
|
+
throw new Error('Session ID is required');
|
|
101
|
+
}
|
|
102
|
+
if (!extra.sessionId) {
|
|
103
|
+
throw new Error('Session ID is required');
|
|
104
|
+
}
|
|
105
|
+
const client = this.clients.get(extra.sessionId);
|
|
106
|
+
if (!client) {
|
|
107
|
+
throw new Error('Meet.bot client not configured. Please use configure_meetbot first.');
|
|
108
|
+
}
|
|
109
|
+
if (!page) {
|
|
110
|
+
throw new Error('Page URL is required');
|
|
111
|
+
}
|
|
112
|
+
const pageInfo = await client.getPageInfo({ page });
|
|
113
|
+
return {
|
|
114
|
+
content: [
|
|
115
|
+
{
|
|
116
|
+
type: 'text',
|
|
117
|
+
text: `Page Information:\n\nTitle: ${pageInfo.title}\nDuration: ${pageInfo.duration} minutes\nOwner: ${pageInfo.owner_name}\nMax days ahead: ${pageInfo.max_days_into_the_future}\nURL: ${pageInfo.url}`,
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
};
|
|
121
|
+
});
|
|
122
|
+
// Get available slots tool
|
|
123
|
+
this.server.registerTool('get_available_slots', {
|
|
124
|
+
title: 'Get Available Slots',
|
|
125
|
+
description: 'Get available booking slots for a scheduling page',
|
|
126
|
+
inputSchema: {
|
|
127
|
+
page: z.string().describe('The URL of the scheduling page'),
|
|
128
|
+
count: z.number().optional().describe('Maximum number of slots to return'),
|
|
129
|
+
start: z.string().optional().describe('Start date in YYYY-MM-DD format'),
|
|
130
|
+
end: z.string().optional().describe('End date in YYYY-MM-DD format'),
|
|
131
|
+
timezone: z.string().optional().describe('Timezone in IANA format (e.g., America/New_York)'),
|
|
132
|
+
booking_link: z.boolean().optional().describe('Include shareable booking links'),
|
|
133
|
+
},
|
|
134
|
+
}, async ({ page, ...args }, extra) => {
|
|
135
|
+
if (!extra.sessionId) {
|
|
136
|
+
throw new Error('Session ID is required');
|
|
137
|
+
}
|
|
138
|
+
const client = this.clients.get(extra.sessionId);
|
|
139
|
+
if (!client) {
|
|
140
|
+
throw new Error('Meet.bot client not configured. Please use configure_meetbot first.');
|
|
141
|
+
}
|
|
142
|
+
if (!page) {
|
|
143
|
+
throw new Error('Page URL is required');
|
|
144
|
+
}
|
|
145
|
+
const slots = await client.getSlots({ page, ...args });
|
|
146
|
+
return {
|
|
147
|
+
content: [
|
|
148
|
+
{
|
|
149
|
+
type: 'text',
|
|
150
|
+
text: `Found ${slots.count} available slots (${slots.duration} min each):\n\n${slots.slots
|
|
151
|
+
.map((slot) => {
|
|
152
|
+
const date = new Date(slot.start).toLocaleString();
|
|
153
|
+
const urlInfo = slot.url ? `\n Booking link: ${slot.url}` : '';
|
|
154
|
+
return `• ${date}${urlInfo}`;
|
|
155
|
+
})
|
|
156
|
+
.join('\n\n')}`,
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
// Book meeting tool
|
|
162
|
+
this.server.registerTool('book_meeting', {
|
|
163
|
+
title: 'Book Meeting',
|
|
164
|
+
description: 'Book a new meeting slot',
|
|
165
|
+
inputSchema: {
|
|
166
|
+
page: z.string().describe('The URL of the scheduling page'),
|
|
167
|
+
guest_email: z.string().describe('Email address of the guest'),
|
|
168
|
+
guest_name: z.string().describe('Name of the guest'),
|
|
169
|
+
notes: z.string().optional().describe('Additional notes for the meeting'),
|
|
170
|
+
start: z.string().describe('Start time in ISO 8601 format'),
|
|
171
|
+
},
|
|
172
|
+
}, async ({ page, guest_email, guest_name, notes, start }, extra) => {
|
|
173
|
+
if (!extra.sessionId) {
|
|
174
|
+
throw new Error('Session ID is required');
|
|
175
|
+
}
|
|
176
|
+
const client = this.clients.get(extra.sessionId);
|
|
177
|
+
if (!client) {
|
|
178
|
+
throw new Error('Meet.bot client not configured. Please use configure_meetbot first.');
|
|
179
|
+
}
|
|
180
|
+
if (!page || !guest_email || !guest_name || !start) {
|
|
181
|
+
throw new Error('Required parameters missing: page, guest_email, guest_name, start');
|
|
182
|
+
}
|
|
183
|
+
const booking = await client.bookSlot({ page, guest_email, guest_name, notes, start });
|
|
184
|
+
return {
|
|
185
|
+
content: [
|
|
186
|
+
{
|
|
187
|
+
type: 'text',
|
|
188
|
+
text: `Meeting booked successfully!\n\nGuest: ${booking.guest_name} (${booking.guest_email})\nStart: ${new Date(booking.start).toLocaleString()}\nCalendar ID: ${booking.ical_uid}\nPage: ${booking.page}`,
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
};
|
|
192
|
+
});
|
|
193
|
+
// Health check tool
|
|
194
|
+
this.server.registerTool('health_check', {
|
|
195
|
+
title: 'Health Check',
|
|
196
|
+
description: 'Check if the Meet.bot API client is healthy',
|
|
197
|
+
inputSchema: {},
|
|
198
|
+
}, async (_, extra) => {
|
|
199
|
+
if (!extra.sessionId) {
|
|
200
|
+
throw new Error('Session ID is required');
|
|
201
|
+
}
|
|
202
|
+
const client = this.clients.get(extra.sessionId);
|
|
203
|
+
if (!client) {
|
|
204
|
+
throw new Error('Meet.bot client not configured. Please use configure_meetbot first.');
|
|
205
|
+
}
|
|
206
|
+
const isHealthy = await client.healthCheck();
|
|
207
|
+
return {
|
|
208
|
+
content: [
|
|
209
|
+
{
|
|
210
|
+
type: 'text',
|
|
211
|
+
text: isHealthy
|
|
212
|
+
? '✅ Meet.bot API client is healthy and can connect to the API.'
|
|
213
|
+
: '❌ Meet.bot API client cannot connect to the API. Please check your configuration.',
|
|
214
|
+
},
|
|
215
|
+
],
|
|
216
|
+
};
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Create Express app with MCP endpoints
|
|
221
|
+
*/
|
|
222
|
+
createApp() {
|
|
223
|
+
const app = express();
|
|
224
|
+
app.use(express.json());
|
|
225
|
+
// CORS configuration
|
|
226
|
+
app.use((req, res, next) => {
|
|
227
|
+
res.header('Access-Control-Allow-Origin', '*');
|
|
228
|
+
res.header('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');
|
|
229
|
+
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Mcp-Session-Id, Last-Event-ID');
|
|
230
|
+
res.header('Access-Control-Expose-Headers', 'Mcp-Session-Id');
|
|
231
|
+
if (req.method === 'OPTIONS') {
|
|
232
|
+
res.status(200).end();
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
next();
|
|
236
|
+
});
|
|
237
|
+
// MCP POST endpoint (naked path for dedicated MCP subdomain)
|
|
238
|
+
app.post('/', async (req, res) => {
|
|
239
|
+
const sessionId = req.headers['mcp-session-id'];
|
|
240
|
+
console.log('🔍 MCP POST request for session:', sessionId);
|
|
241
|
+
console.log('🔍 Request body:', req.body);
|
|
242
|
+
try {
|
|
243
|
+
let transport;
|
|
244
|
+
if (sessionId && this.transports.has(sessionId)) {
|
|
245
|
+
// Reuse existing transport
|
|
246
|
+
transport = this.transports.get(sessionId);
|
|
247
|
+
}
|
|
248
|
+
else if (!sessionId && isInitializeRequest(req.body)) {
|
|
249
|
+
// New initialization request
|
|
250
|
+
const eventStore = new InMemoryEventStore();
|
|
251
|
+
transport = new StreamableHTTPServerTransport({
|
|
252
|
+
sessionIdGenerator: () => randomUUID(),
|
|
253
|
+
eventStore, // Enable resumability
|
|
254
|
+
onsessioninitialized: (sessionId) => {
|
|
255
|
+
console.log(`🔍 Session initialized with ID: ${sessionId}`);
|
|
256
|
+
this.transports.set(sessionId, transport);
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
// Set up onclose handler to clean up transport when closed
|
|
260
|
+
transport.onclose = () => {
|
|
261
|
+
const sid = transport.sessionId;
|
|
262
|
+
if (sid && this.transports.has(sid)) {
|
|
263
|
+
console.log(`🔍 Transport closed for session ${sid}, removing from transports map`);
|
|
264
|
+
this.transports.delete(sid);
|
|
265
|
+
this.clients.delete(sid);
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
// Connect the transport to the MCP server BEFORE handling the request
|
|
269
|
+
await this.server.connect(transport);
|
|
270
|
+
await transport.handleRequest(req, res, req.body);
|
|
271
|
+
return; // Already handled
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
// Invalid request - no session ID or not initialization request
|
|
275
|
+
res.status(400).json({
|
|
276
|
+
jsonrpc: '2.0',
|
|
277
|
+
error: {
|
|
278
|
+
code: -32000,
|
|
279
|
+
message: 'Bad Request: No valid session ID provided'
|
|
280
|
+
},
|
|
281
|
+
id: null
|
|
282
|
+
});
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
// Handle the request with existing transport
|
|
286
|
+
await transport.handleRequest(req, res, req.body);
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
console.error('🔍 Error handling MCP request:', error);
|
|
290
|
+
if (!res.headersSent) {
|
|
291
|
+
res.status(500).json({
|
|
292
|
+
jsonrpc: '2.0',
|
|
293
|
+
error: {
|
|
294
|
+
code: -32603,
|
|
295
|
+
message: 'Internal server error'
|
|
296
|
+
},
|
|
297
|
+
id: null
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
// MCP GET endpoint for SSE streams (naked path for dedicated MCP subdomain)
|
|
303
|
+
app.get('/', async (req, res) => {
|
|
304
|
+
const sessionId = req.headers['mcp-session-id'];
|
|
305
|
+
console.log('🔍 MCP GET request for session:', sessionId);
|
|
306
|
+
if (!sessionId || !this.transports.has(sessionId)) {
|
|
307
|
+
res.status(400).send('Invalid or missing session ID');
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
// Check for Last-Event-ID header for resumability
|
|
311
|
+
const lastEventId = req.headers['last-event-id'];
|
|
312
|
+
if (lastEventId) {
|
|
313
|
+
console.log(`🔍 Client reconnecting with Last-Event-ID: ${lastEventId}`);
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
console.log(`🔍 Establishing new SSE stream for session ${sessionId}`);
|
|
317
|
+
}
|
|
318
|
+
const transport = this.transports.get(sessionId);
|
|
319
|
+
await transport.handleRequest(req, res);
|
|
320
|
+
});
|
|
321
|
+
// MCP DELETE endpoint for session termination (naked path for dedicated MCP subdomain)
|
|
322
|
+
app.delete('/', async (req, res) => {
|
|
323
|
+
const sessionId = req.headers['mcp-session-id'];
|
|
324
|
+
console.log(`🔍 Received session termination request for session ${sessionId}`);
|
|
325
|
+
if (!sessionId || !this.transports.has(sessionId)) {
|
|
326
|
+
res.status(400).send('Invalid or missing session ID');
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
try {
|
|
330
|
+
const transport = this.transports.get(sessionId);
|
|
331
|
+
await transport.handleRequest(req, res);
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
console.error('🔍 Error handling session termination:', error);
|
|
335
|
+
if (!res.headersSent) {
|
|
336
|
+
res.status(500).send('Error processing session termination');
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
// Health check endpoint
|
|
341
|
+
app.get('/health', (_req, res) => {
|
|
342
|
+
res.json({ status: 'ok', service: 'meetbot-mcp' });
|
|
343
|
+
});
|
|
344
|
+
return app;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
//# sourceMappingURL=mcp-server-streamable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server-streamable.js","sourceRoot":"","sources":["../src/mcp-server-streamable.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meetbot/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Model Context Protocol (MCP) server for Meet.bot booking page API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
"bin": {
|
|
9
|
+
"meetbot-mcp": "dist/cli.js",
|
|
10
|
+
"meetbot-mcp-http": "dist/cli-http.js",
|
|
11
|
+
"meetbot-mcp-streamable": "dist/cli-streamable.js"
|
|
12
|
+
},
|
|
12
13
|
"scripts": {
|
|
13
14
|
"build": "tsc",
|
|
14
15
|
"dev": "tsc --watch",
|
|
15
16
|
"start": "node dist/cli.js",
|
|
16
17
|
"start:http": "node dist/cli-http.js",
|
|
18
|
+
"start:streamable": "node dist/cli-streamable.js",
|
|
17
19
|
"test": "jest",
|
|
18
20
|
"test:watch": "jest --watch",
|
|
19
21
|
"lint": "eslint src/**/*.ts",
|
|
@@ -41,8 +43,10 @@
|
|
|
41
43
|
},
|
|
42
44
|
"homepage": "https://gitlab.com/meetbot/meetbot-mcp",
|
|
43
45
|
"dependencies": {
|
|
44
|
-
"@modelcontextprotocol/sdk": "^
|
|
46
|
+
"@modelcontextprotocol/sdk": "^1.20.1",
|
|
47
|
+
"@types/express": "^5.0.3",
|
|
45
48
|
"axios": "^1.6.0",
|
|
49
|
+
"express": "^5.1.0",
|
|
46
50
|
"zod": "^3.22.0"
|
|
47
51
|
},
|
|
48
52
|
"devDependencies": {
|
|
@@ -63,4 +67,4 @@
|
|
|
63
67
|
"README.md",
|
|
64
68
|
"LICENSE"
|
|
65
69
|
]
|
|
66
|
-
}
|
|
70
|
+
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { IncomingMessage, ServerResponse } from 'http';
|
|
2
|
-
/**
|
|
3
|
-
* HTTP-based MCP Server for Meet.bot Booking Page API with SSE transport
|
|
4
|
-
*/
|
|
5
|
-
export declare class MeetbotMCPServerHTTP {
|
|
6
|
-
private server;
|
|
7
|
-
private transports;
|
|
8
|
-
private clients;
|
|
9
|
-
constructor();
|
|
10
|
-
private setupToolHandlers;
|
|
11
|
-
private handleConfigureMeetbot;
|
|
12
|
-
private handleGetSchedulingPages;
|
|
13
|
-
private handleGetPageInfo;
|
|
14
|
-
private handleGetAvailableSlots;
|
|
15
|
-
private handleBookMeeting;
|
|
16
|
-
private handleHealthCheck;
|
|
17
|
-
/**
|
|
18
|
-
* Authenticate incoming requests using Bearer token
|
|
19
|
-
*/
|
|
20
|
-
private authenticateRequest;
|
|
21
|
-
/**
|
|
22
|
-
* Handle incoming HTTP requests
|
|
23
|
-
*/
|
|
24
|
-
handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void>;
|
|
25
|
-
}
|
|
26
|
-
//# sourceMappingURL=mcp-server-http.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-server-http.d.ts","sourceRoot":"","sources":["../src/mcp-server-http.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAEvD;;GAEG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,OAAO,CAAyC;;IAaxD,OAAO,CAAC,iBAAiB;YAqKX,sBAAsB;YAgBtB,wBAAwB;YAwBxB,iBAAiB;YAkBjB,uBAAuB;YA0BvB,iBAAiB;YAwBjB,iBAAiB;IAoB/B;;OAEG;YACW,mBAAmB;IAkBjC;;OAEG;IACG,aAAa,CACjB,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,IAAI,CAAC;CA+EjB"}
|
package/dist/mcp-server-http.js
DELETED
|
@@ -1,346 +0,0 @@
|
|
|
1
|
-
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
-
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
|
|
3
|
-
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
-
import { MeetbotClient } from './meetbot-client.js';
|
|
5
|
-
/**
|
|
6
|
-
* HTTP-based MCP Server for Meet.bot Booking Page API with SSE transport
|
|
7
|
-
*/
|
|
8
|
-
export class MeetbotMCPServerHTTP {
|
|
9
|
-
server;
|
|
10
|
-
transports = new Map();
|
|
11
|
-
clients = new Map();
|
|
12
|
-
constructor() {
|
|
13
|
-
this.server = new Server({
|
|
14
|
-
name: 'meetbot-mcp',
|
|
15
|
-
version: '1.1.1',
|
|
16
|
-
});
|
|
17
|
-
this.setupToolHandlers();
|
|
18
|
-
}
|
|
19
|
-
setupToolHandlers() {
|
|
20
|
-
// List available tools
|
|
21
|
-
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
22
|
-
return {
|
|
23
|
-
tools: [
|
|
24
|
-
{
|
|
25
|
-
name: 'configure_meetbot',
|
|
26
|
-
description: 'Configure the Meet.bot API client with authentication',
|
|
27
|
-
inputSchema: {
|
|
28
|
-
type: 'object',
|
|
29
|
-
properties: {
|
|
30
|
-
authToken: {
|
|
31
|
-
type: 'string',
|
|
32
|
-
description: 'Bearer token for authentication (optional)',
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
required: [],
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
name: 'get_scheduling_pages',
|
|
40
|
-
description: 'Get all scheduling pages for the authenticated user',
|
|
41
|
-
inputSchema: {
|
|
42
|
-
type: 'object',
|
|
43
|
-
properties: {},
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
name: 'get_page_info',
|
|
48
|
-
description: 'Get information about a specific scheduling page',
|
|
49
|
-
inputSchema: {
|
|
50
|
-
type: 'object',
|
|
51
|
-
properties: {
|
|
52
|
-
page: {
|
|
53
|
-
type: 'string',
|
|
54
|
-
description: 'The URL of the scheduling page',
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
required: ['page'],
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
name: 'get_available_slots',
|
|
62
|
-
description: 'Get available booking slots for a scheduling page',
|
|
63
|
-
inputSchema: {
|
|
64
|
-
type: 'object',
|
|
65
|
-
properties: {
|
|
66
|
-
page: {
|
|
67
|
-
type: 'string',
|
|
68
|
-
description: 'The URL of the scheduling page',
|
|
69
|
-
},
|
|
70
|
-
count: {
|
|
71
|
-
type: 'number',
|
|
72
|
-
description: 'Maximum number of slots to return',
|
|
73
|
-
},
|
|
74
|
-
start: {
|
|
75
|
-
type: 'string',
|
|
76
|
-
description: 'Start date in YYYY-MM-DD format',
|
|
77
|
-
},
|
|
78
|
-
end: {
|
|
79
|
-
type: 'string',
|
|
80
|
-
description: 'End date in YYYY-MM-DD format',
|
|
81
|
-
},
|
|
82
|
-
timezone: {
|
|
83
|
-
type: 'string',
|
|
84
|
-
description: 'Timezone in IANA format (e.g., America/New_York)',
|
|
85
|
-
},
|
|
86
|
-
booking_link: {
|
|
87
|
-
type: 'boolean',
|
|
88
|
-
description: 'Include shareable booking links',
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
required: ['page'],
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
name: 'book_meeting',
|
|
96
|
-
description: 'Book a new meeting slot',
|
|
97
|
-
inputSchema: {
|
|
98
|
-
type: 'object',
|
|
99
|
-
properties: {
|
|
100
|
-
page: {
|
|
101
|
-
type: 'string',
|
|
102
|
-
description: 'The URL of the scheduling page',
|
|
103
|
-
},
|
|
104
|
-
guest_email: {
|
|
105
|
-
type: 'string',
|
|
106
|
-
description: 'Email address of the guest',
|
|
107
|
-
},
|
|
108
|
-
guest_name: {
|
|
109
|
-
type: 'string',
|
|
110
|
-
description: 'Name of the guest',
|
|
111
|
-
},
|
|
112
|
-
notes: {
|
|
113
|
-
type: 'string',
|
|
114
|
-
description: 'Additional notes for the meeting',
|
|
115
|
-
},
|
|
116
|
-
start: {
|
|
117
|
-
type: 'string',
|
|
118
|
-
description: 'Start time in ISO 8601 format',
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
required: ['page', 'guest_email', 'guest_name', 'start'],
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
name: 'health_check',
|
|
126
|
-
description: 'Check if the Meet.bot API client is properly configured and can connect',
|
|
127
|
-
inputSchema: {
|
|
128
|
-
type: 'object',
|
|
129
|
-
properties: {},
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
],
|
|
133
|
-
};
|
|
134
|
-
});
|
|
135
|
-
// Handle tool calls
|
|
136
|
-
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
137
|
-
const { name, arguments: args } = request.params;
|
|
138
|
-
// Get the client for this session
|
|
139
|
-
const sessionId = request.sessionId;
|
|
140
|
-
const client = sessionId ? this.clients.get(sessionId) || null : null;
|
|
141
|
-
try {
|
|
142
|
-
switch (name) {
|
|
143
|
-
case 'configure_meetbot':
|
|
144
|
-
return await this.handleConfigureMeetbot(args, sessionId);
|
|
145
|
-
case 'get_scheduling_pages':
|
|
146
|
-
return await this.handleGetSchedulingPages(client);
|
|
147
|
-
case 'get_page_info':
|
|
148
|
-
return await this.handleGetPageInfo(args, client);
|
|
149
|
-
case 'get_available_slots':
|
|
150
|
-
return await this.handleGetAvailableSlots(args, client);
|
|
151
|
-
case 'book_meeting':
|
|
152
|
-
return await this.handleBookMeeting(args, client);
|
|
153
|
-
case 'health_check':
|
|
154
|
-
return await this.handleHealthCheck(client);
|
|
155
|
-
default:
|
|
156
|
-
throw new Error(`Unknown tool: ${name}`);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
catch (error) {
|
|
160
|
-
return {
|
|
161
|
-
content: [
|
|
162
|
-
{
|
|
163
|
-
type: 'text',
|
|
164
|
-
text: `Error: ${error instanceof Error ? error.message : String(error)}`,
|
|
165
|
-
},
|
|
166
|
-
],
|
|
167
|
-
isError: true,
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
async handleConfigureMeetbot(args, sessionId) {
|
|
173
|
-
const client = new MeetbotClient(args);
|
|
174
|
-
this.clients.set(sessionId, client);
|
|
175
|
-
return {
|
|
176
|
-
content: [
|
|
177
|
-
{
|
|
178
|
-
type: 'text',
|
|
179
|
-
text: 'Meet.bot API client configured successfully.',
|
|
180
|
-
},
|
|
181
|
-
],
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
async handleGetSchedulingPages(client) {
|
|
185
|
-
if (!client) {
|
|
186
|
-
throw new Error('Meet.bot client not configured. Please run configure_meetbot first.');
|
|
187
|
-
}
|
|
188
|
-
const pages = await client.getPages();
|
|
189
|
-
return {
|
|
190
|
-
content: [
|
|
191
|
-
{
|
|
192
|
-
type: 'text',
|
|
193
|
-
text: `Found ${pages.pages.length} scheduling pages for ${pages.email}:\n\n${pages.pages
|
|
194
|
-
.map((page) => `• ${page.title} (${page.duration} min) - ${page.url}`)
|
|
195
|
-
.join('\n')}`,
|
|
196
|
-
},
|
|
197
|
-
],
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
async handleGetPageInfo(args, client) {
|
|
201
|
-
if (!client) {
|
|
202
|
-
throw new Error('Meet.bot client not configured. Please run configure_meetbot first.');
|
|
203
|
-
}
|
|
204
|
-
const pageInfo = await client.getPageInfo(args);
|
|
205
|
-
return {
|
|
206
|
-
content: [
|
|
207
|
-
{
|
|
208
|
-
type: 'text',
|
|
209
|
-
text: `Page Information:\n\nTitle: ${pageInfo.title}\nDuration: ${pageInfo.duration} minutes\nOwner: ${pageInfo.owner_name}\nMax days ahead: ${pageInfo.max_days_into_the_future}\nURL: ${pageInfo.url}`,
|
|
210
|
-
},
|
|
211
|
-
],
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
async handleGetAvailableSlots(args, client) {
|
|
215
|
-
if (!client) {
|
|
216
|
-
throw new Error('Meet.bot client not configured. Please run configure_meetbot first.');
|
|
217
|
-
}
|
|
218
|
-
const slots = await client.getSlots(args);
|
|
219
|
-
return {
|
|
220
|
-
content: [
|
|
221
|
-
{
|
|
222
|
-
type: 'text',
|
|
223
|
-
text: `Found ${slots.count} available slots (${slots.duration} min each):\n\n${slots.slots
|
|
224
|
-
.map((slot) => {
|
|
225
|
-
const date = new Date(slot.start).toLocaleString();
|
|
226
|
-
const urlInfo = slot.url ? `\n Booking link: ${slot.url}` : '';
|
|
227
|
-
return `• ${date}${urlInfo}`;
|
|
228
|
-
})
|
|
229
|
-
.join('\n\n')}`,
|
|
230
|
-
},
|
|
231
|
-
],
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
async handleBookMeeting(args, client) {
|
|
235
|
-
if (!client) {
|
|
236
|
-
throw new Error('Meet.bot client not configured. Please run configure_meetbot first.');
|
|
237
|
-
}
|
|
238
|
-
const booking = await client.bookSlot(args);
|
|
239
|
-
return {
|
|
240
|
-
content: [
|
|
241
|
-
{
|
|
242
|
-
type: 'text',
|
|
243
|
-
text: `Meeting booked successfully!\n\nGuest: ${booking.guest_name} (${booking.guest_email})\nStart: ${new Date(booking.start).toLocaleString()}\nCalendar ID: ${booking.ical_uid}\nPage: ${booking.page}`,
|
|
244
|
-
},
|
|
245
|
-
],
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
async handleHealthCheck(client) {
|
|
249
|
-
if (!client) {
|
|
250
|
-
throw new Error('Meet.bot client not configured. Please run configure_meetbot first.');
|
|
251
|
-
}
|
|
252
|
-
const isHealthy = await client.healthCheck();
|
|
253
|
-
return {
|
|
254
|
-
content: [
|
|
255
|
-
{
|
|
256
|
-
type: 'text',
|
|
257
|
-
text: isHealthy
|
|
258
|
-
? '✅ Meet.bot API client is healthy and can connect to the API.'
|
|
259
|
-
: '❌ Meet.bot API client cannot connect to the API. Please check your configuration.',
|
|
260
|
-
},
|
|
261
|
-
],
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Authenticate incoming requests using Bearer token
|
|
266
|
-
*/
|
|
267
|
-
async authenticateRequest(req) {
|
|
268
|
-
const authHeader = req.headers.authorization;
|
|
269
|
-
if (!authHeader) {
|
|
270
|
-
return null;
|
|
271
|
-
}
|
|
272
|
-
// Extract bearer token
|
|
273
|
-
const match = authHeader.match(/^Bearer\s+(.+)$/i);
|
|
274
|
-
if (!match || !match[1]) {
|
|
275
|
-
return null;
|
|
276
|
-
}
|
|
277
|
-
return match[1];
|
|
278
|
-
}
|
|
279
|
-
/**
|
|
280
|
-
* Handle incoming HTTP requests
|
|
281
|
-
*/
|
|
282
|
-
async handleRequest(req, res) {
|
|
283
|
-
const url = new URL(req.url || '/', `http://${req.headers.host}`);
|
|
284
|
-
// Authenticate the request
|
|
285
|
-
const authToken = await this.authenticateRequest(req);
|
|
286
|
-
if (!authToken) {
|
|
287
|
-
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
288
|
-
res.end(JSON.stringify({
|
|
289
|
-
error: 'Unauthorized',
|
|
290
|
-
message: 'Missing or invalid Authorization header. Use: Authorization: Bearer <your-token>',
|
|
291
|
-
}));
|
|
292
|
-
return;
|
|
293
|
-
}
|
|
294
|
-
// Handle SSE connection (GET request)
|
|
295
|
-
if (req.method === 'GET' && url.pathname === '/sse') {
|
|
296
|
-
const transport = new SSEServerTransport('/messages', res);
|
|
297
|
-
const sessionId = transport.sessionId;
|
|
298
|
-
// Store transport and create client with the authenticated token
|
|
299
|
-
this.transports.set(sessionId, transport);
|
|
300
|
-
const client = new MeetbotClient({ authToken });
|
|
301
|
-
this.clients.set(sessionId, client);
|
|
302
|
-
// Attach session ID to requests
|
|
303
|
-
const originalSetRequestHandler = this.server.setRequestHandler.bind(this.server);
|
|
304
|
-
this.server.setRequestHandler = ((schema, handler) => {
|
|
305
|
-
return originalSetRequestHandler(schema, async (request) => {
|
|
306
|
-
request.sessionId = sessionId;
|
|
307
|
-
return handler(request);
|
|
308
|
-
});
|
|
309
|
-
});
|
|
310
|
-
await this.server.connect(transport);
|
|
311
|
-
// Cleanup on close
|
|
312
|
-
transport.onclose = () => {
|
|
313
|
-
this.transports.delete(sessionId);
|
|
314
|
-
this.clients.delete(sessionId);
|
|
315
|
-
};
|
|
316
|
-
return;
|
|
317
|
-
}
|
|
318
|
-
// Handle POST messages
|
|
319
|
-
if (req.method === 'POST' && url.pathname === '/messages') {
|
|
320
|
-
const sessionId = url.searchParams.get('sessionId');
|
|
321
|
-
if (!sessionId) {
|
|
322
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
323
|
-
res.end(JSON.stringify({ error: 'Missing sessionId' }));
|
|
324
|
-
return;
|
|
325
|
-
}
|
|
326
|
-
const transport = this.transports.get(sessionId);
|
|
327
|
-
if (!transport) {
|
|
328
|
-
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
329
|
-
res.end(JSON.stringify({ error: 'Session not found' }));
|
|
330
|
-
return;
|
|
331
|
-
}
|
|
332
|
-
await transport.handlePostMessage(req, res);
|
|
333
|
-
return;
|
|
334
|
-
}
|
|
335
|
-
// Health check endpoint
|
|
336
|
-
if (req.method === 'GET' && url.pathname === '/health') {
|
|
337
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
338
|
-
res.end(JSON.stringify({ status: 'ok', service: 'meetbot-mcp' }));
|
|
339
|
-
return;
|
|
340
|
-
}
|
|
341
|
-
// 404 for other routes
|
|
342
|
-
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
343
|
-
res.end(JSON.stringify({ error: 'Not found' }));
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
//# sourceMappingURL=mcp-server-http.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-server-http.js","sourceRoot":"","sources":["../src/mcp-server-http.ts"],"names":[],"mappings":"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"}
|