@deadragdoll/tellymcp 0.0.12 → 0.0.14
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/.env.example.client +5 -1
- package/.env.example.gateway +16 -1
- package/CHANGELOG.md +30 -0
- package/README-ru.md +33 -0
- package/README.md +33 -0
- package/TOOLS.md +384 -9
- package/config/templates/env.both.template +15 -2
- package/config/templates/env.client.template +5 -2
- package/config/templates/env.gateway.template +15 -2
- package/dist/cli.js +137 -2
- package/dist/services/features/telegram-mcp/browser.service.js +56 -1
- package/dist/services/features/telegram-mcp/file-content.service.js +94 -0
- package/dist/services/features/telegram-mcp/gateway-delivery.service.js +5 -1
- package/dist/services/features/telegram-mcp/gateway-socket.service.js +43 -11
- package/dist/services/features/telegram-mcp/mcp-http.service.js +1 -0
- package/dist/services/features/telegram-mcp/mcp-server.service.js +30 -0
- package/dist/services/features/telegram-mcp/src/app/bootstrap/runtime.js +23 -1
- package/dist/services/features/telegram-mcp/src/app/config/env.js +132 -2
- package/dist/services/features/telegram-mcp/src/app/http.js +139 -99
- package/dist/services/features/telegram-mcp/src/app/oauthFacade.js +642 -0
- package/dist/services/features/telegram-mcp/src/app/webapp/assets.js +151 -170
- package/dist/services/features/telegram-mcp/src/app/webapp/auth.js +96 -99
- package/dist/services/features/telegram-mcp/src/entities/request/model/schema.js +205 -17
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserAttachActiveTabTool.js +28 -0
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserAttachTabTool.js +28 -0
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserClickTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserDetachTabTool.js +28 -0
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserDomTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserFillTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserInjectScriptTool.js +28 -0
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserListAttachedInstancesTool.js +33 -0
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserListTabsTool.js +33 -0
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserPressTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserRecordingStartTool.js +28 -0
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserRecordingStatusTool.js +28 -0
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserRecordingStopTool.js +28 -0
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserScreenshotTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserService.js +890 -23
- package/dist/services/features/telegram-mcp/src/features/browser-attach/model/browserRecordingBundle.js +536 -0
- package/dist/services/features/telegram-mcp/src/features/browser-attach/model/firefoxAttachRegistry.js +80 -0
- package/dist/services/features/telegram-mcp/src/features/browser-attach/model/firefoxAttachServer.js +736 -0
- package/dist/services/features/telegram-mcp/src/features/browser-attach/model/types.js +188 -0
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/collaborationService.js +2 -0
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileService.js +6 -3
- package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayClientAccess.js +4 -1
- package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/gatewayHttpService.js +33 -35
- package/dist/services/features/telegram-mcp/src/features/file-content/model/getFileListTool.js +33 -0
- package/dist/services/features/telegram-mcp/src/features/file-content/model/getFileService.js +327 -0
- package/dist/services/features/telegram-mcp/src/features/file-content/model/getFileTool.js +81 -0
- package/dist/services/features/telegram-mcp/src/features/file-content/model/temporaryFileLinkStore.js +307 -0
- package/dist/services/features/telegram-mcp/src/features/file-content/model/workspaceFilePolicy.js +115 -0
- package/dist/services/features/telegram-mcp/src/features/notify/model/notifyService.js +5 -1
- package/dist/services/features/telegram-mcp/src/shared/integrations/redis/stateStore.js +28 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transport.js +3 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportFileHandoffActions.js +6 -3
- package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/client.js +29 -6
- package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/ptyRegistry.js +100 -2
- package/dist/services/features/telegram-mcp/src/shared/lib/bodyLimits.js +63 -0
- package/dist/services/features/telegram-mcp/src/shared/lib/gatewayAuth.js +13 -0
- package/dist/services/features/telegram-mcp/src/shared/lib/time/localTimestamp.js +21 -0
- package/docs/CHAT_CONNECTOR.md +134 -0
- package/docs/STANDALONE-ru.md +55 -6
- package/docs/STANDALONE.md +55 -6
- package/package.json +10 -5
- package/packages/chrome-attach-extension/dist/background.js +1735 -0
- package/packages/chrome-attach-extension/dist/icon.svg +6 -0
- package/packages/chrome-attach-extension/dist/manifest.json +37 -0
- package/packages/chrome-attach-extension/dist/options.html +312 -0
- package/packages/chrome-attach-extension/dist/options.js +606 -0
- package/packages/chrome-attach-extension/dist/popup.html +93 -0
- package/packages/chrome-attach-extension/dist/popup.js +79 -0
- package/packages/chrome-attach-extension/dist/recorder-content.js +96 -0
- package/packages/chrome-attach-extension/dist/recorder-page.js +282 -0
- package/packages/firefox-attach-extension/README.md +13 -0
- package/packages/firefox-attach-extension/dist/background.js +1622 -0
- package/packages/firefox-attach-extension/dist/icon.svg +6 -0
- package/packages/firefox-attach-extension/dist/manifest.json +44 -0
- package/packages/firefox-attach-extension/dist/options.html +312 -0
- package/packages/firefox-attach-extension/dist/options.js +540 -0
- package/packages/firefox-attach-extension/dist/popup.html +93 -0
- package/packages/firefox-attach-extension/dist/popup.js +64 -0
- package/packages/firefox-attach-extension/dist/recorder-content.js +90 -0
- package/packages/firefox-attach-extension/dist/recorder-page.js +318 -0
|
@@ -124,27 +124,42 @@ function normalizeTelegramWebAppInitData(rawInitData) {
|
|
|
124
124
|
}
|
|
125
125
|
return normalized.trim();
|
|
126
126
|
}
|
|
127
|
-
function
|
|
128
|
-
if (!user || typeof user !== "object"
|
|
127
|
+
function normalizeTelegramWebAppUser(user) {
|
|
128
|
+
if (!user || typeof user !== "object") {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
const record = user;
|
|
132
|
+
if (typeof record.id !== "number" ||
|
|
133
|
+
!Number.isSafeInteger(record.id) ||
|
|
134
|
+
record.id <= 0) {
|
|
129
135
|
return null;
|
|
130
136
|
}
|
|
131
137
|
return {
|
|
132
|
-
id:
|
|
133
|
-
...(typeof
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
...(typeof
|
|
137
|
-
? {
|
|
138
|
+
id: record.id,
|
|
139
|
+
...(typeof record.first_name === "string"
|
|
140
|
+
? { first_name: record.first_name }
|
|
141
|
+
: {}),
|
|
142
|
+
...(typeof record.last_name === "string"
|
|
143
|
+
? { last_name: record.last_name }
|
|
144
|
+
: {}),
|
|
145
|
+
...(typeof record.username === "string"
|
|
146
|
+
? { username: record.username }
|
|
147
|
+
: {}),
|
|
148
|
+
...(typeof record.language_code === "string"
|
|
149
|
+
? { language_code: record.language_code }
|
|
150
|
+
: {}),
|
|
151
|
+
...(typeof record.photo_url === "string"
|
|
152
|
+
? { photo_url: record.photo_url }
|
|
138
153
|
: {}),
|
|
139
|
-
...(typeof user.photo_url === "string" ? { photo_url: user.photo_url } : {}),
|
|
140
154
|
};
|
|
141
155
|
}
|
|
142
|
-
function
|
|
156
|
+
function validateOfficialRawHash(rawInitData, botToken) {
|
|
143
157
|
const params = new URLSearchParams(rawInitData);
|
|
144
|
-
const
|
|
145
|
-
if (!
|
|
146
|
-
|
|
158
|
+
const receivedHashes = params.getAll("hash");
|
|
159
|
+
if (receivedHashes.length !== 1 || !receivedHashes[0]) {
|
|
160
|
+
throw new Error("Telegram WebApp initData hash validation failed.");
|
|
147
161
|
}
|
|
162
|
+
const receivedHash = receivedHashes[0];
|
|
148
163
|
const checkString = [...params.entries()]
|
|
149
164
|
.filter(([key, value]) => key !== "hash" && value !== undefined)
|
|
150
165
|
.sort((left, right) => left[0].localeCompare(right[0]))
|
|
@@ -158,83 +173,86 @@ function buildOfficialRawValidation(rawInitData, botToken) {
|
|
|
158
173
|
.digest("hex");
|
|
159
174
|
const matches = computed.length === receivedHash.length &&
|
|
160
175
|
(0, node_crypto_1.timingSafeEqual)(Buffer.from(computed, "utf8"), Buffer.from(receivedHash, "utf8"));
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
matches,
|
|
166
|
-
};
|
|
176
|
+
if (!matches) {
|
|
177
|
+
throw new Error("Telegram WebApp initData hash validation failed.");
|
|
178
|
+
}
|
|
179
|
+
return params;
|
|
167
180
|
}
|
|
168
|
-
function
|
|
169
|
-
|
|
170
|
-
|
|
181
|
+
function readSignedParam(params, key, required) {
|
|
182
|
+
const values = params.getAll(key);
|
|
183
|
+
if (values.length > 1) {
|
|
184
|
+
throw new Error(`Telegram WebApp initData contains duplicate ${key}.`);
|
|
171
185
|
}
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
186
|
+
const value = values[0];
|
|
187
|
+
if (required && (value === undefined || value.length === 0)) {
|
|
188
|
+
throw new Error(`Telegram WebApp initData is missing ${key}.`);
|
|
189
|
+
}
|
|
190
|
+
return value;
|
|
191
|
+
}
|
|
192
|
+
function parseSignedUser(value) {
|
|
193
|
+
let parsed;
|
|
194
|
+
try {
|
|
195
|
+
parsed = JSON.parse(value);
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
throw new Error("Telegram WebApp signed user is malformed.");
|
|
199
|
+
}
|
|
200
|
+
const user = normalizeTelegramWebAppUser(parsed);
|
|
201
|
+
if (!user) {
|
|
202
|
+
throw new Error("Telegram WebApp signed user is invalid.");
|
|
203
|
+
}
|
|
204
|
+
return user;
|
|
205
|
+
}
|
|
206
|
+
function assertUnsafeDataMatchesSigned(unsafe, signed) {
|
|
207
|
+
const unsafeUser = normalizeTelegramWebAppUser(unsafe.user);
|
|
208
|
+
if (!unsafeUser ||
|
|
209
|
+
JSON.stringify(unsafeUser) !== JSON.stringify(signed.user)) {
|
|
210
|
+
throw new Error("Telegram WebApp unsafe user does not match signed initData.");
|
|
211
|
+
}
|
|
212
|
+
const unsafeAuthDate = typeof unsafe.auth_date === "number" || typeof unsafe.auth_date === "string"
|
|
213
|
+
? String(unsafe.auth_date)
|
|
178
214
|
: undefined;
|
|
179
|
-
if (
|
|
180
|
-
|
|
215
|
+
if (unsafeAuthDate !== String(signed.authDate)) {
|
|
216
|
+
throw new Error("Telegram WebApp unsafe auth_date does not match signed initData.");
|
|
217
|
+
}
|
|
218
|
+
if (unsafe.query_id !== signed.queryId) {
|
|
219
|
+
throw new Error("Telegram WebApp unsafe query_id does not match signed initData.");
|
|
220
|
+
}
|
|
221
|
+
if (unsafe.start_param !== signed.startParam) {
|
|
222
|
+
throw new Error("Telegram WebApp unsafe start_param does not match signed initData.");
|
|
223
|
+
}
|
|
224
|
+
if (unsafe.hash !== undefined && unsafe.hash !== signed.hash) {
|
|
225
|
+
throw new Error("Telegram WebApp unsafe hash does not match signed initData.");
|
|
181
226
|
}
|
|
182
|
-
const params = {
|
|
183
|
-
id: user.id,
|
|
184
|
-
first_name: user.first_name,
|
|
185
|
-
last_name: user.last_name,
|
|
186
|
-
username: user.username,
|
|
187
|
-
photo_url: user.photo_url,
|
|
188
|
-
auth_date: authDateValue,
|
|
189
|
-
};
|
|
190
|
-
const checkString = Object.keys(params)
|
|
191
|
-
.sort()
|
|
192
|
-
.filter((key) => params[key] !== undefined)
|
|
193
|
-
.map((key) => `${key}=${params[key]}`)
|
|
194
|
-
.join("\n");
|
|
195
|
-
const secretKey = (0, node_crypto_1.createHash)("sha256")
|
|
196
|
-
.update(botToken.trim())
|
|
197
|
-
.digest();
|
|
198
|
-
const computed = (0, node_crypto_1.createHmac)("sha256", secretKey)
|
|
199
|
-
.update(checkString)
|
|
200
|
-
.digest("hex");
|
|
201
|
-
const matches = computed.length === receivedHash.length &&
|
|
202
|
-
(0, node_crypto_1.timingSafeEqual)(Buffer.from(computed, "utf8"), Buffer.from(receivedHash, "utf8"));
|
|
203
|
-
return {
|
|
204
|
-
checkString,
|
|
205
|
-
computedHash: computed,
|
|
206
|
-
providedHash: receivedHash,
|
|
207
|
-
matches,
|
|
208
|
-
};
|
|
209
227
|
}
|
|
210
228
|
function validateTelegramWebAppInitData(rawInitData, unsafeInitData, botToken, maxAgeSeconds) {
|
|
211
229
|
const normalizedRaw = rawInitData
|
|
212
230
|
? normalizeTelegramWebAppInitData(rawInitData)
|
|
213
231
|
: "";
|
|
214
|
-
|
|
215
|
-
if (!normalizedRaw && !normalizedUnsafe) {
|
|
232
|
+
if (!normalizedRaw) {
|
|
216
233
|
throw new Error("Telegram WebApp initData is empty.");
|
|
217
234
|
}
|
|
218
|
-
const
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
if (!normalizedUnsafe) {
|
|
224
|
-
throw new Error("Telegram WebApp unsafe init data is missing.");
|
|
225
|
-
}
|
|
226
|
-
const user = normalizeUnsafeUser(normalizedUnsafe.user);
|
|
227
|
-
const authDateRaw = typeof normalizedUnsafe.auth_date === "number" ||
|
|
228
|
-
typeof normalizedUnsafe.auth_date === "string"
|
|
229
|
-
? String(normalizedUnsafe.auth_date)
|
|
230
|
-
: null;
|
|
231
|
-
if (!authDateRaw || !user) {
|
|
232
|
-
throw new Error("Telegram WebApp initData is missing auth_date or user.");
|
|
235
|
+
const signedParams = validateOfficialRawHash(normalizedRaw, botToken);
|
|
236
|
+
const user = parseSignedUser(readSignedParam(signedParams, "user", true));
|
|
237
|
+
const authDateRaw = readSignedParam(signedParams, "auth_date", true);
|
|
238
|
+
if (!/^\d+$/.test(authDateRaw)) {
|
|
239
|
+
throw new Error("Telegram WebApp auth_date is invalid.");
|
|
233
240
|
}
|
|
234
|
-
const authDate = Number
|
|
235
|
-
if (!Number.
|
|
241
|
+
const authDate = Number(authDateRaw);
|
|
242
|
+
if (!Number.isSafeInteger(authDate) || authDate <= 0) {
|
|
236
243
|
throw new Error("Telegram WebApp auth_date is invalid.");
|
|
237
244
|
}
|
|
245
|
+
const queryId = readSignedParam(signedParams, "query_id", false);
|
|
246
|
+
const startParam = readSignedParam(signedParams, "start_param", false);
|
|
247
|
+
if (unsafeInitData) {
|
|
248
|
+
assertUnsafeDataMatchesSigned(unsafeInitData, {
|
|
249
|
+
user,
|
|
250
|
+
authDate,
|
|
251
|
+
...(queryId !== undefined ? { queryId } : {}),
|
|
252
|
+
...(startParam !== undefined ? { startParam } : {}),
|
|
253
|
+
hash: readSignedParam(signedParams, "hash", true),
|
|
254
|
+
});
|
|
255
|
+
}
|
|
238
256
|
const nowSeconds = Math.floor(Date.now() / 1000);
|
|
239
257
|
if (nowSeconds - authDate > maxAgeSeconds) {
|
|
240
258
|
throw new Error("Telegram WebApp initData is expired.");
|
|
@@ -243,28 +261,7 @@ function validateTelegramWebAppInitData(rawInitData, unsafeInitData, botToken, m
|
|
|
243
261
|
user,
|
|
244
262
|
authDate,
|
|
245
263
|
rawInitData: normalizedRaw,
|
|
246
|
-
...(
|
|
247
|
-
|
|
248
|
-
: {}),
|
|
249
|
-
...(typeof normalizedUnsafe.start_param === "string"
|
|
250
|
-
? { startParam: normalizedUnsafe.start_param }
|
|
251
|
-
: {}),
|
|
252
|
-
validationDebug: {
|
|
253
|
-
providedHash: officialRawValidation?.providedHash ??
|
|
254
|
-
userFieldsValidation?.providedHash ??
|
|
255
|
-
"",
|
|
256
|
-
officialRaw: {
|
|
257
|
-
checkString: officialRawValidation?.checkString ?? "",
|
|
258
|
-
computedHash: officialRawValidation?.computedHash ?? "",
|
|
259
|
-
matches: officialRawValidation?.matches ?? false,
|
|
260
|
-
},
|
|
261
|
-
userFields: userFieldsValidation
|
|
262
|
-
? {
|
|
263
|
-
checkString: userFieldsValidation.checkString,
|
|
264
|
-
computedHash: userFieldsValidation.computedHash,
|
|
265
|
-
matches: userFieldsValidation.matches,
|
|
266
|
-
}
|
|
267
|
-
: null,
|
|
268
|
-
},
|
|
264
|
+
...(queryId !== undefined ? { queryId } : {}),
|
|
265
|
+
...(startParam !== undefined ? { startParam } : {}),
|
|
269
266
|
};
|
|
270
267
|
}
|
|
@@ -33,9 +33,11 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.
|
|
37
|
-
exports.markXchangeRecordReadOutputSchema = exports.markXchangeRecordReadInputSchema = exports.getXchangeRecordOutputSchema = exports.getXchangeRecordInputSchema = exports.listXchangeRecordsOutputSchema = exports.listXchangeRecordsInputSchema = exports.sendPartnerNoteOutputSchema = void 0;
|
|
36
|
+
exports.browserWaitForInputSchema = exports.browserInjectScriptOutputSchema = exports.browserInjectScriptInputSchema = exports.browserPressOutputSchema = exports.browserPressInputSchema = exports.browserFillOutputSchema = exports.browserFillInputSchema = exports.browserClickOutputSchema = exports.browserClickInputSchema = exports.browserReloadOutputSchema = exports.browserReloadInputSchema = exports.browserRecordingStatusOutputSchema = exports.browserRecordingStatusInputSchema = exports.browserRecordingStopOutputSchema = exports.browserRecordingStopInputSchema = exports.browserRecordingStartOutputSchema = exports.browserRecordingStartInputSchema = exports.browserDetachTabOutputSchema = exports.browserDetachTabInputSchema = exports.browserAttachTabOutputSchema = exports.browserAttachTabInputSchema = exports.browserAttachActiveTabInputSchema = exports.browserListTabsOutputSchema = exports.browserListTabsInputSchema = exports.browserListAttachedInstancesOutputSchema = exports.browserListAttachedInstancesInputSchema = exports.browserOpenOutputSchema = exports.browserOpenInputSchema = exports.clearSessionContextOutputSchema = exports.clearSessionContextInputSchema = exports.getSessionContextOutputSchema = exports.getSessionContextInputSchema = exports.setSessionContextOutputSchema = exports.renameSessionOutputSchema = exports.renameSessionInputSchema = exports.setSessionContextInputSchema = exports.refreshToolsMarkdownOutputSchema = exports.refreshToolsMarkdownInputSchema = exports.listGatewaySessionsOutputSchema = exports.listGatewaySessionsInputSchema = exports.getFileListOutputSchema = exports.getFileListInputSchema = exports.getFileOutputSchema = exports.getFileInputSchema = exports.sendFileToTelegramOutputSchema = exports.sendFileToTelegramInputSchema = exports.notifyTelegramOutputSchema = exports.notifyTelegramInputSchema = exports.askUserTelegramOutputSchema = exports.askUserTelegramInputSchema = void 0;
|
|
37
|
+
exports.markXchangeRecordReadOutputSchema = exports.markXchangeRecordReadInputSchema = exports.getXchangeRecordOutputSchema = exports.getXchangeRecordInputSchema = exports.listXchangeRecordsOutputSchema = exports.listXchangeRecordsInputSchema = exports.sendPartnerNoteOutputSchema = exports.sendPartnerFileInputSchema = exports.sendPartnerNoteInputSchema = exports.browserCloseOutputSchema = exports.browserCloseInputSchema = exports.browserScreenshotOutputSchema = exports.browserScreenshotInputSchema = exports.browserComputedStyleOutputSchema = exports.browserComputedStyleInputSchema = exports.browserDomOutputSchema = exports.browserDomInputSchema = exports.browserClearLogsOutputSchema = exports.browserClearLogsInputSchema = exports.browserNetworkFailuresOutputSchema = exports.browserNetworkFailuresInputSchema = exports.browserErrorsOutputSchema = exports.browserErrorsInputSchema = exports.browserConsoleOutputSchema = exports.browserConsoleInputSchema = exports.browserWaitForUrlOutputSchema = exports.browserWaitForUrlInputSchema = exports.browserWaitForOutputSchema = void 0;
|
|
38
38
|
const z = __importStar(require("zod/v4"));
|
|
39
|
+
const bodyLimits_1 = require("../../../shared/lib/bodyLimits");
|
|
40
|
+
const bodyStringSchema = z.string().max(bodyLimits_1.MAX_BODY_SIZE_BYTES);
|
|
39
41
|
const partnerNoteKindSchema = z.enum([
|
|
40
42
|
"share",
|
|
41
43
|
"question",
|
|
@@ -87,6 +89,45 @@ exports.sendFileToTelegramOutputSchema = z.object({
|
|
|
87
89
|
sent: z.boolean(),
|
|
88
90
|
message_id: z.number().int().positive().optional(),
|
|
89
91
|
});
|
|
92
|
+
exports.getFileInputSchema = z
|
|
93
|
+
.object({
|
|
94
|
+
session_id: z.string().trim().min(1).optional(),
|
|
95
|
+
file_path: z.string().trim().min(1).optional(),
|
|
96
|
+
selector: z.enum(["latest_screenshot"]).optional(),
|
|
97
|
+
type: z.enum(["url", "image", "text", "base64"]).optional(),
|
|
98
|
+
})
|
|
99
|
+
.refine((input) => Boolean(input.file_path) !== Boolean(input.selector), {
|
|
100
|
+
message: "Provide exactly one of file_path or selector.",
|
|
101
|
+
});
|
|
102
|
+
exports.getFileOutputSchema = z.object({
|
|
103
|
+
type: z.enum(["url", "image", "text", "base64"]),
|
|
104
|
+
data: bodyStringSchema,
|
|
105
|
+
mimetype: z.string().trim().min(1),
|
|
106
|
+
filename: z.string().trim().min(1),
|
|
107
|
+
size_bytes: z.number().int().nonnegative(),
|
|
108
|
+
expires_at: z.string().trim().min(1).optional(),
|
|
109
|
+
});
|
|
110
|
+
const getFileListSourceSchema = z.enum([
|
|
111
|
+
"telegram-upload",
|
|
112
|
+
"browser-screenshot",
|
|
113
|
+
"partner-artifact",
|
|
114
|
+
]);
|
|
115
|
+
exports.getFileListInputSchema = z.object({
|
|
116
|
+
session_id: z.string().trim().min(1).optional(),
|
|
117
|
+
source: getFileListSourceSchema.optional(),
|
|
118
|
+
limit: z.number().int().positive().max(200).optional(),
|
|
119
|
+
});
|
|
120
|
+
exports.getFileListOutputSchema = z.object({
|
|
121
|
+
total: z.number().int().nonnegative(),
|
|
122
|
+
files: z.array(z.object({
|
|
123
|
+
file_path: z.string().trim().min(1),
|
|
124
|
+
filename: z.string().trim().min(1),
|
|
125
|
+
mimetype: z.string().trim().min(1),
|
|
126
|
+
source: getFileListSourceSchema,
|
|
127
|
+
size_bytes: z.number().int().nonnegative().optional(),
|
|
128
|
+
created_at: z.string().trim().min(1),
|
|
129
|
+
})),
|
|
130
|
+
});
|
|
90
131
|
exports.listGatewaySessionsInputSchema = z.object({
|
|
91
132
|
client_uuid: z.string().trim().min(1).optional(),
|
|
92
133
|
connected_only: z.boolean().optional(),
|
|
@@ -210,6 +251,131 @@ exports.browserOpenOutputSchema = z.object({
|
|
|
210
251
|
viewport_width: z.number().int().positive().optional(),
|
|
211
252
|
viewport_height: z.number().int().positive().optional(),
|
|
212
253
|
});
|
|
254
|
+
exports.browserListAttachedInstancesInputSchema = z.object({
|
|
255
|
+
session_id: z.string().trim().min(1).optional(),
|
|
256
|
+
});
|
|
257
|
+
exports.browserListAttachedInstancesOutputSchema = z.object({
|
|
258
|
+
session_id: z.string().trim().min(1).optional(),
|
|
259
|
+
total: z.number().int().nonnegative(),
|
|
260
|
+
instances: z.array(z.object({
|
|
261
|
+
instance_id: z.string().trim().min(1),
|
|
262
|
+
browser: z.enum(["firefox", "chrome"]),
|
|
263
|
+
extension_version: z.string().trim().min(1),
|
|
264
|
+
profile_name: z.string().trim().min(1).optional(),
|
|
265
|
+
connected_at: z.string().trim().min(1),
|
|
266
|
+
last_seen_at: z.string().trim().min(1),
|
|
267
|
+
capabilities: z.array(z.string().trim().min(1)),
|
|
268
|
+
tab_count: z.number().int().nonnegative(),
|
|
269
|
+
active_tab: z
|
|
270
|
+
.object({
|
|
271
|
+
tab_id: z.number().int().nonnegative(),
|
|
272
|
+
window_id: z.number().int().nonnegative().optional(),
|
|
273
|
+
active: z.boolean(),
|
|
274
|
+
title: z.string(),
|
|
275
|
+
url: z.string(),
|
|
276
|
+
status: z.string().optional(),
|
|
277
|
+
})
|
|
278
|
+
.optional(),
|
|
279
|
+
})),
|
|
280
|
+
});
|
|
281
|
+
exports.browserListTabsInputSchema = z.object({
|
|
282
|
+
session_id: z.string().trim().min(1).optional(),
|
|
283
|
+
instance_id: z.string().trim().min(1).optional(),
|
|
284
|
+
});
|
|
285
|
+
exports.browserListTabsOutputSchema = z.object({
|
|
286
|
+
session_id: z.string().trim().min(1).optional(),
|
|
287
|
+
instance_id: z.string().trim().min(1),
|
|
288
|
+
total: z.number().int().nonnegative(),
|
|
289
|
+
tabs: z.array(z.object({
|
|
290
|
+
tab_id: z.number().int().nonnegative(),
|
|
291
|
+
window_id: z.number().int().nonnegative().optional(),
|
|
292
|
+
active: z.boolean(),
|
|
293
|
+
selected: z.boolean().optional(),
|
|
294
|
+
title: z.string(),
|
|
295
|
+
url: z.string(),
|
|
296
|
+
status: z.string().optional(),
|
|
297
|
+
})),
|
|
298
|
+
});
|
|
299
|
+
exports.browserAttachActiveTabInputSchema = z.object({
|
|
300
|
+
session_id: z.string().trim().min(1).optional(),
|
|
301
|
+
instance_id: z.string().trim().min(1).optional(),
|
|
302
|
+
});
|
|
303
|
+
exports.browserAttachTabInputSchema = z.object({
|
|
304
|
+
session_id: z.string().trim().min(1).optional(),
|
|
305
|
+
instance_id: z.string().trim().min(1).optional(),
|
|
306
|
+
tab_id: z.number().int().nonnegative(),
|
|
307
|
+
});
|
|
308
|
+
exports.browserAttachTabOutputSchema = z.object({
|
|
309
|
+
session_id: z.string().trim().min(1),
|
|
310
|
+
backend: z.literal("firefox-attached"),
|
|
311
|
+
instance_id: z.string().trim().min(1),
|
|
312
|
+
tab_id: z.number().int().nonnegative(),
|
|
313
|
+
attached_at: z.string().trim().min(1),
|
|
314
|
+
title: z.string().optional(),
|
|
315
|
+
url: z.string().optional(),
|
|
316
|
+
});
|
|
317
|
+
exports.browserDetachTabInputSchema = z.object({
|
|
318
|
+
session_id: z.string().trim().min(1).optional(),
|
|
319
|
+
});
|
|
320
|
+
exports.browserDetachTabOutputSchema = z.object({
|
|
321
|
+
session_id: z.string().trim().min(1),
|
|
322
|
+
detached: z.boolean(),
|
|
323
|
+
});
|
|
324
|
+
exports.browserRecordingStartInputSchema = z.object({
|
|
325
|
+
session_id: z.string().trim().min(1).optional(),
|
|
326
|
+
instance_id: z.string().trim().min(1).optional(),
|
|
327
|
+
});
|
|
328
|
+
exports.browserRecordingStartOutputSchema = z.object({
|
|
329
|
+
session_id: z.string().trim().min(1),
|
|
330
|
+
backend: z.literal("firefox-attached"),
|
|
331
|
+
started: z.boolean(),
|
|
332
|
+
recording_id: z.string().trim().min(1),
|
|
333
|
+
instance_id: z.string().trim().min(1),
|
|
334
|
+
tab_id: z.number().int().nonnegative(),
|
|
335
|
+
tab_title: z.string().optional(),
|
|
336
|
+
tab_url: z.string().optional(),
|
|
337
|
+
bundle_dir_name: z.string().trim().min(1),
|
|
338
|
+
bundle_relative_path: z.string().trim().min(1),
|
|
339
|
+
bundle_path: z.string().trim().min(1),
|
|
340
|
+
started_at: z.string().trim().min(1),
|
|
341
|
+
});
|
|
342
|
+
exports.browserRecordingStopInputSchema = z.object({
|
|
343
|
+
session_id: z.string().trim().min(1).optional(),
|
|
344
|
+
});
|
|
345
|
+
exports.browserRecordingStopOutputSchema = z.object({
|
|
346
|
+
session_id: z.string().trim().min(1),
|
|
347
|
+
stopped: z.boolean(),
|
|
348
|
+
recording_id: z.string().trim().min(1).optional(),
|
|
349
|
+
bundle_dir_name: z.string().trim().min(1).optional(),
|
|
350
|
+
bundle_relative_path: z.string().trim().min(1).optional(),
|
|
351
|
+
bundle_path: z.string().trim().min(1).optional(),
|
|
352
|
+
stopped_at: z.string().trim().min(1).optional(),
|
|
353
|
+
});
|
|
354
|
+
exports.browserRecordingStatusInputSchema = z.object({
|
|
355
|
+
session_id: z.string().trim().min(1).optional(),
|
|
356
|
+
});
|
|
357
|
+
exports.browserRecordingStatusOutputSchema = z.object({
|
|
358
|
+
session_id: z.string().trim().min(1),
|
|
359
|
+
active: z.boolean(),
|
|
360
|
+
recording: z
|
|
361
|
+
.object({
|
|
362
|
+
backend: z.literal("firefox-attached"),
|
|
363
|
+
recording_id: z.string().trim().min(1),
|
|
364
|
+
instance_id: z.string().trim().min(1),
|
|
365
|
+
tab_id: z.number().int().nonnegative(),
|
|
366
|
+
tab_title: z.string().optional(),
|
|
367
|
+
tab_url: z.string().optional(),
|
|
368
|
+
bundle_dir_name: z.string().trim().min(1),
|
|
369
|
+
bundle_relative_path: z.string().trim().min(1),
|
|
370
|
+
bundle_path: z.string().trim().min(1),
|
|
371
|
+
started_at: z.string().trim().min(1),
|
|
372
|
+
stopped_at: z.string().trim().min(1).optional(),
|
|
373
|
+
status: z.enum(["recording", "stopped"]),
|
|
374
|
+
event_count: z.number().int().nonnegative(),
|
|
375
|
+
last_event_at: z.string().trim().min(1).optional(),
|
|
376
|
+
})
|
|
377
|
+
.optional(),
|
|
378
|
+
});
|
|
213
379
|
exports.browserReloadInputSchema = z.object({
|
|
214
380
|
session_id: z.string().trim().min(1).optional(),
|
|
215
381
|
wait_until: z
|
|
@@ -219,7 +385,7 @@ exports.browserReloadInputSchema = z.object({
|
|
|
219
385
|
exports.browserReloadOutputSchema = z.object({
|
|
220
386
|
session_id: z.string(),
|
|
221
387
|
reloaded: z.boolean(),
|
|
222
|
-
url: z.string()
|
|
388
|
+
url: z.string(),
|
|
223
389
|
title: z.string().optional(),
|
|
224
390
|
});
|
|
225
391
|
const browserLocatorInputShape = {
|
|
@@ -242,7 +408,7 @@ exports.browserClickOutputSchema = z.object({
|
|
|
242
408
|
ai_tag: z.string().optional(),
|
|
243
409
|
selector: z.string().optional(),
|
|
244
410
|
text: z.string().optional(),
|
|
245
|
-
url: z.string()
|
|
411
|
+
url: z.string(),
|
|
246
412
|
title: z.string().optional(),
|
|
247
413
|
});
|
|
248
414
|
exports.browserFillInputSchema = z
|
|
@@ -261,7 +427,7 @@ exports.browserFillOutputSchema = z.object({
|
|
|
261
427
|
selector: z.string().optional(),
|
|
262
428
|
text: z.string().optional(),
|
|
263
429
|
value_length: z.number().int().nonnegative(),
|
|
264
|
-
url: z.string()
|
|
430
|
+
url: z.string(),
|
|
265
431
|
title: z.string().optional(),
|
|
266
432
|
});
|
|
267
433
|
exports.browserPressInputSchema = z.object({
|
|
@@ -275,7 +441,27 @@ exports.browserPressOutputSchema = z.object({
|
|
|
275
441
|
ai_tag: z.string().optional(),
|
|
276
442
|
selector: z.string().optional(),
|
|
277
443
|
text: z.string().optional(),
|
|
278
|
-
url: z.string()
|
|
444
|
+
url: z.string(),
|
|
445
|
+
title: z.string().optional(),
|
|
446
|
+
});
|
|
447
|
+
exports.browserInjectScriptInputSchema = z
|
|
448
|
+
.object({
|
|
449
|
+
session_id: z.string().trim().min(1).optional(),
|
|
450
|
+
source: z.string().optional(),
|
|
451
|
+
file_path: z.string().trim().min(1).optional(),
|
|
452
|
+
namespace: z.string().trim().min(1).optional(),
|
|
453
|
+
})
|
|
454
|
+
.refine((input) => Boolean(input.source?.trim() || input.file_path?.trim()), {
|
|
455
|
+
message: "Provide source or file_path.",
|
|
456
|
+
path: ["source"],
|
|
457
|
+
});
|
|
458
|
+
exports.browserInjectScriptOutputSchema = z.object({
|
|
459
|
+
session_id: z.string(),
|
|
460
|
+
injected: z.boolean(),
|
|
461
|
+
namespace: z.string(),
|
|
462
|
+
source_type: z.enum(["inline", "file"]),
|
|
463
|
+
bytes: z.number().int().nonnegative(),
|
|
464
|
+
url: z.string(),
|
|
279
465
|
title: z.string().optional(),
|
|
280
466
|
});
|
|
281
467
|
exports.browserWaitForInputSchema = z
|
|
@@ -294,7 +480,7 @@ exports.browserWaitForOutputSchema = z.object({
|
|
|
294
480
|
ai_tag: z.string().optional(),
|
|
295
481
|
selector: z.string().optional(),
|
|
296
482
|
text: z.string().optional(),
|
|
297
|
-
url: z.string()
|
|
483
|
+
url: z.string(),
|
|
298
484
|
title: z.string().optional(),
|
|
299
485
|
});
|
|
300
486
|
exports.browserWaitForUrlInputSchema = z
|
|
@@ -314,7 +500,7 @@ exports.browserWaitForUrlOutputSchema = z.object({
|
|
|
314
500
|
matched: z.enum(["url", "url_contains"]),
|
|
315
501
|
url: z.string().optional(),
|
|
316
502
|
url_contains: z.string().optional(),
|
|
317
|
-
current_url: z.string()
|
|
503
|
+
current_url: z.string(),
|
|
318
504
|
title: z.string().optional(),
|
|
319
505
|
});
|
|
320
506
|
exports.browserConsoleInputSchema = z.object({
|
|
@@ -352,7 +538,7 @@ exports.browserNetworkFailuresOutputSchema = z.object({
|
|
|
352
538
|
session_id: z.string(),
|
|
353
539
|
total: z.number().int().nonnegative(),
|
|
354
540
|
failures: z.array(z.object({
|
|
355
|
-
url: z.string()
|
|
541
|
+
url: z.string(),
|
|
356
542
|
method: z.string(),
|
|
357
543
|
status: z.number().int().optional(),
|
|
358
544
|
error_text: z.string().optional(),
|
|
@@ -440,9 +626,9 @@ exports.sendPartnerNoteInputSchema = z.object({
|
|
|
440
626
|
target_local_session_id: z.string().trim().min(1).optional(),
|
|
441
627
|
project_uuid: z.string().trim().min(1).optional(),
|
|
442
628
|
kind: partnerNoteKindSchema,
|
|
443
|
-
summary:
|
|
444
|
-
message:
|
|
445
|
-
expected_reply:
|
|
629
|
+
summary: bodyStringSchema.trim().min(1),
|
|
630
|
+
message: bodyStringSchema.trim().min(1),
|
|
631
|
+
expected_reply: bodyStringSchema.trim().min(1).optional(),
|
|
446
632
|
requires_reply: z.boolean().optional(),
|
|
447
633
|
in_reply_to: z.string().trim().min(1).optional(),
|
|
448
634
|
artifacts: z.array(z.string().trim().min(1)).optional(),
|
|
@@ -454,7 +640,7 @@ exports.sendPartnerNoteInputSchema = z.object({
|
|
|
454
640
|
mime_type: z.string().trim().min(1).optional(),
|
|
455
641
|
size_bytes: z.number().int().nonnegative().optional(),
|
|
456
642
|
storage_ref: z.string().trim().min(1).optional(),
|
|
457
|
-
content_base64:
|
|
643
|
+
content_base64: bodyStringSchema.trim().min(1).optional(),
|
|
458
644
|
}))
|
|
459
645
|
.optional(),
|
|
460
646
|
});
|
|
@@ -467,9 +653,9 @@ exports.sendPartnerFileInputSchema = z.object({
|
|
|
467
653
|
cwd: z.string().trim().min(1).optional(),
|
|
468
654
|
file_path: z.string().trim().min(1),
|
|
469
655
|
kind: partnerNoteKindSchema.optional(),
|
|
470
|
-
summary:
|
|
471
|
-
message:
|
|
472
|
-
expected_reply:
|
|
656
|
+
summary: bodyStringSchema.trim().min(1).optional(),
|
|
657
|
+
message: bodyStringSchema.trim().min(1).optional(),
|
|
658
|
+
expected_reply: bodyStringSchema.trim().min(1).optional(),
|
|
473
659
|
requires_reply: z.boolean().optional(),
|
|
474
660
|
in_reply_to: z.string().trim().min(1).optional(),
|
|
475
661
|
});
|
|
@@ -533,7 +719,9 @@ const xchangeRecordSchema = z.object({
|
|
|
533
719
|
exports.listXchangeRecordsInputSchema = z.object({
|
|
534
720
|
session_id: z.string().trim().min(1).optional(),
|
|
535
721
|
status: z.enum(["new", "read", "archived"]).optional(),
|
|
536
|
-
category: z
|
|
722
|
+
category: z
|
|
723
|
+
.enum(["partner_note", "local_handoff", "telegram_message"])
|
|
724
|
+
.optional(),
|
|
537
725
|
direction: z.enum(["incoming", "outgoing", "local"]).optional(),
|
|
538
726
|
limit: z.number().int().positive().max(200).optional(),
|
|
539
727
|
});
|
package/dist/services/features/telegram-mcp/src/features/browser/model/browserAttachActiveTabTool.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BrowserAttachActiveTabTool = void 0;
|
|
4
|
+
const schema_1 = require("../../../entities/request/model/schema");
|
|
5
|
+
function createContent(output) {
|
|
6
|
+
return [{ type: "text", text: JSON.stringify(output, null, 2) }];
|
|
7
|
+
}
|
|
8
|
+
class BrowserAttachActiveTabTool {
|
|
9
|
+
browserService;
|
|
10
|
+
constructor(browserService) {
|
|
11
|
+
this.browserService = browserService;
|
|
12
|
+
}
|
|
13
|
+
register(server) {
|
|
14
|
+
server.registerTool("browser_attach_active_tab", {
|
|
15
|
+
title: "Browser Attach Active Tab",
|
|
16
|
+
description: "Attach the current MCP session to the active tab of a connected attached browser instance. If only one instance is connected, instance_id can be omitted.",
|
|
17
|
+
inputSchema: schema_1.browserAttachActiveTabInputSchema,
|
|
18
|
+
outputSchema: schema_1.browserAttachTabOutputSchema,
|
|
19
|
+
}, async (args) => {
|
|
20
|
+
const output = await this.browserService.attachActiveTab(args);
|
|
21
|
+
return {
|
|
22
|
+
content: createContent(output),
|
|
23
|
+
structuredContent: output,
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.BrowserAttachActiveTabTool = BrowserAttachActiveTabTool;
|
package/dist/services/features/telegram-mcp/src/features/browser/model/browserAttachTabTool.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BrowserAttachTabTool = void 0;
|
|
4
|
+
const schema_1 = require("../../../entities/request/model/schema");
|
|
5
|
+
function createContent(output) {
|
|
6
|
+
return [{ type: "text", text: JSON.stringify(output, null, 2) }];
|
|
7
|
+
}
|
|
8
|
+
class BrowserAttachTabTool {
|
|
9
|
+
browserService;
|
|
10
|
+
constructor(browserService) {
|
|
11
|
+
this.browserService = browserService;
|
|
12
|
+
}
|
|
13
|
+
register(server) {
|
|
14
|
+
server.registerTool("browser_attach_tab", {
|
|
15
|
+
title: "Browser Attach Tab",
|
|
16
|
+
description: "Attach the current MCP session to a specific tab in a connected attached browser instance by tab_id.",
|
|
17
|
+
inputSchema: schema_1.browserAttachTabInputSchema,
|
|
18
|
+
outputSchema: schema_1.browserAttachTabOutputSchema,
|
|
19
|
+
}, async (args) => {
|
|
20
|
+
const output = await this.browserService.attachTab(args);
|
|
21
|
+
return {
|
|
22
|
+
content: createContent(output),
|
|
23
|
+
structuredContent: output,
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.BrowserAttachTabTool = BrowserAttachTabTool;
|
|
@@ -13,7 +13,7 @@ class BrowserClickTool {
|
|
|
13
13
|
register(server) {
|
|
14
14
|
server.registerTool("browser_click", {
|
|
15
15
|
title: "Browser Click",
|
|
16
|
-
description: "Click an element in the session browser
|
|
16
|
+
description: "Click an element in the current session browser target by CSS selector or visible text. If the session has a selected attached Firefox tab, click there; otherwise use the isolated Playwright page.",
|
|
17
17
|
inputSchema: schema_1.browserClickInputSchema,
|
|
18
18
|
outputSchema: schema_1.browserClickOutputSchema,
|
|
19
19
|
}, async (args) => {
|
package/dist/services/features/telegram-mcp/src/features/browser/model/browserDetachTabTool.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BrowserDetachTabTool = void 0;
|
|
4
|
+
const schema_1 = require("../../../entities/request/model/schema");
|
|
5
|
+
function createContent(output) {
|
|
6
|
+
return [{ type: "text", text: JSON.stringify(output, null, 2) }];
|
|
7
|
+
}
|
|
8
|
+
class BrowserDetachTabTool {
|
|
9
|
+
browserService;
|
|
10
|
+
constructor(browserService) {
|
|
11
|
+
this.browserService = browserService;
|
|
12
|
+
}
|
|
13
|
+
register(server) {
|
|
14
|
+
server.registerTool("browser_detach_tab", {
|
|
15
|
+
title: "Browser Detach Tab",
|
|
16
|
+
description: "Detach the current MCP session from the currently selected attached browser tab.",
|
|
17
|
+
inputSchema: schema_1.browserDetachTabInputSchema,
|
|
18
|
+
outputSchema: schema_1.browserDetachTabOutputSchema,
|
|
19
|
+
}, async (args) => {
|
|
20
|
+
const output = await this.browserService.detachTab(args);
|
|
21
|
+
return {
|
|
22
|
+
content: createContent(output),
|
|
23
|
+
structuredContent: output,
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.BrowserDetachTabTool = BrowserDetachTabTool;
|
|
@@ -13,7 +13,7 @@ class BrowserDomTool {
|
|
|
13
13
|
register(server) {
|
|
14
14
|
server.registerTool("browser_dom", {
|
|
15
15
|
title: "Browser DOM",
|
|
16
|
-
description: "Inspect a DOM element in the
|
|
16
|
+
description: "Inspect a DOM element in the current session browser target and return text, HTML, attributes, and visibility. If the session has a selected attached Firefox tab, inspect that tab; otherwise use the isolated Playwright page.",
|
|
17
17
|
inputSchema: schema_1.browserDomInputSchema,
|
|
18
18
|
outputSchema: schema_1.browserDomOutputSchema,
|
|
19
19
|
}, async (args) => {
|