@overpod/mcp-telegram 1.35.0 → 1.36.1
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 +56 -0
- package/dist/cli.js +0 -0
- package/dist/manifest.d.ts +27 -0
- package/dist/manifest.js +95 -0
- package/dist/qr-login-cli.js +0 -0
- package/package.json +9 -6
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,62 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.36.1] — 2026-05-04
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Add `big-integer` as a direct dependency. Previously it was imported by `src/telegram-client.ts` and `src/telegram-helpers.ts` but only resolved transitively, which broke `tsc --noEmit` on strict-hoisting installers like pnpm.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Dependency updates (no behavioral changes):
|
|
17
|
+
- `zod` `^4.3.6` → `^4.4.3` (patch bump, runtime backward-compatible)
|
|
18
|
+
- `@biomejs/biome` `^2.4.13` → `^2.4.14` (devDep, lint/format only)
|
|
19
|
+
|
|
20
|
+
## [1.36.0] — 2026-04-28
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
**Tool manifest export — introspect the catalog without standing up an MCP transport.**
|
|
25
|
+
|
|
26
|
+
A new `@overpod/mcp-telegram/manifest` subpath export and `mcp-telegram-manifest` bin entry let consumers (and downstream cloud distributions) ask the package "what tools do you register, and at what risk tier?" without booting a real Telegram session.
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { getToolManifest } from "@overpod/mcp-telegram/manifest";
|
|
30
|
+
|
|
31
|
+
const m = getToolManifest();
|
|
32
|
+
// {
|
|
33
|
+
// generatedAt: "2026-04-28T...Z",
|
|
34
|
+
// toolCount: 181,
|
|
35
|
+
// tiers: { "read-only": 74, write: 96, destructive: 11 },
|
|
36
|
+
// tools: [{ name: "telegram-status", tier: "read-only", description: "...", hasInput: false }, ...]
|
|
37
|
+
// }
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
CLI variant:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
mcp-telegram-manifest # writes manifest.json
|
|
44
|
+
mcp-telegram-manifest path/out.json # writes to path/out.json
|
|
45
|
+
mcp-telegram-manifest - # writes JSON to stdout
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
How it works: instantiates an `McpServer`, calls the existing `registerTools()` with a stub service (only types matter — every `telegram.*` call lives inside async tool callbacks, not the registration phase), then introspects the SDK's registered tools and classifies each by `annotations`:
|
|
49
|
+
|
|
50
|
+
- `destructiveHint: true` → `destructive`
|
|
51
|
+
- `readOnlyHint: true` → `read-only`
|
|
52
|
+
- otherwise → `write`
|
|
53
|
+
|
|
54
|
+
Opt-in env flags (`MCP_TELEGRAM_ENABLE_STARS`, `MCP_TELEGRAM_ENABLE_GROUP_CALLS`, `MCP_TELEGRAM_ENABLE_QUICK_REPLIES`) are forced ON during introspection so consumers always see the full catalog, then restored to the caller's prior values. The result is cached for the process lifetime.
|
|
55
|
+
|
|
56
|
+
This is the foundation for upstream parity gates (e.g. cloud distributions that ship a curated whitelist can detect drift in CI by comparing their whitelist against `getToolManifest().tools`).
|
|
57
|
+
|
|
58
|
+
### Notes
|
|
59
|
+
|
|
60
|
+
- New public API surface; no breaking changes to existing exports.
|
|
61
|
+
- `src/manifest.ts` and 13 new tests added; total test count: 505.
|
|
62
|
+
- Build now sets executable bits on all `dist/*-cli.js` outputs (was npm-install-time only for `bin` entries).
|
|
63
|
+
|
|
8
64
|
## [1.35.0] — 2026-04-25
|
|
9
65
|
|
|
10
66
|
### Changed
|
package/dist/cli.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export type ToolTier = "read-only" | "write" | "destructive";
|
|
3
|
+
export interface ToolManifestEntry {
|
|
4
|
+
name: string;
|
|
5
|
+
tier: ToolTier;
|
|
6
|
+
description: string;
|
|
7
|
+
hasInput: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface ToolManifest {
|
|
10
|
+
generatedAt: string;
|
|
11
|
+
toolCount: number;
|
|
12
|
+
tiers: {
|
|
13
|
+
"read-only": number;
|
|
14
|
+
write: number;
|
|
15
|
+
destructive: number;
|
|
16
|
+
};
|
|
17
|
+
tools: ToolManifestEntry[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build a manifest of every tool the package can register. Forces all opt-in
|
|
21
|
+
* env flags ON during introspection so consumers see the full catalog, not
|
|
22
|
+
* the runtime-filtered subset. Cached for the process lifetime — invocations
|
|
23
|
+
* are cheap and idempotent.
|
|
24
|
+
*/
|
|
25
|
+
export declare function getToolManifest(): ToolManifest;
|
|
26
|
+
/** Test-only: discard cache and force a fresh introspection. */
|
|
27
|
+
export declare function _resetManifestCache(): void;
|
package/dist/manifest.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { writeFileSync } from "node:fs";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
|
+
import { registerTools } from "./tools/index.js";
|
|
6
|
+
function classify(name, annotations) {
|
|
7
|
+
if (annotations === undefined) {
|
|
8
|
+
console.warn(`[manifest] Tool '${name}' has no annotations — defaulting to 'write'. Add READ_ONLY/WRITE/DESTRUCTIVE.`);
|
|
9
|
+
return "write";
|
|
10
|
+
}
|
|
11
|
+
if (annotations.destructiveHint === true)
|
|
12
|
+
return "destructive";
|
|
13
|
+
if (annotations.readOnlyHint === true)
|
|
14
|
+
return "read-only";
|
|
15
|
+
return "write";
|
|
16
|
+
}
|
|
17
|
+
const OPT_IN_FLAGS = [
|
|
18
|
+
"MCP_TELEGRAM_ENABLE_STARS",
|
|
19
|
+
"MCP_TELEGRAM_ENABLE_GROUP_CALLS",
|
|
20
|
+
"MCP_TELEGRAM_ENABLE_QUICK_REPLIES",
|
|
21
|
+
];
|
|
22
|
+
/** Cache: introspection is deterministic + cheap, but env save/restore is not reentrant. */
|
|
23
|
+
let cached = null;
|
|
24
|
+
/**
|
|
25
|
+
* Build a manifest of every tool the package can register. Forces all opt-in
|
|
26
|
+
* env flags ON during introspection so consumers see the full catalog, not
|
|
27
|
+
* the runtime-filtered subset. Cached for the process lifetime — invocations
|
|
28
|
+
* are cheap and idempotent.
|
|
29
|
+
*/
|
|
30
|
+
export function getToolManifest() {
|
|
31
|
+
if (cached)
|
|
32
|
+
return cached;
|
|
33
|
+
cached = introspect();
|
|
34
|
+
return cached;
|
|
35
|
+
}
|
|
36
|
+
/** Test-only: discard cache and force a fresh introspection. */
|
|
37
|
+
export function _resetManifestCache() {
|
|
38
|
+
cached = null;
|
|
39
|
+
}
|
|
40
|
+
function introspect() {
|
|
41
|
+
const restore = {};
|
|
42
|
+
for (const key of OPT_IN_FLAGS) {
|
|
43
|
+
restore[key] = process.env[key];
|
|
44
|
+
process.env[key] = "1";
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const server = new McpServer({ name: "manifest-introspect", version: "0.0.0" });
|
|
48
|
+
registerTools(server, {});
|
|
49
|
+
return buildManifest(server);
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
for (const key of OPT_IN_FLAGS) {
|
|
53
|
+
if (restore[key] === undefined)
|
|
54
|
+
delete process.env[key];
|
|
55
|
+
else
|
|
56
|
+
process.env[key] = restore[key];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function buildManifest(server) {
|
|
61
|
+
const registered = server._registeredTools;
|
|
62
|
+
if (!registered || typeof registered !== "object") {
|
|
63
|
+
throw new Error("Failed to introspect MCP server: _registeredTools is missing. " +
|
|
64
|
+
"The @modelcontextprotocol/sdk shape may have changed — please file an issue at " +
|
|
65
|
+
"https://github.com/mcp-telegram/mcp-telegram/issues");
|
|
66
|
+
}
|
|
67
|
+
const tools = Object.entries(registered)
|
|
68
|
+
.map(([name, tool]) => ({
|
|
69
|
+
name,
|
|
70
|
+
tier: classify(name, tool.annotations),
|
|
71
|
+
description: tool.description ?? "",
|
|
72
|
+
hasInput: tool.inputSchema !== undefined,
|
|
73
|
+
}))
|
|
74
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
75
|
+
const tiers = { "read-only": 0, write: 0, destructive: 0 };
|
|
76
|
+
for (const t of tools)
|
|
77
|
+
tiers[t.tier]++;
|
|
78
|
+
return {
|
|
79
|
+
generatedAt: new Date().toISOString(),
|
|
80
|
+
toolCount: tools.length,
|
|
81
|
+
tiers,
|
|
82
|
+
tools,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (import.meta.url === `file://${process.argv[1]}` || fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
86
|
+
const manifest = getToolManifest();
|
|
87
|
+
const output = process.argv[2] ?? "manifest.json";
|
|
88
|
+
if (output === "-") {
|
|
89
|
+
process.stdout.write(`${JSON.stringify(manifest, null, 2)}\n`);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
writeFileSync(output, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
93
|
+
console.error(`[manifest] Wrote ${manifest.toolCount} tools to ${output}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
package/dist/qr-login-cli.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@overpod/mcp-telegram",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.36.1",
|
|
4
4
|
"description": "MCP server for Telegram userbot — messages, media, reactions, polls & more. Built on GramJS/MTProto.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": "./dist/index.js",
|
|
9
|
-
"./service": "./dist/telegram-client.js"
|
|
9
|
+
"./service": "./dist/telegram-client.js",
|
|
10
|
+
"./manifest": "./dist/manifest.js"
|
|
10
11
|
},
|
|
11
12
|
"bin": {
|
|
12
|
-
"mcp-telegram": "dist/cli.js"
|
|
13
|
+
"mcp-telegram": "dist/cli.js",
|
|
14
|
+
"mcp-telegram-manifest": "dist/manifest.js"
|
|
13
15
|
},
|
|
14
16
|
"files": [
|
|
15
17
|
"dist",
|
|
@@ -21,7 +23,7 @@
|
|
|
21
23
|
"dev": "tsx watch src/index.ts",
|
|
22
24
|
"start": "node dist/index.js",
|
|
23
25
|
"login": "node dist/qr-login-cli.js",
|
|
24
|
-
"build": "tsc",
|
|
26
|
+
"build": "tsc && chmod +x dist/cli.js dist/manifest.js dist/qr-login-cli.js",
|
|
25
27
|
"typecheck": "tsc --noEmit",
|
|
26
28
|
"prepublishOnly": "npm run build",
|
|
27
29
|
"lint": "biome check src/",
|
|
@@ -57,13 +59,14 @@
|
|
|
57
59
|
},
|
|
58
60
|
"dependencies": {
|
|
59
61
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
62
|
+
"big-integer": "^1.6.52",
|
|
60
63
|
"dotenv": "^17.4.2",
|
|
61
64
|
"qrcode": "^1.5.4",
|
|
62
65
|
"telegram": "^2.26.22",
|
|
63
|
-
"zod": "^4.3
|
|
66
|
+
"zod": "^4.4.3"
|
|
64
67
|
},
|
|
65
68
|
"devDependencies": {
|
|
66
|
-
"@biomejs/biome": "^2.4.
|
|
69
|
+
"@biomejs/biome": "^2.4.14",
|
|
67
70
|
"@types/node": "^25.6.0",
|
|
68
71
|
"@types/qrcode": "^1.5.6",
|
|
69
72
|
"c8": "^11.0.0",
|