@thenavidm/midjourney-mcp-cli 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.
Files changed (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +677 -0
  3. package/SKILL.md +184 -0
  4. package/dist/api/client.d.ts +72 -0
  5. package/dist/api/client.js +278 -0
  6. package/dist/api/client.js.map +1 -0
  7. package/dist/api/download.d.ts +41 -0
  8. package/dist/api/download.js +108 -0
  9. package/dist/api/download.js.map +1 -0
  10. package/dist/api/errors.d.ts +75 -0
  11. package/dist/api/errors.js +166 -0
  12. package/dist/api/errors.js.map +1 -0
  13. package/dist/api/jobs.d.ts +140 -0
  14. package/dist/api/jobs.js +296 -0
  15. package/dist/api/jobs.js.map +1 -0
  16. package/dist/api/moodboards.d.ts +88 -0
  17. package/dist/api/moodboards.js +189 -0
  18. package/dist/api/moodboards.js.map +1 -0
  19. package/dist/capture.d.ts +27 -0
  20. package/dist/capture.js +162 -0
  21. package/dist/capture.js.map +1 -0
  22. package/dist/cli.d.ts +92 -0
  23. package/dist/cli.js +633 -0
  24. package/dist/cli.js.map +1 -0
  25. package/dist/config.d.ts +37 -0
  26. package/dist/config.js +90 -0
  27. package/dist/config.js.map +1 -0
  28. package/dist/content/prompt.d.ts +69 -0
  29. package/dist/content/prompt.js +173 -0
  30. package/dist/content/prompt.js.map +1 -0
  31. package/dist/doctor.d.ts +19 -0
  32. package/dist/doctor.js +161 -0
  33. package/dist/doctor.js.map +1 -0
  34. package/dist/format/jobs.d.ts +71 -0
  35. package/dist/format/jobs.js +211 -0
  36. package/dist/format/jobs.js.map +1 -0
  37. package/dist/index.d.ts +13 -0
  38. package/dist/index.js +161 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/safety.d.ts +52 -0
  41. package/dist/safety.js +100 -0
  42. package/dist/safety.js.map +1 -0
  43. package/dist/server.d.ts +10 -0
  44. package/dist/server.js +57 -0
  45. package/dist/server.js.map +1 -0
  46. package/dist/tools/create.d.ts +96 -0
  47. package/dist/tools/create.js +375 -0
  48. package/dist/tools/create.js.map +1 -0
  49. package/dist/tools/download.d.ts +17 -0
  50. package/dist/tools/download.js +47 -0
  51. package/dist/tools/download.js.map +1 -0
  52. package/dist/tools/explore.d.ts +8 -0
  53. package/dist/tools/explore.js +57 -0
  54. package/dist/tools/explore.js.map +1 -0
  55. package/dist/tools/index.d.ts +3 -0
  56. package/dist/tools/index.js +16 -0
  57. package/dist/tools/index.js.map +1 -0
  58. package/dist/tools/jobs.d.ts +18 -0
  59. package/dist/tools/jobs.js +92 -0
  60. package/dist/tools/jobs.js.map +1 -0
  61. package/dist/tools/kit.d.ts +84 -0
  62. package/dist/tools/kit.js +104 -0
  63. package/dist/tools/kit.js.map +1 -0
  64. package/dist/tools/library.d.ts +22 -0
  65. package/dist/tools/library.js +185 -0
  66. package/dist/tools/library.js.map +1 -0
  67. package/dist/tools/profile.d.ts +2 -0
  68. package/dist/tools/profile.js +89 -0
  69. package/dist/tools/profile.js.map +1 -0
  70. package/dist/transport/cdp.d.ts +217 -0
  71. package/dist/transport/cdp.js +607 -0
  72. package/dist/transport/cdp.js.map +1 -0
  73. package/dist/transport/http.d.ts +18 -0
  74. package/dist/transport/http.js +48 -0
  75. package/dist/transport/http.js.map +1 -0
  76. package/package.json +72 -0
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Record what the Midjourney web app actually calls.
3
+ *
4
+ * Midjourney has no API documentation, so every endpoint this server knows
5
+ * about was learned by watching the site. The reference implementation for this
6
+ * API did that once, by hand, and froze the result: twelve read endpoints from
7
+ * a single browsing session, and no way for anyone to extend it without
8
+ * repeating the whole exercise.
9
+ *
10
+ * Making it a command changes that. Run capture, use the site normally, click
11
+ * the thing that has no tool yet, and the request appears in the output with
12
+ * its method, path, query and body. That is the input to a new tool, and it
13
+ * takes a minute rather than an afternoon.
14
+ *
15
+ * It records the account's own traffic in its own browser. It never touches the
16
+ * request headers, which is deliberate: the interesting part is the shape of
17
+ * the call, and writing session cookies into a file people will paste into
18
+ * issues is a good way to leak an account.
19
+ */
20
+ import { writeFile } from "node:fs/promises";
21
+ import { CdpBrowser, CdpSession } from "./transport/cdp.js";
22
+ const REDACTED = new Set(["cookie", "authorization", "x-csrf-token", "set-cookie"]);
23
+ /** Never write a credential to disk, whatever shape it arrives in. */
24
+ function scrub(value, depth = 0) {
25
+ if (depth > 6)
26
+ return "[deep]";
27
+ if (Array.isArray(value))
28
+ return value.slice(0, 5).map((item) => scrub(item, depth + 1));
29
+ if (value === null || typeof value !== "object")
30
+ return value;
31
+ const out = {};
32
+ for (const [key, nested] of Object.entries(value)) {
33
+ if (REDACTED.has(key.toLowerCase())) {
34
+ out[key] = "[redacted]";
35
+ continue;
36
+ }
37
+ out[key] = scrub(nested, depth + 1);
38
+ }
39
+ return out;
40
+ }
41
+ function parseBody(raw) {
42
+ if (!raw)
43
+ return undefined;
44
+ try {
45
+ return scrub(JSON.parse(raw));
46
+ }
47
+ catch {
48
+ return raw.slice(0, 300);
49
+ }
50
+ }
51
+ /** Trim a response to something readable without pasting a whole feed into a file. */
52
+ function sample(text) {
53
+ try {
54
+ const parsed = JSON.parse(text);
55
+ if (Array.isArray(parsed)) {
56
+ return { _array_of: parsed.length, first: scrub(parsed[0]) };
57
+ }
58
+ return scrub(parsed);
59
+ }
60
+ catch {
61
+ return text.slice(0, 200);
62
+ }
63
+ }
64
+ export async function runCapture(config, options) {
65
+ const browser = new CdpBrowser({
66
+ cdpUrl: config.cdpUrl,
67
+ profileDir: config.profileDir,
68
+ chromePath: config.chromePath,
69
+ autoLaunch: config.autoLaunch,
70
+ headless: false,
71
+ timeoutMs: config.requestTimeoutMs,
72
+ origin: config.origin,
73
+ });
74
+ await browser.launch();
75
+ const targets = (await fetch(`${config.cdpUrl}/json/list`).then((response) => response.json()));
76
+ const host = new URL(config.origin).host;
77
+ const page = targets.find((target) => target.type === "page" && target.webSocketDebuggerUrl && target.url.includes(host));
78
+ if (!page?.webSocketDebuggerUrl) {
79
+ process.stderr.write(`No ${host} tab is open in the controlled browser. Open one, then run capture again.\n`);
80
+ return 1;
81
+ }
82
+ const session = new CdpSession(page.webSocketDebuggerUrl, config.requestTimeoutMs);
83
+ await session.connect();
84
+ await session.send("Network.enable");
85
+ const observed = new Map();
86
+ const inFlight = new Map();
87
+ session.on("Network.requestWillBeSent", (params) => {
88
+ const event = params;
89
+ let url;
90
+ try {
91
+ url = new URL(event.request.url);
92
+ }
93
+ catch {
94
+ return;
95
+ }
96
+ if (url.host !== host)
97
+ return;
98
+ if (!options.all && !url.pathname.startsWith("/api/"))
99
+ return;
100
+ const key = `${event.request.method} ${url.pathname}`;
101
+ const existing = observed.get(key);
102
+ if (existing) {
103
+ existing.count += 1;
104
+ }
105
+ else {
106
+ observed.set(key, {
107
+ method: event.request.method,
108
+ path: url.pathname,
109
+ query: Object.fromEntries(url.searchParams.entries()),
110
+ requestBody: parseBody(event.request.postData),
111
+ count: 1,
112
+ });
113
+ }
114
+ inFlight.set(event.requestId, { key });
115
+ process.stderr.write(` ${event.request.method} ${url.pathname}\n`);
116
+ });
117
+ session.on("Network.responseReceived", (params) => {
118
+ const event = params;
119
+ const pending = inFlight.get(event.requestId);
120
+ if (!pending)
121
+ return;
122
+ const entry = observed.get(pending.key);
123
+ if (entry)
124
+ entry.status = event.response.status;
125
+ });
126
+ process.stderr.write(`\nRecording ${host} API traffic for ${options.seconds}s.\nUse the site in the controlled window: click the thing you want a tool for.\n\n`);
127
+ await new Promise((resolve) => setTimeout(resolve, options.seconds * 1000));
128
+ // Bodies are fetched at the end rather than as they arrive, because asking
129
+ // for one mid-flight can stall the page the user is still driving.
130
+ for (const [requestId, pending] of inFlight) {
131
+ const entry = observed.get(pending.key);
132
+ if (!entry || entry.responseSample !== undefined)
133
+ continue;
134
+ try {
135
+ const body = await session.send("Network.getResponseBody", { requestId });
136
+ if (!body.base64Encoded)
137
+ entry.responseSample = sample(body.body);
138
+ }
139
+ catch {
140
+ // The body is gone from the cache. The shape of the request is still the
141
+ // useful half.
142
+ }
143
+ }
144
+ session.close();
145
+ const result = {
146
+ captured_at: new Date().toISOString(),
147
+ origin: config.origin,
148
+ seconds: options.seconds,
149
+ endpoint_count: observed.size,
150
+ endpoints: [...observed.values()].sort((a, b) => a.path.localeCompare(b.path)),
151
+ };
152
+ const json = JSON.stringify(result, null, 2);
153
+ if (options.outPath) {
154
+ await writeFile(options.outPath, `${json}\n`);
155
+ process.stderr.write(`\n${observed.size} endpoint(s) written to ${options.outPath}\n`);
156
+ }
157
+ else {
158
+ process.stdout.write(`${json}\n`);
159
+ }
160
+ return 0;
161
+ }
162
+ //# sourceMappingURL=capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.js","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,92 @@
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. `submit_imagine` runs as `submit-imagine`, and
10
+ * the 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 { type ZodRawShape } from "zod";
18
+ import { type AnyToolSpec } from "./tools/kit.js";
19
+ /** How a value reaches the parser, once the Zod wrappers are peeled off. */
20
+ type FlagKind = "string" | "number" | "boolean" | "enum" | "json";
21
+ type Flag = {
22
+ key: string;
23
+ flag: string;
24
+ kind: FlagKind;
25
+ required: boolean;
26
+ repeatable: boolean;
27
+ choices?: string[];
28
+ help: string;
29
+ };
30
+ export declare function flagsFor(shape: ZodRawShape): Flag[];
31
+ /**
32
+ * Midjourney's own parameter spellings, accepted as flags.
33
+ *
34
+ * The schema names things in full because a tool description is read by a model
35
+ * that has never seen a Midjourney prompt. A person at a terminal has, and they
36
+ * will type `--ar 16:9`, because that is what the parameter is called
37
+ * everywhere Midjourney documents it. Refusing the name the whole ecosystem
38
+ * uses, to protect a naming convention nobody outside this repo can see, would
39
+ * be the wrong trade.
40
+ */
41
+ export declare const FLAG_ALIASES: Record<string, string>;
42
+ /**
43
+ * Parse argv against a tool's flags.
44
+ *
45
+ * Zod does the real validation afterwards, so this only has to get values into
46
+ * the right JavaScript types and catch the mistakes Zod would otherwise report
47
+ * in terms of a schema the person at the terminal never sees.
48
+ */
49
+ export declare function parseArgs(argv: string[], flags: Flag[]): Record<string, unknown>;
50
+ /**
51
+ * Keep only the named fields.
52
+ *
53
+ * These endpoints are verbose: one explore page is tens of kilobytes of JSON,
54
+ * most of it layout hints. An agent piping that into its own context pays for
55
+ * every byte. `--select id,status,images` cuts it to what was asked for.
56
+ * Dotted paths descend, and arrays are traversed element-wise.
57
+ */
58
+ export declare function selectFields(data: unknown, paths: string[]): unknown;
59
+ /** Errors are JSON on stderr, always, so a caller parses one shape. */
60
+ export declare function emitError(error: unknown): void;
61
+ /**
62
+ * The name this was invoked as, so examples are copy-pasteable.
63
+ *
64
+ * The package puts two binaries on the same file. Printing `midjourney-mcp` at
65
+ * someone who typed `midjourney-cli` hands them a command that works but is not
66
+ * the one in their fingers.
67
+ */
68
+ export declare function binName(): string;
69
+ /**
70
+ * Words people use mapped onto words the tools use.
71
+ *
72
+ * Without this, "make a picture" matches nothing, because every tool says
73
+ * "generate" and "image". A lookup that only works when you already know the
74
+ * vocabulary is not a lookup.
75
+ */
76
+ export declare const SYNONYMS: Record<string, string[]>;
77
+ /**
78
+ * Resolve a capability described in words to the command that does it.
79
+ *
80
+ * An agent that knows what it wants but not what this tool calls it would
81
+ * otherwise read the full tool list to find out, which is the cost the CLI
82
+ * exists to avoid. Scoring is deliberately dumb: name and title carry the most
83
+ * weight, because a tool called `download_job` should win "download my images"
84
+ * without any cleverness.
85
+ */
86
+ export declare function whichCommand(query: string): {
87
+ tool: AnyToolSpec;
88
+ score: number;
89
+ }[];
90
+ export declare function isCliCommand(argv: string[]): boolean;
91
+ export declare function runCli(argv: string[]): Promise<number>;
92
+ export {};