@thenavidm/threads-mcp-cli 1.1.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.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1019 -0
  3. package/SKILL.md +203 -0
  4. package/dist/api/client.d.ts +105 -0
  5. package/dist/api/client.js +305 -0
  6. package/dist/api/client.js.map +1 -0
  7. package/dist/api/errors.d.ts +92 -0
  8. package/dist/api/errors.js +195 -0
  9. package/dist/api/errors.js.map +1 -0
  10. package/dist/api/identity.d.ts +33 -0
  11. package/dist/api/identity.js +52 -0
  12. package/dist/api/identity.js.map +1 -0
  13. package/dist/auth/login.d.ts +32 -0
  14. package/dist/auth/login.js +204 -0
  15. package/dist/auth/login.js.map +1 -0
  16. package/dist/auth/store.d.ts +37 -0
  17. package/dist/auth/store.js +88 -0
  18. package/dist/auth/store.js.map +1 -0
  19. package/dist/auth/tokens.d.ts +54 -0
  20. package/dist/auth/tokens.js +96 -0
  21. package/dist/auth/tokens.js.map +1 -0
  22. package/dist/cli.d.ts +59 -0
  23. package/dist/cli.js +444 -0
  24. package/dist/cli.js.map +1 -0
  25. package/dist/config.d.ts +98 -0
  26. package/dist/config.js +185 -0
  27. package/dist/config.js.map +1 -0
  28. package/dist/content/containers.d.ts +89 -0
  29. package/dist/content/containers.js +210 -0
  30. package/dist/content/containers.js.map +1 -0
  31. package/dist/content/media.d.ts +61 -0
  32. package/dist/content/media.js +125 -0
  33. package/dist/content/media.js.map +1 -0
  34. package/dist/content/text.d.ts +68 -0
  35. package/dist/content/text.js +106 -0
  36. package/dist/content/text.js.map +1 -0
  37. package/dist/doctor.d.ts +14 -0
  38. package/dist/doctor.js +218 -0
  39. package/dist/doctor.js.map +1 -0
  40. package/dist/format/posts.d.ts +41 -0
  41. package/dist/format/posts.js +153 -0
  42. package/dist/format/posts.js.map +1 -0
  43. package/dist/index.d.ts +13 -0
  44. package/dist/index.js +167 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/safety.d.ts +52 -0
  47. package/dist/safety.js +85 -0
  48. package/dist/safety.js.map +1 -0
  49. package/dist/server.d.ts +20 -0
  50. package/dist/server.js +232 -0
  51. package/dist/server.js.map +1 -0
  52. package/dist/tools/accounts.d.ts +27 -0
  53. package/dist/tools/accounts.js +162 -0
  54. package/dist/tools/accounts.js.map +1 -0
  55. package/dist/tools/discover.d.ts +56 -0
  56. package/dist/tools/discover.js +146 -0
  57. package/dist/tools/discover.js.map +1 -0
  58. package/dist/tools/index.d.ts +3 -0
  59. package/dist/tools/index.js +16 -0
  60. package/dist/tools/index.js.map +1 -0
  61. package/dist/tools/insights.d.ts +55 -0
  62. package/dist/tools/insights.js +223 -0
  63. package/dist/tools/insights.js.map +1 -0
  64. package/dist/tools/kit.d.ts +90 -0
  65. package/dist/tools/kit.js +119 -0
  66. package/dist/tools/kit.js.map +1 -0
  67. package/dist/tools/posts.d.ts +170 -0
  68. package/dist/tools/posts.js +312 -0
  69. package/dist/tools/posts.js.map +1 -0
  70. package/dist/tools/read.d.ts +31 -0
  71. package/dist/tools/read.js +95 -0
  72. package/dist/tools/read.js.map +1 -0
  73. package/dist/tools/replies.d.ts +92 -0
  74. package/dist/tools/replies.js +218 -0
  75. package/dist/tools/replies.js.map +1 -0
  76. package/dist/transport/http.d.ts +28 -0
  77. package/dist/transport/http.js +103 -0
  78. package/dist/transport/http.js.map +1 -0
  79. package/package.json +65 -0
package/dist/cli.js ADDED
@@ -0,0 +1,444 @@
1
+ /**
2
+ * The CLI adapter.
3
+ *
4
+ * `register()` in tools/kit.ts turns a `ToolSpec` into an MCP tool. This turns
5
+ * the same spec into a shell command, from the same `ALL_TOOLS` array, through
6
+ * the same handler and the same `WriteGuard`. Nothing is described twice, so a
7
+ * tool added tomorrow is a command tomorrow and the two surfaces cannot drift.
8
+ *
9
+ * The command IS the tool name. `create_post` runs as `create-post`, and the
10
+ * underscore form works too. Inventing a prettier command tree would mean a
11
+ * hand-written mapping, which is exactly the drift this avoids, and it would
12
+ * force anyone reading the SKILL.md to learn two vocabularies for one action.
13
+ *
14
+ * Zod is the only schema: every flag, its placeholder, its help text and its
15
+ * validation come from the shape the MCP tool already declares.
16
+ */
17
+ import { z } from "zod";
18
+ import { zodToJsonSchema } from "zod-to-json-schema";
19
+ import { loadConfig } from "./config.js";
20
+ import { accountsFromStore } from "./auth/store.js";
21
+ import { ThreadsClient } from "./api/client.js";
22
+ import { WriteGuard } from "./safety.js";
23
+ import { ALL_TOOLS } from "./tools/index.js";
24
+ import { makeContext } from "./tools/kit.js";
25
+ import { ThreadsError } from "./api/errors.js";
26
+ /**
27
+ * Peel `.optional()`, `.default()` and `.nullable()` to reach the real type.
28
+ *
29
+ * A description can sit on either the wrapper or the inner type depending on
30
+ * the order the tool author chained them, so both are collected on the way
31
+ * down and the outermost one wins.
32
+ */
33
+ function unwrap(schema) {
34
+ let inner = schema;
35
+ let optional = false;
36
+ let description = schema.description;
37
+ for (;;) {
38
+ const typeName = inner._def.typeName;
39
+ if (typeName === "ZodOptional" || typeName === "ZodDefault" || typeName === "ZodNullable") {
40
+ if (typeName !== "ZodNullable")
41
+ optional = true;
42
+ inner = inner._def.innerType;
43
+ description ??= inner.description;
44
+ continue;
45
+ }
46
+ return { inner, optional, description };
47
+ }
48
+ }
49
+ function kindOf(schema) {
50
+ const typeName = schema._def.typeName;
51
+ switch (typeName) {
52
+ case "ZodString":
53
+ return { kind: "string", repeatable: false };
54
+ case "ZodNumber":
55
+ return { kind: "number", repeatable: false };
56
+ case "ZodBoolean":
57
+ return { kind: "boolean", repeatable: false };
58
+ case "ZodEnum":
59
+ return {
60
+ kind: "enum",
61
+ choices: schema._def.values,
62
+ repeatable: false,
63
+ };
64
+ case "ZodArray": {
65
+ // An array of scalars is repeatable (`--text a --text b`). An array of
66
+ // objects is not worth flattening, so it takes JSON.
67
+ const element = unwrap(schema._def.type).inner;
68
+ const elementKind = element._def.typeName;
69
+ // An enum element is a word you type, so it belongs with the scalars.
70
+ // Treating it as JSON meant `--metrics views` was rejected and you had to
71
+ // write `--metrics '"views"'` instead.
72
+ const scalar = elementKind === "ZodString" || elementKind === "ZodNumber" || elementKind === "ZodEnum";
73
+ return { kind: scalar ? "string" : "json", repeatable: true };
74
+ }
75
+ default:
76
+ // Objects, unions, records and anything else take a JSON literal.
77
+ return { kind: "json", repeatable: false };
78
+ }
79
+ }
80
+ /** Turn one schema entry into a flag. */
81
+ function toFlag(key, schema) {
82
+ const { inner, optional, description } = unwrap(schema);
83
+ const { kind, choices, repeatable } = kindOf(inner);
84
+ return {
85
+ key,
86
+ flag: `--${key.replace(/_/g, "-")}`,
87
+ kind,
88
+ required: !optional,
89
+ repeatable,
90
+ choices,
91
+ help: description ?? "",
92
+ };
93
+ }
94
+ export function flagsFor(shape) {
95
+ return Object.entries(shape).map(([key, schema]) => toFlag(key, schema));
96
+ }
97
+ class UsageError extends Error {
98
+ }
99
+ /** Accept a flag as `--foo-bar`, `--foo_bar`, or `foo_bar`. */
100
+ function normalize(token) {
101
+ return token.replace(/^--/, "").replace(/-/g, "_");
102
+ }
103
+ function coerce(flag, raw) {
104
+ switch (flag.kind) {
105
+ case "number": {
106
+ const value = Number(raw);
107
+ if (!Number.isFinite(value))
108
+ throw new UsageError(`${flag.flag} expects a number, got '${raw}'.`);
109
+ return value;
110
+ }
111
+ case "enum":
112
+ if (flag.choices && !flag.choices.includes(raw)) {
113
+ throw new UsageError(`${flag.flag} expects one of: ${flag.choices.join(", ")}. Got '${raw}'.`);
114
+ }
115
+ return raw;
116
+ case "json":
117
+ try {
118
+ return JSON.parse(raw);
119
+ }
120
+ catch {
121
+ throw new UsageError(`${flag.flag} expects JSON, got '${raw}'.`);
122
+ }
123
+ default:
124
+ return raw;
125
+ }
126
+ }
127
+ /**
128
+ * Parse argv against a tool's flags.
129
+ *
130
+ * Zod does the real validation afterwards, so this only has to get the values
131
+ * into the right JavaScript types and catch the mistakes Zod would report in
132
+ * terms of a schema the person at the terminal never sees.
133
+ */
134
+ export function parseArgs(argv, flags) {
135
+ const byKey = new Map(flags.map((f) => [f.key, f]));
136
+ const out = {};
137
+ const positional = [];
138
+ for (let i = 0; i < argv.length; i++) {
139
+ const token = argv[i];
140
+ if (!token.startsWith("--")) {
141
+ positional.push(token);
142
+ continue;
143
+ }
144
+ // `--flag=value` and `--flag value` are both normal to type.
145
+ const equals = token.indexOf("=");
146
+ const name = normalize(equals === -1 ? token : token.slice(0, equals));
147
+ const flag = byKey.get(name);
148
+ if (!flag)
149
+ throw new UsageError(`Unknown option ${token}.`);
150
+ if (flag.kind === "boolean") {
151
+ if (equals !== -1) {
152
+ const value = token.slice(equals + 1);
153
+ out[flag.key] = value !== "false" && value !== "0";
154
+ }
155
+ else {
156
+ out[flag.key] = true;
157
+ }
158
+ continue;
159
+ }
160
+ const raw = equals === -1 ? argv[++i] : token.slice(equals + 1);
161
+ if (raw === undefined)
162
+ throw new UsageError(`${flag.flag} expects a value.`);
163
+ const value = coerce(flag, raw);
164
+ if (flag.repeatable) {
165
+ out[flag.key] = [...(out[flag.key] ?? []), value];
166
+ }
167
+ else {
168
+ out[flag.key] = value;
169
+ }
170
+ }
171
+ // One bare argument fills the first required flag, so `search-keyword "cats"`
172
+ // works the way anyone would expect it to before reading any help.
173
+ if (positional.length > 0) {
174
+ const target = flags.find((f) => f.required && out[f.key] === undefined);
175
+ if (!target)
176
+ throw new UsageError(`Unexpected argument '${positional[0]}'.`);
177
+ if (positional.length > 1)
178
+ throw new UsageError(`Unexpected argument '${positional[1]}'.`);
179
+ const value = coerce(target, positional[0]);
180
+ out[target.key] = target.repeatable ? [value] : value;
181
+ }
182
+ return out;
183
+ }
184
+ /** Exit codes, so a script can branch without parsing the message. */
185
+ export const EXIT = {
186
+ ok: 0, usage: 2, notFound: 3, auth: 4, api: 5, rateLimited: 7, config: 10,
187
+ };
188
+ /** Map a thrown error onto one of those, from the shape the API gave back. */
189
+ export function exitCodeFor(error) {
190
+ const e = error;
191
+ const status = e?.status;
192
+ const text = `${e?.code ?? ""} ${e?.message ?? ""}`.toLowerCase();
193
+ if (status === 429 || /rate ?limit/.test(text))
194
+ return EXIT.rateLimited;
195
+ // Config before auth: "no account configured" mentions a token, and matching
196
+ // auth first sent someone who had configured nothing looking for an expired
197
+ // credential. Only when there is no HTTP status, so a real 401 still wins.
198
+ if (!status && /not configured|no [a-z ]*(account|profile|credential|token|key)s? (is |are )?configured|missing .*env/.test(text))
199
+ return EXIT.config;
200
+ if (status === 401 || status === 403 || /auth|credential|token|cookie|session/.test(text))
201
+ return EXIT.auth;
202
+ if (status === 404 || /not found/.test(text))
203
+ return EXIT.notFound;
204
+ // A refused write is the caller asking for something the guard will not do:
205
+ // that is a usage problem to fix in the command, not an API failure to retry.
206
+ if (/will not run without|read-only|is unavailable/.test(text))
207
+ return EXIT.usage;
208
+ if (/not configured|missing .*env|config/.test(text))
209
+ return EXIT.config;
210
+ if (typeof status === "number" && status >= 500)
211
+ return EXIT.api;
212
+ return EXIT.api;
213
+ }
214
+ /**
215
+ * `--select id,post.title` keeps only the named fields. Dotted paths descend,
216
+ * arrays are traversed element-wise. This is what makes a long feed affordable.
217
+ */
218
+ export function selectFields(data, paths) {
219
+ if (Array.isArray(data))
220
+ return data.map((d) => selectFields(d, paths));
221
+ if (data === null || typeof data !== "object")
222
+ return data;
223
+ const out = {};
224
+ for (const path of paths) {
225
+ const [head, ...rest] = path.split(".");
226
+ if (head === undefined)
227
+ continue;
228
+ const value = data[head];
229
+ if (value === undefined)
230
+ continue;
231
+ out[head] = rest.length ? selectFields(value, [rest.join(".")]) : value;
232
+ }
233
+ return out;
234
+ }
235
+ /**
236
+ * Print a handler result.
237
+ *
238
+ * Reading tools already return the tagged text from `format/`, which is the
239
+ * shaped-for-a-model output and is just as readable in a terminal. Writing
240
+ * tools return a small object. `--json` forces JSON either way so a script
241
+ * never has to know which kind of tool it called.
242
+ */
243
+ function emit(data, format) {
244
+ if (format === "text" && typeof data === "string") {
245
+ process.stdout.write(data.endsWith("\n") ? data : `${data}\n`);
246
+ return;
247
+ }
248
+ const json = format === "compact" ? JSON.stringify(data) : JSON.stringify(data, null, 2);
249
+ process.stdout.write(`${json}\n`);
250
+ }
251
+ /** Errors are JSON on stderr, always, so a caller parses one shape. */
252
+ function emitError(error) {
253
+ const payload = error instanceof ThreadsError
254
+ ? error.toJSON()
255
+ : { error: error?.message ?? String(error) };
256
+ process.stderr.write(`${JSON.stringify(payload, null, 2)}\n`);
257
+ }
258
+ /* -------------------------------------------------------------------- help */
259
+ function commandName(tool) {
260
+ return tool.replace(/_/g, "-");
261
+ }
262
+ /** Where help text starts, when the flag is short enough to leave room. */
263
+ const COLUMN = 34;
264
+ /**
265
+ * The name this was invoked as, so examples are copy-pasteable.
266
+ *
267
+ * The package ships two binaries onto the same file. Printing `threads-mcp` at
268
+ * someone who typed `threads-cli` hands them a command that works but is not
269
+ * the one they have in their fingers.
270
+ */
271
+ function binName() {
272
+ const name = (process.argv[1] ?? "").split("/").pop() ?? "";
273
+ return name.startsWith("threads-cli") ? "threads-cli" : "threads-mcp";
274
+ }
275
+ function renderToolHelp(spec) {
276
+ const flags = flagsFor(spec.schema);
277
+ const required = flags.filter((f) => f.required);
278
+ const optional = flags.filter((f) => !f.required);
279
+ const usage = [
280
+ `${binName()} ${commandName(spec.name)}`,
281
+ ...required.map((f) => `${f.flag} <${f.kind}>`),
282
+ optional.length > 0 ? "[options]" : "",
283
+ ]
284
+ .filter(Boolean)
285
+ .join(" ");
286
+ const lines = [``, spec.description.trim(), ``, `Usage:`, ` ${usage}`, ``];
287
+ const describe = (list, heading) => {
288
+ if (list.length === 0)
289
+ return;
290
+ lines.push(`${heading}:`);
291
+ for (const f of list) {
292
+ const placeholder = f.kind === "boolean" ? "" : ` <${f.choices ? f.choices.join("|") : f.kind}>`;
293
+ const left = ` ${f.flag}${placeholder}`;
294
+ const help = f.repeatable ? `${f.help} Repeatable.` : f.help;
295
+ if (!help) {
296
+ lines.push(left);
297
+ }
298
+ else if (left.length < COLUMN) {
299
+ lines.push(`${left.padEnd(COLUMN)}${help}`);
300
+ }
301
+ else {
302
+ // A long enum spelled out in the placeholder would push the help off
303
+ // the line, so it gets its own.
304
+ lines.push(left, `${" ".repeat(COLUMN)}${help}`);
305
+ }
306
+ }
307
+ lines.push(``);
308
+ };
309
+ describe(required, "Required");
310
+ describe(optional, "Options");
311
+ lines.push(`Output:`);
312
+ lines.push(` --json force JSON`);
313
+ lines.push(` --compact force single-line JSON`);
314
+ lines.push(` --agent machine mode: JSON, compact, no prompts, no colour`);
315
+ lines.push(` --select <a,b.c> keep only these fields, dotted paths descend`);
316
+ lines.push(``);
317
+ lines.push(`Risk: ${spec.risk}`);
318
+ lines.push(``);
319
+ return lines.join("\n");
320
+ }
321
+ function renderToolList(tools) {
322
+ const width = Math.max(...tools.map((t) => commandName(t.name).length)) + 2;
323
+ const bin = binName();
324
+ const lines = [``, `${bin} commands (${tools.length})`, ``];
325
+ for (const tool of tools) {
326
+ const mark = tool.risk === "read" ? " " : tool.risk === "destructive" ? "!" : "*";
327
+ lines.push(` ${mark} ${commandName(tool.name).padEnd(width)}${tool.title}`);
328
+ }
329
+ lines.push(``);
330
+ lines.push(` * writes ! irreversible, needs --confirm`);
331
+ lines.push(``);
332
+ lines.push(` ${bin} <command> --help what it takes`);
333
+ lines.push(` ${bin} schema <command> the JSON schema an MCP client sees`);
334
+ lines.push(``);
335
+ return lines.join("\n");
336
+ }
337
+ /* ---------------------------------------------------------------- dispatch */
338
+ /** The tools this process will expose, with READ_ONLY applied exactly as the server applies it. */
339
+ function visibleTools(guard) {
340
+ return ALL_TOOLS.filter((tool) => !guard.readOnly || tool.risk === "read");
341
+ }
342
+ export function isCliCommand(argv) {
343
+ const first = argv[0];
344
+ if (!first || first.startsWith("-"))
345
+ return false;
346
+ if (first === "tools" || first === "schema")
347
+ return true;
348
+ const name = normalize(first);
349
+ return ALL_TOOLS.some((tool) => tool.name === name);
350
+ }
351
+ export async function runCli(argv) {
352
+ // The store is read here rather than inside loadConfig so that the config
353
+ // module stays free of filesystem access, exactly as index.ts does it. A CLI
354
+ // that skipped it would not see the token `threads-mcp login` wrote.
355
+ const stored = accountsFromStore(loadConfig().storePath);
356
+ const config = loadConfig(stored);
357
+ const guard = new WriteGuard(config, "cli");
358
+ const tools = visibleTools(guard);
359
+ const command = argv[0];
360
+ const rest = argv.slice(1);
361
+ if (command === "tools") {
362
+ process.stdout.write(renderToolList(tools));
363
+ return 0;
364
+ }
365
+ if (command === "schema") {
366
+ const wanted = normalize(rest[0] ?? "");
367
+ const spec = tools.find((t) => t.name === wanted);
368
+ if (!spec) {
369
+ emitError(new Error(`Unknown command '${rest[0] ?? ""}'. Run \`${binName()} tools\`.`));
370
+ return 1;
371
+ }
372
+ // The same JSON Schema an MCP client receives, so the two surfaces are
373
+ // provably one. Emitting the Zod object instead printed its internals
374
+ // (`_def`, `~standard`), which is not a schema anyone can consume.
375
+ emit(zodToJsonSchema(z.object(spec.schema).describe(spec.description)), "json");
376
+ return 0;
377
+ }
378
+ const name = normalize(command);
379
+ const spec = tools.find((t) => t.name === name);
380
+ if (!spec) {
381
+ const hidden = ALL_TOOLS.find((t) => t.name === name);
382
+ emitError(new Error(hidden
383
+ ? `${name} is unavailable: this server is running with THREADS_READ_ONLY=1.`
384
+ : `Unknown command '${command}'. Run \`${binName()} tools\`.`));
385
+ return 1;
386
+ }
387
+ if (rest.includes("--help") || rest.includes("-h")) {
388
+ process.stdout.write(renderToolHelp(spec));
389
+ return 0;
390
+ }
391
+ // `--agent` is the whole machine-readable posture in one flag, so an agent
392
+ // does not have to remember four and silently forget one.
393
+ const agent = rest.includes("--agent");
394
+ const format = rest.includes("--compact") || agent ? "compact" : rest.includes("--json") ? "json" : "text";
395
+ const selectAt = rest.findIndex((t) => t === "--select" || t.startsWith("--select="));
396
+ const selectRaw = selectAt === -1
397
+ ? undefined
398
+ : rest[selectAt].includes("=")
399
+ ? rest[selectAt].split("=").slice(1).join("=")
400
+ : rest[selectAt + 1];
401
+ const select = selectRaw?.split(",").map((f) => f.trim()).filter(Boolean);
402
+ const consumed = new Set(["--json", "--compact", "--agent", "--no-color", "--no-input", "--yes"]);
403
+ const toolArgv = rest.filter((token, i) => {
404
+ if (consumed.has(token))
405
+ return false;
406
+ if (token === "--select" || token.startsWith("--select="))
407
+ return false;
408
+ if (selectAt !== -1 && i === selectAt + 1 && !rest[selectAt].includes("="))
409
+ return false;
410
+ return true;
411
+ });
412
+ try {
413
+ const parsed = parseArgs(toolArgv, flagsFor(spec.schema));
414
+ // Zod is the authority on validity, exactly as it is for an MCP call.
415
+ const args = z.object(spec.schema).parse(parsed);
416
+ const client = new ThreadsClient(config);
417
+ const ctx = makeContext(client, config, guard);
418
+ // The same gate the MCP path applies, so --confirm, READ_ONLY,
419
+ // ALLOW_DESTRUCTIVE and the audit log all behave identically here.
420
+ if (spec.risk !== "read") {
421
+ const summary = spec.summary?.(args) ?? spec.name;
422
+ guard.check(spec.name, spec.risk, args.confirm, summary);
423
+ }
424
+ const result = await spec.handler(args, ctx);
425
+ emit(select?.length ? selectFields(result, select) : result, format);
426
+ return EXIT.ok;
427
+ }
428
+ catch (error) {
429
+ if (error instanceof UsageError) {
430
+ emitError(error);
431
+ if (!agent)
432
+ process.stderr.write(renderToolHelp(spec));
433
+ return EXIT.usage;
434
+ }
435
+ if (error instanceof z.ZodError) {
436
+ const first = error.issues[0];
437
+ emitError(new Error(first ? `${first.path.join(".") || "argument"}: ${first.message}` : error.message));
438
+ return EXIT.usage;
439
+ }
440
+ emitError(error);
441
+ return exitCodeFor(error);
442
+ }
443
+ }
444
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Resolving credentials, and the multi-account model.
3
+ *
4
+ * Threads is not like a platform with app passwords. Every credential here is
5
+ * an OAuth token minted against a Meta app, it is bound to one Threads profile,
6
+ * and it dies after 60 days unless something refreshes it. That shapes the
7
+ * whole design: tokens arrive from three places, and the one that matters most
8
+ * is the token store `threads-mcp login` writes, because that is the only one
9
+ * this server can keep alive on its own.
10
+ *
11
+ * Three sources, in priority order:
12
+ * 1. THREADS_ACCOUNTS a JSON array, for several profiles at once
13
+ * 2. THREADS_ACCESS_TOKEN the single-account variable
14
+ * 3. the token store ~/.threads-mcp/tokens.json, written by `login`
15
+ *
16
+ * The store is last rather than first so an explicit environment variable
17
+ * always wins. Someone who exports a token into one client's config expects
18
+ * that token to be the one used, not a stale one a login left on disk months
19
+ * ago.
20
+ *
21
+ * `user_id` is deliberately optional everywhere. Almost every Threads endpoint
22
+ * is keyed by the numeric profile id, and asking a person to find theirs before
23
+ * anything works is a setup step with no reason to exist: `GET /me` returns it,
24
+ * and the client resolves and caches it on first use.
25
+ */
26
+ export type Account = {
27
+ /** Long-lived user access token for one Threads profile. */
28
+ accessToken: string;
29
+ /**
30
+ * Numeric Threads profile id. Optional: resolved from `GET /me` and cached
31
+ * on first use when it is not supplied.
32
+ */
33
+ userId?: string;
34
+ /**
35
+ * Username without the @, when known. Used for matching an `account`
36
+ * argument and for display. Resolved from `GET /me` when absent.
37
+ */
38
+ username?: string;
39
+ /** Unix ms when this token expires, when known. */
40
+ expiresAt?: number;
41
+ /** Where this credential came from. Shown by `doctor` and `list_accounts`. */
42
+ source: "env" | "env-json" | "store";
43
+ };
44
+ export type Config = {
45
+ accounts: Account[];
46
+ /** Usernames preferred, in order, when a tool is called without `account`. */
47
+ preferred: string[];
48
+ /** Meta app credentials. Needed by `login` and by token refresh. */
49
+ appId?: string;
50
+ appSecret?: string;
51
+ readOnly: boolean;
52
+ allowDestructive: boolean;
53
+ /**
54
+ * Refresh a token this many days before it expires.
55
+ *
56
+ * Wide on purpose. Meta refuses to refresh a token in its first 24 hours, so
57
+ * a narrow window plus infrequent runs can miss every chance it gets. A wide
58
+ * one means many attempts before anything actually lapses, and refreshing
59
+ * twice just resets the clock twice.
60
+ */
61
+ refreshWindowDays: number;
62
+ /** Write refreshed tokens back to the store. */
63
+ persistTokens: boolean;
64
+ storePath: string;
65
+ requestTimeoutMs: number;
66
+ minRequestIntervalMs: number;
67
+ maxRetries: number;
68
+ /** How long to wait for a media container to finish processing. */
69
+ containerTimeoutMs: number;
70
+ graphHost: string;
71
+ userAgent: string;
72
+ auditPath?: string;
73
+ };
74
+ export declare const DEFAULT_GRAPH_HOST = "https://graph.threads.net";
75
+ /** Where `login` writes tokens, and where refreshed tokens are written back. */
76
+ export declare function defaultStorePath(): string;
77
+ /** Strip a leading @ and lowercase. */
78
+ export declare function normalizeUsername(raw: string): string;
79
+ /**
80
+ * Read `THREADS_ACCOUNTS`, a JSON array.
81
+ *
82
+ * Both snake_case and camelCase keys are accepted, because the same JSON gets
83
+ * pasted between a shell export and a client config file, and the two
84
+ * conventions do not survive that trip intact.
85
+ */
86
+ export declare function accountsFromJson(raw: string | undefined): Account[];
87
+ export declare function loadConfig(stored?: Account[]): Config;
88
+ /**
89
+ * Pick which profile a call acts as.
90
+ *
91
+ * With no hint: the first configured `THREADS_DEFAULT_ACCOUNT` that is actually
92
+ * connected, else the first account. Exact username match beats prefix match,
93
+ * because "navid" is a prefix of "navidmedia", and a prefix-first search would
94
+ * hand an unnamed post to the wrong profile whenever both are connected. A
95
+ * name that matches nothing fails and lists what is connected, rather than
96
+ * quietly posting somewhere else.
97
+ */
98
+ export declare function selectAccount(config: Config, hint?: string): Account;