@thenavidm/threads-mcp-cli 1.1.2 → 2.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/README.md +105 -53
- package/SKILL.md +9 -8
- package/dist/app.d.ts +9 -0
- package/dist/app.js +101 -0
- package/dist/app.js.map +1 -0
- package/dist/auth/login.js +2 -1
- package/dist/auth/login.js.map +1 -1
- package/dist/auth/refresh.d.ts +8 -0
- package/dist/auth/refresh.js +39 -0
- package/dist/auth/refresh.js.map +1 -0
- package/dist/doctor.d.ts +11 -4
- package/dist/doctor.js +64 -125
- package/dist/doctor.js.map +1 -1
- package/dist/{server.d.ts → guide.d.ts} +14 -17
- package/dist/{server.js → guide.js} +18 -122
- package/dist/guide.js.map +1 -0
- package/dist/index.d.ts +5 -8
- package/dist/index.js +9 -162
- package/dist/index.js.map +1 -1
- package/dist/tools/accounts.d.ts +5 -18
- package/dist/tools/discover.d.ts +5 -46
- package/dist/tools/insights.d.ts +5 -36
- package/dist/tools/kit.d.ts +23 -49
- package/dist/tools/kit.js +64 -79
- package/dist/tools/kit.js.map +1 -1
- package/dist/tools/posts.d.ts +10 -161
- package/dist/tools/read.d.ts +3 -24
- package/dist/tools/replies.d.ts +8 -79
- package/package.json +11 -6
- package/dist/cli.d.ts +0 -59
- package/dist/cli.js +0 -444
- package/dist/cli.js.map +0 -1
- package/dist/safety.d.ts +0 -52
- package/dist/safety.js +0 -85
- package/dist/safety.js.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/transport/http.d.ts +0 -28
- package/dist/transport/http.js +0 -107
- package/dist/transport/http.js.map +0 -1
package/dist/transport/http.js
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HTTP transport, for running the server somewhere always on.
|
|
3
|
-
*
|
|
4
|
-
* Streamable HTTP, stateless: every request builds its own transport and tears
|
|
5
|
-
* it down. No session map means no session leak, which matters more here than
|
|
6
|
-
* the reconnect support a stateful server would buy.
|
|
7
|
-
*
|
|
8
|
-
* There is a second reason to run this way for Threads specifically. A token
|
|
9
|
-
* only stays alive if something refreshes it inside its 60-day window, and an
|
|
10
|
-
* MCP server launched over stdio only exists while a client has it open. A
|
|
11
|
-
* long-running HTTP instance refreshes on its own and never lets the window
|
|
12
|
-
* close.
|
|
13
|
-
*
|
|
14
|
-
* Bound to 127.0.0.1 by default. A Threads token can post as you, so a server
|
|
15
|
-
* that binds 0.0.0.0 without being asked is a mistake waiting to be made once;
|
|
16
|
-
* THREADS_HTTP_HOST is there for people who mean it.
|
|
17
|
-
*/
|
|
18
|
-
import { createServer } from "node:http";
|
|
19
|
-
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
20
|
-
import { daysRemaining } from "../auth/tokens.js";
|
|
21
|
-
import { numericFlag } from "../config.js";
|
|
22
|
-
export function httpOptionsFromEnv(argv = []) {
|
|
23
|
-
// `--port` beats THREADS_HTTP_PORT, which beats the default. Both spellings
|
|
24
|
-
// of the flag are accepted; see numericFlag for why that is worth saying.
|
|
25
|
-
const fromEnv = Number(process.env.THREADS_HTTP_PORT);
|
|
26
|
-
const fallback = Number.isFinite(fromEnv) && fromEnv > 0 ? fromEnv : 8787;
|
|
27
|
-
const port = numericFlag(argv, "port", fallback);
|
|
28
|
-
return {
|
|
29
|
-
port,
|
|
30
|
-
host: process.env.THREADS_HTTP_HOST || "127.0.0.1",
|
|
31
|
-
token: process.env.THREADS_HTTP_TOKEN || undefined,
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
async function readBody(req) {
|
|
35
|
-
const chunks = [];
|
|
36
|
-
for await (const chunk of req)
|
|
37
|
-
chunks.push(chunk);
|
|
38
|
-
const raw = Buffer.concat(chunks).toString("utf8");
|
|
39
|
-
if (!raw)
|
|
40
|
-
return undefined;
|
|
41
|
-
try {
|
|
42
|
-
return JSON.parse(raw);
|
|
43
|
-
}
|
|
44
|
-
catch {
|
|
45
|
-
return undefined;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
/** Constant-time-ish comparison, so the token cannot be guessed byte by byte. */
|
|
49
|
-
function tokenMatches(expected, provided) {
|
|
50
|
-
if (expected.length !== provided.length)
|
|
51
|
-
return false;
|
|
52
|
-
let diff = 0;
|
|
53
|
-
for (let i = 0; i < expected.length; i++)
|
|
54
|
-
diff |= expected.charCodeAt(i) ^ provided.charCodeAt(i);
|
|
55
|
-
return diff === 0;
|
|
56
|
-
}
|
|
57
|
-
async function handle(built, options, req, res) {
|
|
58
|
-
// Health needs no auth: it reports counts, never content.
|
|
59
|
-
if (req.method === "GET" && (req.url === "/health" || req.url === "/healthz")) {
|
|
60
|
-
res.writeHead(200, { "content-type": "application/json" });
|
|
61
|
-
res.end(JSON.stringify({
|
|
62
|
-
status: "ok",
|
|
63
|
-
tools: built.toolCount,
|
|
64
|
-
accounts: built.config.accounts.length,
|
|
65
|
-
read_only: built.config.readOnly,
|
|
66
|
-
tokens: built.config.accounts.map((a) => ({
|
|
67
|
-
username: a.username ?? null,
|
|
68
|
-
days_left: daysRemaining(a) ?? null,
|
|
69
|
-
})),
|
|
70
|
-
}));
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
if (options.token) {
|
|
74
|
-
const header = req.headers.authorization ?? "";
|
|
75
|
-
const provided = header.startsWith("Bearer ") ? header.slice(7) : "";
|
|
76
|
-
if (!provided || !tokenMatches(options.token, provided)) {
|
|
77
|
-
res.writeHead(401, { "content-type": "application/json" });
|
|
78
|
-
res.end(JSON.stringify({ error: "unauthorized" }));
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
|
|
83
|
-
res.on("close", () => void transport.close());
|
|
84
|
-
await built.server.connect(transport);
|
|
85
|
-
await transport.handleRequest(req, res, await readBody(req));
|
|
86
|
-
}
|
|
87
|
-
export async function startHttpServer(built, options) {
|
|
88
|
-
const http = createServer((req, res) => {
|
|
89
|
-
void handle(built, options, req, res).catch((error) => {
|
|
90
|
-
if (!res.headersSent)
|
|
91
|
-
res.writeHead(500, { "content-type": "application/json" });
|
|
92
|
-
res.end(JSON.stringify({
|
|
93
|
-
jsonrpc: "2.0",
|
|
94
|
-
error: { code: -32603, message: error?.message ?? "internal error" },
|
|
95
|
-
id: null,
|
|
96
|
-
}));
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
await new Promise((resolve) => http.listen(options.port, options.host, resolve));
|
|
100
|
-
process.stderr.write(`[threads-mcp] HTTP on http://${options.host}:${options.port} (${built.toolCount} tools, ${built.config.accounts.length} account(s))${options.token ? "" : "\n[threads-mcp] No THREADS_HTTP_TOKEN set: this endpoint is unauthenticated."}\n`);
|
|
101
|
-
return {
|
|
102
|
-
close: () => new Promise((resolve) => {
|
|
103
|
-
http.close(() => resolve());
|
|
104
|
-
}),
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
//# sourceMappingURL=http.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/transport/http.ts"],"names":[],"mappings":"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"}
|