@respond-io/mcp-server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/LICENSE +21 -0
- package/README.md +635 -0
- package/dist/constants.d.ts +89 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +143 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/middlewares/TokenVerifier.d.ts +19 -0
- package/dist/middlewares/TokenVerifier.d.ts.map +1 -0
- package/dist/middlewares/TokenVerifier.js +68 -0
- package/dist/middlewares/TokenVerifier.js.map +1 -0
- package/dist/protocol/BaseProtocol.d.ts +4 -0
- package/dist/protocol/BaseProtocol.d.ts.map +1 -0
- package/dist/protocol/BaseProtocol.js +7 -0
- package/dist/protocol/BaseProtocol.js.map +1 -0
- package/dist/protocol/HttpStreamProtocol.d.ts +36 -0
- package/dist/protocol/HttpStreamProtocol.d.ts.map +1 -0
- package/dist/protocol/HttpStreamProtocol.js +148 -0
- package/dist/protocol/HttpStreamProtocol.js.map +1 -0
- package/dist/protocol/StdioProtocol.d.ts +14 -0
- package/dist/protocol/StdioProtocol.d.ts.map +1 -0
- package/dist/protocol/StdioProtocol.js +32 -0
- package/dist/protocol/StdioProtocol.js.map +1 -0
- package/dist/protocol/index.d.ts +4 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +4 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/server.d.ts +13 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +36 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/BaseTool.d.ts +38 -0
- package/dist/tools/BaseTool.d.ts.map +1 -0
- package/dist/tools/BaseTool.js +39 -0
- package/dist/tools/BaseTool.js.map +1 -0
- package/dist/tools/comment.tool.d.ts +14 -0
- package/dist/tools/comment.tool.d.ts.map +1 -0
- package/dist/tools/comment.tool.js +43 -0
- package/dist/tools/comment.tool.js.map +1 -0
- package/dist/tools/contacts.tool.d.ts +17 -0
- package/dist/tools/contacts.tool.d.ts.map +1 -0
- package/dist/tools/contacts.tool.js +355 -0
- package/dist/tools/contacts.tool.js.map +1 -0
- package/dist/tools/conversation.tool.d.ts +14 -0
- package/dist/tools/conversation.tool.d.ts.map +1 -0
- package/dist/tools/conversation.tool.js +77 -0
- package/dist/tools/conversation.tool.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +7 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/messaging.tool.d.ts +15 -0
- package/dist/tools/messaging.tool.d.ts.map +1 -0
- package/dist/tools/messaging.tool.js +160 -0
- package/dist/tools/messaging.tool.js.map +1 -0
- package/dist/tools/workspace.tool.d.ts +15 -0
- package/dist/tools/workspace.tool.d.ts.map +1 -0
- package/dist/tools/workspace.tool.js +282 -0
- package/dist/tools/workspace.tool.js.map +1 -0
- package/dist/types.d.ts +351 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/api.d.ts +127 -0
- package/dist/utils/api.d.ts.map +1 -0
- package/dist/utils/api.js +340 -0
- package/dist/utils/api.js.map +1 -0
- package/package.json +108 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants for the Respond.io MCP Server
|
|
3
|
+
*/
|
|
4
|
+
export declare const APP_CONFIG: {
|
|
5
|
+
readonly PORT: number;
|
|
6
|
+
readonly debug: false;
|
|
7
|
+
};
|
|
8
|
+
export declare const API_CONFIG: {
|
|
9
|
+
readonly BASE_URL: string;
|
|
10
|
+
readonly TIMEOUT: 30000;
|
|
11
|
+
readonly MAX_RETRIES: 3;
|
|
12
|
+
readonly RETRY_DELAY: 1000;
|
|
13
|
+
};
|
|
14
|
+
export declare const PAGINATION: {
|
|
15
|
+
readonly DEFAULT_LIMIT: 10;
|
|
16
|
+
readonly MIN_LIMIT: 1;
|
|
17
|
+
readonly MAX_LIMIT: 100;
|
|
18
|
+
};
|
|
19
|
+
export declare const FIELD_LIMITS: {
|
|
20
|
+
readonly CUSTOM_FIELD_NAME_MAX_LENGTH: 50;
|
|
21
|
+
readonly CUSTOM_FIELD_SLUG_MAX_LENGTH: 50;
|
|
22
|
+
readonly CUSTOM_FIELD_DESCRIPTION_MAX_LENGTH: 255;
|
|
23
|
+
readonly TAG_MAX_LENGTH: 255;
|
|
24
|
+
readonly TAG_MAX_COUNT: 10;
|
|
25
|
+
readonly COMMENT_MAX_LENGTH: 1000;
|
|
26
|
+
readonly CLOSING_NOTE_CATEGORY_MAX_LENGTH: 128;
|
|
27
|
+
readonly CLOSING_NOTE_SUMMARY_MAX_LENGTH: 512;
|
|
28
|
+
};
|
|
29
|
+
export declare const MESSAGE_TYPES: readonly ["text", "attachment", "whatsapp_template", "email", "quick_reply", "custom_payload"];
|
|
30
|
+
export declare const ATTACHMENT_TYPES: readonly ["image", "video", "audio", "file"];
|
|
31
|
+
export declare const CUSTOM_FIELD_DATA_TYPES: readonly ["text", "list", "checkbox", "email", "number", "url", "date", "time"];
|
|
32
|
+
export declare const CONVERSATION_STATUSES: readonly ["open", "close"];
|
|
33
|
+
export declare const USER_ROLES: readonly ["agent", "manager", "owner"];
|
|
34
|
+
export declare const CHANNEL_SOURCES: readonly ["facebook", "instagram", "line", "telegram", "viber", "twitter", "wechat", "custom_channel", "gmail", "other_email", "twilio", "message_bird", "nexmo", "360dialog_whatsapp", "twilio_whatsapp", "message_bird_whatsapp", "whatsapp", "nexmo_whatsapp", "whatsapp_cloud"];
|
|
35
|
+
export declare const MESSAGE_STATUSES: readonly ["pending", "sent", "delivered", "read", "failed"];
|
|
36
|
+
export declare const FILTER_OPERATORS: readonly ["isEqualTo", "isNotEqualTo", "isTimestampAfter", "isTimestampBefore", "isTimestampBetween", "exists", "doesNotExist", "isGreaterThan", "isLessThan", "isBetween", "hasAnyOf", "hasAllOf", "hasNoneOf"];
|
|
37
|
+
export declare const FILTER_CATEGORIES: readonly ["contactField", "contactTag", "lifecycle"];
|
|
38
|
+
export declare const FACEBOOK_MESSAGE_TAGS: readonly ["ACCOUNT_UPDATE", "POST_PURCHASE_UPDATE", "CONFIRMED_EVENT_UPDATE"];
|
|
39
|
+
export declare const ERROR_CODES: {
|
|
40
|
+
readonly VALIDATION_ERROR: 400;
|
|
41
|
+
readonly UNAUTHORIZED: 401;
|
|
42
|
+
readonly NOT_FOUND: 404;
|
|
43
|
+
readonly CONFLICT: 409;
|
|
44
|
+
readonly RATE_LIMIT: 429;
|
|
45
|
+
readonly REQUEST_QUEUED: 449;
|
|
46
|
+
readonly SERVER_ERROR: 500;
|
|
47
|
+
};
|
|
48
|
+
export declare const ERROR_MESSAGES: {
|
|
49
|
+
readonly INVALID_API_KEY: "Invalid or missing API key";
|
|
50
|
+
readonly INVALID_IDENTIFIER: "Invalid identifier format. Use 'id:123', 'email:user@example.com', or 'phone:+1234567890'";
|
|
51
|
+
readonly INVALID_EMAIL: "Invalid email format";
|
|
52
|
+
readonly INVALID_PHONE: "Invalid phone number format. Use E.164 format (e.g., +60123456789)";
|
|
53
|
+
readonly INVALID_URL: "Invalid URL format";
|
|
54
|
+
readonly INVALID_LANGUAGE_CODE: "Invalid language code. Use ISO 639-1 format (e.g., 'en', 'ms')";
|
|
55
|
+
readonly INVALID_COUNTRY_CODE: "Invalid country code. Use ISO 3166-1 alpha-2 format (e.g., 'MY', 'US')";
|
|
56
|
+
readonly MISSING_REQUIRED_FIELD: "Missing required field";
|
|
57
|
+
readonly TAG_TOO_LONG: "Tag exceeds maximum length of 255 characters";
|
|
58
|
+
readonly TOO_MANY_TAGS: "Cannot add more than 10 tags";
|
|
59
|
+
readonly COMMENT_TOO_LONG: "Comment exceeds maximum length of 1000 characters";
|
|
60
|
+
};
|
|
61
|
+
export declare const HTTP_STATUS_DESCRIPTIONS: {
|
|
62
|
+
readonly 200: "OK";
|
|
63
|
+
readonly 400: "Bad Request";
|
|
64
|
+
readonly 401: "Unauthorized";
|
|
65
|
+
readonly 404: "Not Found";
|
|
66
|
+
readonly 409: "Conflict";
|
|
67
|
+
readonly 429: "Too Many Requests";
|
|
68
|
+
readonly 449: "Retry With";
|
|
69
|
+
readonly 500: "Internal Server Error";
|
|
70
|
+
};
|
|
71
|
+
export declare const REGEX_PATTERNS: {
|
|
72
|
+
readonly IDENTIFIER_ID: RegExp;
|
|
73
|
+
readonly IDENTIFIER_EMAIL: RegExp;
|
|
74
|
+
readonly IDENTIFIER_PHONE: RegExp;
|
|
75
|
+
readonly EMAIL: RegExp;
|
|
76
|
+
readonly PHONE_E164: RegExp;
|
|
77
|
+
readonly ISO_DATE: RegExp;
|
|
78
|
+
readonly TIME_24H: RegExp;
|
|
79
|
+
readonly LANGUAGE_CODE: RegExp;
|
|
80
|
+
readonly COUNTRY_CODE: RegExp;
|
|
81
|
+
readonly SLUG: RegExp;
|
|
82
|
+
};
|
|
83
|
+
export declare const DEFAULT_TIMEZONE = "UTC";
|
|
84
|
+
export declare const SERVER_INFO: {
|
|
85
|
+
readonly NAME: "respondio-mcp-server";
|
|
86
|
+
readonly VERSION: "1.0.0";
|
|
87
|
+
readonly DESCRIPTION: "Model Context Protocol server for Respond.io API";
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,UAAU;;;CAGb,CAAC;AAEX,eAAO,MAAM,UAAU;;;;;CAKb,CAAC;AAEX,eAAO,MAAM,UAAU;;;;CAIb,CAAC;AAEX,eAAO,MAAM,YAAY;;;;;;;;;CASf,CAAC;AAEX,eAAO,MAAM,aAAa,gGAOhB,CAAC;AAEX,eAAO,MAAM,gBAAgB,8CAA+C,CAAC;AAE7E,eAAO,MAAM,uBAAuB,iFAS1B,CAAC;AAEX,eAAO,MAAM,qBAAqB,4BAA6B,CAAC;AAEhE,eAAO,MAAM,UAAU,wCAAyC,CAAC;AAEjE,eAAO,MAAM,eAAe,qRAoBlB,CAAC;AAEX,eAAO,MAAM,gBAAgB,6DAA8D,CAAC;AAE5F,eAAO,MAAM,gBAAgB,kNAcnB,CAAC;AAEX,eAAO,MAAM,iBAAiB,sDAAuD,CAAC;AAEtF,eAAO,MAAM,qBAAqB,+EAIxB,CAAC;AAEX,eAAO,MAAM,WAAW;;;;;;;;CAQd,CAAC;AAEX,eAAO,MAAM,cAAc;;;;;;;;;;;;CAajB,CAAC;AAEX,eAAO,MAAM,wBAAwB;;;;;;;;;CAS3B,CAAC;AAEX,eAAO,MAAM,cAAc;;;;;;;;;;;CAWjB,CAAC;AAEX,eAAO,MAAM,gBAAgB,QAAQ,CAAC;AAEtC,eAAO,MAAM,WAAW;;;;CAId,CAAC"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants for the Respond.io MCP Server
|
|
3
|
+
*/
|
|
4
|
+
export const APP_CONFIG = {
|
|
5
|
+
PORT: Number(process.env.PORT || 3000),
|
|
6
|
+
debug: false,
|
|
7
|
+
};
|
|
8
|
+
export const API_CONFIG = {
|
|
9
|
+
BASE_URL: process.env.RESPONDIO_BASE_URL || "https://api.respond.io/v2",
|
|
10
|
+
TIMEOUT: 30000, // 30 seconds
|
|
11
|
+
MAX_RETRIES: 3,
|
|
12
|
+
RETRY_DELAY: 1000, // 1 second
|
|
13
|
+
};
|
|
14
|
+
export const PAGINATION = {
|
|
15
|
+
DEFAULT_LIMIT: 10,
|
|
16
|
+
MIN_LIMIT: 1,
|
|
17
|
+
MAX_LIMIT: 100,
|
|
18
|
+
};
|
|
19
|
+
export const FIELD_LIMITS = {
|
|
20
|
+
CUSTOM_FIELD_NAME_MAX_LENGTH: 50,
|
|
21
|
+
CUSTOM_FIELD_SLUG_MAX_LENGTH: 50,
|
|
22
|
+
CUSTOM_FIELD_DESCRIPTION_MAX_LENGTH: 255,
|
|
23
|
+
TAG_MAX_LENGTH: 255,
|
|
24
|
+
TAG_MAX_COUNT: 10,
|
|
25
|
+
COMMENT_MAX_LENGTH: 1000,
|
|
26
|
+
CLOSING_NOTE_CATEGORY_MAX_LENGTH: 128,
|
|
27
|
+
CLOSING_NOTE_SUMMARY_MAX_LENGTH: 512,
|
|
28
|
+
};
|
|
29
|
+
export const MESSAGE_TYPES = [
|
|
30
|
+
"text",
|
|
31
|
+
"attachment",
|
|
32
|
+
"whatsapp_template",
|
|
33
|
+
"email",
|
|
34
|
+
"quick_reply",
|
|
35
|
+
"custom_payload",
|
|
36
|
+
];
|
|
37
|
+
export const ATTACHMENT_TYPES = ["image", "video", "audio", "file"];
|
|
38
|
+
export const CUSTOM_FIELD_DATA_TYPES = [
|
|
39
|
+
"text",
|
|
40
|
+
"list",
|
|
41
|
+
"checkbox",
|
|
42
|
+
"email",
|
|
43
|
+
"number",
|
|
44
|
+
"url",
|
|
45
|
+
"date",
|
|
46
|
+
"time",
|
|
47
|
+
];
|
|
48
|
+
export const CONVERSATION_STATUSES = ["open", "close"];
|
|
49
|
+
export const USER_ROLES = ["agent", "manager", "owner"];
|
|
50
|
+
export const CHANNEL_SOURCES = [
|
|
51
|
+
"facebook",
|
|
52
|
+
"instagram",
|
|
53
|
+
"line",
|
|
54
|
+
"telegram",
|
|
55
|
+
"viber",
|
|
56
|
+
"twitter",
|
|
57
|
+
"wechat",
|
|
58
|
+
"custom_channel",
|
|
59
|
+
"gmail",
|
|
60
|
+
"other_email",
|
|
61
|
+
"twilio",
|
|
62
|
+
"message_bird",
|
|
63
|
+
"nexmo",
|
|
64
|
+
"360dialog_whatsapp",
|
|
65
|
+
"twilio_whatsapp",
|
|
66
|
+
"message_bird_whatsapp",
|
|
67
|
+
"whatsapp",
|
|
68
|
+
"nexmo_whatsapp",
|
|
69
|
+
"whatsapp_cloud",
|
|
70
|
+
];
|
|
71
|
+
export const MESSAGE_STATUSES = ["pending", "sent", "delivered", "read", "failed"];
|
|
72
|
+
export const FILTER_OPERATORS = [
|
|
73
|
+
"isEqualTo",
|
|
74
|
+
"isNotEqualTo",
|
|
75
|
+
"isTimestampAfter",
|
|
76
|
+
"isTimestampBefore",
|
|
77
|
+
"isTimestampBetween",
|
|
78
|
+
"exists",
|
|
79
|
+
"doesNotExist",
|
|
80
|
+
"isGreaterThan",
|
|
81
|
+
"isLessThan",
|
|
82
|
+
"isBetween",
|
|
83
|
+
"hasAnyOf",
|
|
84
|
+
"hasAllOf",
|
|
85
|
+
"hasNoneOf",
|
|
86
|
+
];
|
|
87
|
+
export const FILTER_CATEGORIES = ["contactField", "contactTag", "lifecycle"];
|
|
88
|
+
export const FACEBOOK_MESSAGE_TAGS = [
|
|
89
|
+
"ACCOUNT_UPDATE",
|
|
90
|
+
"POST_PURCHASE_UPDATE",
|
|
91
|
+
"CONFIRMED_EVENT_UPDATE",
|
|
92
|
+
];
|
|
93
|
+
export const ERROR_CODES = {
|
|
94
|
+
VALIDATION_ERROR: 400,
|
|
95
|
+
UNAUTHORIZED: 401,
|
|
96
|
+
NOT_FOUND: 404,
|
|
97
|
+
CONFLICT: 409,
|
|
98
|
+
RATE_LIMIT: 429,
|
|
99
|
+
REQUEST_QUEUED: 449,
|
|
100
|
+
SERVER_ERROR: 500,
|
|
101
|
+
};
|
|
102
|
+
export const ERROR_MESSAGES = {
|
|
103
|
+
INVALID_API_KEY: "Invalid or missing API key",
|
|
104
|
+
INVALID_IDENTIFIER: "Invalid identifier format. Use 'id:123', 'email:user@example.com', or 'phone:+1234567890'",
|
|
105
|
+
INVALID_EMAIL: "Invalid email format",
|
|
106
|
+
INVALID_PHONE: "Invalid phone number format. Use E.164 format (e.g., +60123456789)",
|
|
107
|
+
INVALID_URL: "Invalid URL format",
|
|
108
|
+
INVALID_LANGUAGE_CODE: "Invalid language code. Use ISO 639-1 format (e.g., 'en', 'ms')",
|
|
109
|
+
INVALID_COUNTRY_CODE: "Invalid country code. Use ISO 3166-1 alpha-2 format (e.g., 'MY', 'US')",
|
|
110
|
+
MISSING_REQUIRED_FIELD: "Missing required field",
|
|
111
|
+
TAG_TOO_LONG: `Tag exceeds maximum length of ${FIELD_LIMITS.TAG_MAX_LENGTH} characters`,
|
|
112
|
+
TOO_MANY_TAGS: `Cannot add more than ${FIELD_LIMITS.TAG_MAX_COUNT} tags`,
|
|
113
|
+
COMMENT_TOO_LONG: `Comment exceeds maximum length of ${FIELD_LIMITS.COMMENT_MAX_LENGTH} characters`,
|
|
114
|
+
};
|
|
115
|
+
export const HTTP_STATUS_DESCRIPTIONS = {
|
|
116
|
+
200: "OK",
|
|
117
|
+
400: "Bad Request",
|
|
118
|
+
401: "Unauthorized",
|
|
119
|
+
404: "Not Found",
|
|
120
|
+
409: "Conflict",
|
|
121
|
+
429: "Too Many Requests",
|
|
122
|
+
449: "Retry With",
|
|
123
|
+
500: "Internal Server Error",
|
|
124
|
+
};
|
|
125
|
+
export const REGEX_PATTERNS = {
|
|
126
|
+
IDENTIFIER_ID: /^id:\d+$/,
|
|
127
|
+
IDENTIFIER_EMAIL: /^email:.+@.+\..+$/,
|
|
128
|
+
IDENTIFIER_PHONE: /^phone:\+?\d+$/,
|
|
129
|
+
EMAIL: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
|
|
130
|
+
PHONE_E164: /^\+[1-9]\d{1,14}$/,
|
|
131
|
+
ISO_DATE: /^\d{4}-\d{2}-\d{2}$/,
|
|
132
|
+
TIME_24H: /^([01]\d|2[0-3]):([0-5]\d)$/,
|
|
133
|
+
LANGUAGE_CODE: /^[a-z]{2}$/i,
|
|
134
|
+
COUNTRY_CODE: /^[A-Z]{2}$/,
|
|
135
|
+
SLUG: /^[a-zA-Z0-9_]+$/,
|
|
136
|
+
};
|
|
137
|
+
export const DEFAULT_TIMEZONE = "UTC";
|
|
138
|
+
export const SERVER_INFO = {
|
|
139
|
+
NAME: "respondio-mcp-server",
|
|
140
|
+
VERSION: "1.0.0",
|
|
141
|
+
DESCRIPTION: "Model Context Protocol server for Respond.io API",
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { API_CONFIG, APP_CONFIG } from "./constants.js";
|
|
3
|
+
import { HttpStreamProtocol, StdioProtocol } from "./protocol/index.js";
|
|
4
|
+
import { initializeClientMonitoring } from "./utils/api.js";
|
|
5
|
+
/**
|
|
6
|
+
* Initializes and starts the appropriate protocol based on the `MCP_SERVER_MODE` environment variable.
|
|
7
|
+
* If `MCP_SERVER_MODE` is set to "http", the `HttpStreamProtocol` is used; otherwise, the `StdioProtocol` is used.
|
|
8
|
+
* The configuration is sourced from environment variables, with fallback to default values from the application and API configurations.
|
|
9
|
+
*
|
|
10
|
+
* @throws {Error} If the protocol fails to start, an error is logged to the console, and the process exits with a non-zero status code.
|
|
11
|
+
*/
|
|
12
|
+
const startServer = async () => {
|
|
13
|
+
const isHttpMode = process.env.MCP_SERVER_MODE === "http";
|
|
14
|
+
if (!isHttpMode && !process.env.RESPONDIO_API_KEY) {
|
|
15
|
+
console.error("RESPONDIO_API_KEY is not set in the environment");
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
const protocol = isHttpMode
|
|
19
|
+
? new HttpStreamProtocol({
|
|
20
|
+
port: process.env.PORT ? parseInt(process.env.PORT) : APP_CONFIG.PORT,
|
|
21
|
+
apiBaseUrl: process.env.RESPONDIO_BASE_URL || API_CONFIG.BASE_URL,
|
|
22
|
+
debug: process.env.DEBUG === "true" || APP_CONFIG.debug,
|
|
23
|
+
})
|
|
24
|
+
: new StdioProtocol({
|
|
25
|
+
apiBaseUrl: process.env.RESPONDIO_BASE_URL || API_CONFIG.BASE_URL,
|
|
26
|
+
debug: process.env.DEBUG === "true" || APP_CONFIG.debug,
|
|
27
|
+
});
|
|
28
|
+
try {
|
|
29
|
+
await protocol.init();
|
|
30
|
+
// Initialize client monitoring after protocol is ready
|
|
31
|
+
initializeClientMonitoring();
|
|
32
|
+
console.warn("Respond.io MCP Server started successfully");
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
console.error("Failed to start protocol:", err);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
void startServer();
|
|
40
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAE5D;;;;;;GAMG;AACH,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE;IAC7B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,MAAM,CAAC;IAE1D,IAAI,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAClD,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,UAAU;QACzB,CAAC,CAAC,IAAI,kBAAkB,CAAC;YACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI;YACrE,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,UAAU,CAAC,QAAQ;YACjE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,MAAM,IAAI,UAAU,CAAC,KAAK;SACxD,CAAC;QACJ,CAAC,CAAC,IAAI,aAAa,CAAC;YAChB,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,UAAU,CAAC,QAAQ;YACjE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,MAAM,IAAI,UAAU,CAAC,KAAK;SACxD,CAAC,CAAC;IAEP,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACtB,uDAAuD;QACvD,0BAA0B,EAAE,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IAC7D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC;AAEF,KAAK,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Request, Response, NextFunction } from "express";
|
|
2
|
+
import { JWTPayload } from "../types.js";
|
|
3
|
+
declare module "express-serve-static-core" {
|
|
4
|
+
interface Request {
|
|
5
|
+
user?: JWTPayload;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Middleware to verify the authenticity of a JSON Web Token (JWT).
|
|
10
|
+
* This middleware checks for the presence of a Bearer token in the `Authorization` header,
|
|
11
|
+
* validates its format, and ensures the payload contains all the required fields.
|
|
12
|
+
* If the token is valid, the decoded payload is attached to the `req.user` property.
|
|
13
|
+
*
|
|
14
|
+
* @param {Request} req - The Express request object.
|
|
15
|
+
* @param {Response} res - The Express response object.
|
|
16
|
+
* @param {NextFunction} next - The next middleware function in the chain.
|
|
17
|
+
*/
|
|
18
|
+
export declare const tokenVerifier: (req: Request, res: Response, next: NextFunction) => void;
|
|
19
|
+
//# sourceMappingURL=TokenVerifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenVerifier.d.ts","sourceRoot":"","sources":["../../src/middlewares/TokenVerifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAYzC,OAAO,QAAQ,2BAA2B,CAAC;IACzC,UAAU,OAAO;QACf,IAAI,CAAC,EAAE,UAAU,CAAC;KACnB;CACF;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,GAAI,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,KAAG,IAqD/E,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// Define the validation schema for the JWT payload
|
|
3
|
+
const jwtPayloadSchema = z.object({
|
|
4
|
+
iat: z.number(),
|
|
5
|
+
id: z.number(),
|
|
6
|
+
spaceId: z.number(),
|
|
7
|
+
type: z.string(),
|
|
8
|
+
orgId: z.number(),
|
|
9
|
+
});
|
|
10
|
+
/**
|
|
11
|
+
* Middleware to verify the authenticity of a JSON Web Token (JWT).
|
|
12
|
+
* This middleware checks for the presence of a Bearer token in the `Authorization` header,
|
|
13
|
+
* validates its format, and ensures the payload contains all the required fields.
|
|
14
|
+
* If the token is valid, the decoded payload is attached to the `req.user` property.
|
|
15
|
+
*
|
|
16
|
+
* @param {Request} req - The Express request object.
|
|
17
|
+
* @param {Response} res - The Express response object.
|
|
18
|
+
* @param {NextFunction} next - The next middleware function in the chain.
|
|
19
|
+
*/
|
|
20
|
+
export const tokenVerifier = (req, res, next) => {
|
|
21
|
+
try {
|
|
22
|
+
const authHeader = req.headers.authorization;
|
|
23
|
+
if (!authHeader) {
|
|
24
|
+
res.status(401).json({ error: "No authorization header provided" });
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const parts = authHeader.split(" ");
|
|
28
|
+
if (parts.length !== 2 || parts[0] !== "Bearer") {
|
|
29
|
+
res
|
|
30
|
+
.status(401)
|
|
31
|
+
.json({ error: "Invalid authorization header format. Expected: Bearer <token>" });
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const token = parts[1];
|
|
35
|
+
const tokenParts = token.split(".");
|
|
36
|
+
if (tokenParts.length !== 3) {
|
|
37
|
+
res.status(401).json({ error: "Invalid JWT format" });
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const payload = JSON.parse(Buffer.from(tokenParts[1], "base64url").toString("utf-8"));
|
|
41
|
+
// Validate the payload against the schema
|
|
42
|
+
const validationResult = jwtPayloadSchema.safeParse(payload);
|
|
43
|
+
if (!validationResult.success) {
|
|
44
|
+
res.status(401).json({
|
|
45
|
+
error: "Invalid token payload",
|
|
46
|
+
details: validationResult.error.flatten(),
|
|
47
|
+
});
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
req.user = validationResult.data;
|
|
51
|
+
next();
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
if (error instanceof Error) {
|
|
55
|
+
res.status(401).json({
|
|
56
|
+
error: "Invalid token",
|
|
57
|
+
details: error.message,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
res.status(401).json({
|
|
62
|
+
error: "Invalid token",
|
|
63
|
+
details: "Unknown error",
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=TokenVerifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenVerifier.js","sourceRoot":"","sources":["../../src/middlewares/TokenVerifier.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,mDAAmD;AACnD,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;CAClB,CAAC,CAAC;AASH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAQ,EAAE;IACrF,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC;QAE7C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC,CAAC;YACpE,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;YAChD,GAAG;iBACA,MAAM,CAAC,GAAG,CAAC;iBACX,IAAI,CAAC,EAAE,KAAK,EAAE,+DAA+D,EAAE,CAAC,CAAC;YACpF,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CACxB,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAC5C,CAAC;QAEhB,0CAA0C;QAC1C,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC7D,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;YAC9B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,uBAAuB;gBAC9B,OAAO,EAAE,gBAAgB,CAAC,KAAK,CAAC,OAAO,EAAE;aAC1C,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,GAAG,CAAC,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC;QACjC,IAAI,EAAE,CAAC;IACT,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,KAAK,CAAC,OAAO;aACvB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,eAAe;aACzB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseProtocol.d.ts","sourceRoot":"","sources":["../../src/protocol/BaseProtocol.ts"],"names":[],"mappings":"AAAA,8BAAsB,YAAY;IAEhC,IAAI,IAAI,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC;CAGhC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseProtocol.js","sourceRoot":"","sources":["../../src/protocol/BaseProtocol.ts"],"names":[],"mappings":"AAAA,MAAM,OAAgB,YAAY;IAChC,6EAA6E;IAC7E,IAAI;QACF,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;CACF"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Express } from "express";
|
|
2
|
+
import { Server as HttpServer } from "http";
|
|
3
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
4
|
+
import { BaseProtocol } from "./BaseProtocol.js";
|
|
5
|
+
type InitOptions = {
|
|
6
|
+
port: number;
|
|
7
|
+
apiBaseUrl: string;
|
|
8
|
+
debug: boolean;
|
|
9
|
+
staticDir?: string;
|
|
10
|
+
corsOrigin?: string | string[] | true;
|
|
11
|
+
allowedHeaders?: string;
|
|
12
|
+
sessionIdGenerator?: (() => string) | undefined;
|
|
13
|
+
app?: Express;
|
|
14
|
+
};
|
|
15
|
+
type InitResult = {
|
|
16
|
+
app: Express;
|
|
17
|
+
httpServer: HttpServer;
|
|
18
|
+
transport: StreamableHTTPServerTransport;
|
|
19
|
+
close: () => Promise<void>;
|
|
20
|
+
port: number;
|
|
21
|
+
};
|
|
22
|
+
export declare class HttpStreamProtocol extends BaseProtocol {
|
|
23
|
+
private readonly options;
|
|
24
|
+
private app?;
|
|
25
|
+
private httpServer?;
|
|
26
|
+
private transport?;
|
|
27
|
+
private closing;
|
|
28
|
+
private readonly port;
|
|
29
|
+
private readonly apiBaseUrl;
|
|
30
|
+
private readonly debug;
|
|
31
|
+
constructor(options: InitOptions);
|
|
32
|
+
init(): Promise<InitResult>;
|
|
33
|
+
close(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=HttpStreamProtocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HttpStreamProtocol.d.ts","sourceRoot":"","sources":["../../src/protocol/HttpStreamProtocol.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAqB,OAAO,EAAE,MAAM,SAAS,CAAC;AAE9D,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAC;AAC5C,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAGnG,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIjD,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,CAAC;IAChD,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,GAAG,EAAE,OAAO,CAAC;IACb,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,6BAA6B,CAAC;IACzC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,YAAY;IAStC,OAAO,CAAC,QAAQ,CAAC,OAAO;IARpC,OAAO,CAAC,GAAG,CAAC,CAAU;IACtB,OAAO,CAAC,UAAU,CAAC,CAAa;IAChC,OAAO,CAAC,SAAS,CAAC,CAAgC;IAClD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;gBAEH,OAAO,EAAE,WAAW;IAOpC,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC;IAoI3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CASpC"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
import cors from "cors";
|
|
3
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
4
|
+
import { createServer } from "../server.js";
|
|
5
|
+
import { tokenVerifier } from "../middlewares/TokenVerifier.js";
|
|
6
|
+
import { BaseProtocol } from "./BaseProtocol.js";
|
|
7
|
+
import path from "path";
|
|
8
|
+
export class HttpStreamProtocol extends BaseProtocol {
|
|
9
|
+
options;
|
|
10
|
+
app;
|
|
11
|
+
httpServer;
|
|
12
|
+
transport;
|
|
13
|
+
closing = false;
|
|
14
|
+
port;
|
|
15
|
+
apiBaseUrl;
|
|
16
|
+
debug;
|
|
17
|
+
constructor(options) {
|
|
18
|
+
super();
|
|
19
|
+
this.options = options;
|
|
20
|
+
this.port = options.port;
|
|
21
|
+
this.apiBaseUrl = options.apiBaseUrl;
|
|
22
|
+
this.debug = options.debug;
|
|
23
|
+
}
|
|
24
|
+
async init() {
|
|
25
|
+
if (this.httpServer) {
|
|
26
|
+
return {
|
|
27
|
+
app: this.app,
|
|
28
|
+
httpServer: this.httpServer,
|
|
29
|
+
transport: this.transport,
|
|
30
|
+
close: this.close.bind(this),
|
|
31
|
+
port: this.port,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const app = this.options.app ?? express();
|
|
35
|
+
app.use(express.json());
|
|
36
|
+
app.use(express.static(this.options.staticDir ?? path.join(process.cwd(), "public")));
|
|
37
|
+
app.use(cors({
|
|
38
|
+
origin: this.options.corsOrigin ?? true,
|
|
39
|
+
methods: "*",
|
|
40
|
+
allowedHeaders: this.options.allowedHeaders ?? "Authorization, Origin, Content-Type, Accept, *",
|
|
41
|
+
}));
|
|
42
|
+
app.options("/mcp", cors());
|
|
43
|
+
const transport = new StreamableHTTPServerTransport({
|
|
44
|
+
sessionIdGenerator: this.options.sessionIdGenerator,
|
|
45
|
+
});
|
|
46
|
+
app.get("/health", (_req, res) => {
|
|
47
|
+
res.status(200).json({ status: "ok" });
|
|
48
|
+
});
|
|
49
|
+
app.use("/mcp", tokenVerifier);
|
|
50
|
+
app.post("/mcp", async (req, res) => {
|
|
51
|
+
console.error("Received MCP request:", req.body);
|
|
52
|
+
try {
|
|
53
|
+
await transport.handleRequest(req, res, req.body);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
console.error("Error handling MCP request:", error);
|
|
57
|
+
if (!res.headersSent) {
|
|
58
|
+
res.status(500).json({
|
|
59
|
+
jsonrpc: "2.0",
|
|
60
|
+
error: {
|
|
61
|
+
code: -32603,
|
|
62
|
+
message: "Internal server error",
|
|
63
|
+
},
|
|
64
|
+
id: null,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
const methodNotAllowed = (req, res) => {
|
|
70
|
+
console.error(`Received ${req.method} MCP request`);
|
|
71
|
+
res.status(405).json({
|
|
72
|
+
jsonrpc: "2.0",
|
|
73
|
+
error: {
|
|
74
|
+
code: -32000,
|
|
75
|
+
message: "Method not allowed.",
|
|
76
|
+
},
|
|
77
|
+
id: null,
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
app.get("/mcp", methodNotAllowed);
|
|
81
|
+
app.delete("/mcp", methodNotAllowed);
|
|
82
|
+
const { server } = createServer({
|
|
83
|
+
apiBaseUrl: this.apiBaseUrl,
|
|
84
|
+
debug: this.debug,
|
|
85
|
+
mode: "http",
|
|
86
|
+
});
|
|
87
|
+
try {
|
|
88
|
+
await server.connect(transport);
|
|
89
|
+
console.error("Server connected successfully");
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
console.error("Failed to set up the server:", error);
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
const httpServer = app.listen(this.port, () => {
|
|
96
|
+
console.error(`MCP Streamable HTTP Server listening on port ${this.port}`);
|
|
97
|
+
});
|
|
98
|
+
const onSigInt = async () => {
|
|
99
|
+
console.error("Shutting down server...");
|
|
100
|
+
await this.close().catch((err) => console.error("Error during shutdown:", err));
|
|
101
|
+
process.exit(0);
|
|
102
|
+
};
|
|
103
|
+
process.on("SIGINT", () => void onSigInt());
|
|
104
|
+
process.on("SIGTERM", () => void onSigInt());
|
|
105
|
+
this.app = app;
|
|
106
|
+
this.httpServer = httpServer;
|
|
107
|
+
this.transport = transport;
|
|
108
|
+
const originalClose = this.close.bind(this);
|
|
109
|
+
this.close = async () => {
|
|
110
|
+
if (this.closing) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
this.closing = true;
|
|
114
|
+
try {
|
|
115
|
+
console.error("Closing transport");
|
|
116
|
+
await transport.close();
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
console.error("Error closing transport:", error);
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
await server.close();
|
|
123
|
+
console.error("Server shutdown complete");
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
console.error("Error closing server:", error);
|
|
127
|
+
}
|
|
128
|
+
await originalClose();
|
|
129
|
+
};
|
|
130
|
+
return {
|
|
131
|
+
app,
|
|
132
|
+
httpServer,
|
|
133
|
+
transport,
|
|
134
|
+
close: this.close.bind(this),
|
|
135
|
+
port: this.port,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
async close() {
|
|
139
|
+
if (!this.httpServer) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
await new Promise((resolve, reject) => {
|
|
143
|
+
this.httpServer.close((err) => (err ? reject(err) : resolve()));
|
|
144
|
+
});
|
|
145
|
+
this.httpServer = undefined;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=HttpStreamProtocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HttpStreamProtocol.js","sourceRoot":"","sources":["../../src/protocol/HttpStreamProtocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseProtocol } from "./BaseProtocol.js";
|
|
2
|
+
type InitOptions = {
|
|
3
|
+
apiBaseUrl: string;
|
|
4
|
+
debug: boolean;
|
|
5
|
+
};
|
|
6
|
+
export declare class StdioProtocol extends BaseProtocol {
|
|
7
|
+
private readonly apiBaseUrl;
|
|
8
|
+
private readonly debug;
|
|
9
|
+
constructor(options: InitOptions);
|
|
10
|
+
init(): Promise<void>;
|
|
11
|
+
close(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=StdioProtocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StdioProtocol.d.ts","sourceRoot":"","sources":["../../src/protocol/StdioProtocol.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,qBAAa,aAAc,SAAQ,YAAY;IAC7C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;gBAEpB,OAAO,EAAE,WAAW;IAMnB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAGpC"}
|