text2image-mcp 2.0.1 → 2.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.
package/README.md CHANGED
@@ -159,6 +159,68 @@ npx text2image-mcp
159
159
  # This creates a local .nano-banana-config.json file
160
160
  ```
161
161
 
162
+ ## 🌐 Remote Server Mode
163
+
164
+ Run text2image-mcp as an HTTP server so anyone can connect with their own Gemini API key — no local install needed.
165
+
166
+ ### Quick Start
167
+
168
+ ```bash
169
+ # Install and build
170
+ npm install && npm run build
171
+
172
+ # Start the remote server (default port 3000)
173
+ npm run start:remote
174
+
175
+ # Or with a custom port
176
+ PORT=8080 npm run start:remote
177
+ ```
178
+
179
+ ### Docker Deployment
180
+
181
+ ```bash
182
+ # Build the image
183
+ docker build -t text2image-mcp .
184
+
185
+ # Run the container
186
+ docker run -p 3000:3000 text2image-mcp
187
+ ```
188
+
189
+ Deploy to any container platform (Railway, Render, Fly.io, etc.) by pointing to the Dockerfile.
190
+
191
+ ### Client Configuration
192
+
193
+ Connect any MCP client using a URL and your Gemini API key as a Bearer token:
194
+
195
+ ```json
196
+ {
197
+ "mcpServers": {
198
+ "text2image": {
199
+ "url": "https://your-server.com/mcp",
200
+ "headers": {
201
+ "Authorization": "Bearer YOUR_GEMINI_API_KEY"
202
+ }
203
+ }
204
+ }
205
+ }
206
+ ```
207
+
208
+ ### Endpoints
209
+
210
+ | Method | Path | Description |
211
+ |--------|------|-------------|
212
+ | `POST` | `/mcp` | MCP JSON-RPC (initialize + tool calls) |
213
+ | `GET` | `/mcp` | SSE stream for existing sessions |
214
+ | `DELETE` | `/mcp` | Terminate a session |
215
+ | `GET` | `/health` | Health check + active session count |
216
+
217
+ ### How It Works
218
+
219
+ - **Auth**: Your Gemini API key is passed as `Authorization: Bearer <key>` — the server never stores it
220
+ - **Sessions**: Each connection gets an isolated server instance with independent state (chat history, last image, etc.)
221
+ - **Timeout**: Idle sessions are cleaned up after 30 minutes
222
+ - **Tools**: Remote mode exposes 4 tools (`generate_image`, `edit_image`, `continue_editing`, `get_last_image_info`) — config tools are excluded since the API key comes from the auth header
223
+
162
224
  ## 🛠️ Available Commands
163
225
 
164
226
  ### `generate_image`
package/dist/config.d.ts CHANGED
@@ -7,6 +7,7 @@ export declare class ConfigManager {
7
7
  configSource: ConfigSource;
8
8
  isConfigured(): boolean;
9
9
  load(): Promise<void>;
10
+ configureFromKey(apiKey: string): void;
10
11
  setApiKey(apiKey: string): Promise<void>;
11
12
  private save;
12
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAK5C,OAAO,EAAE,MAAM,EAAgB,MAAM,YAAY,CAAC;AAIlD,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,aAAa,GAAG,gBAAgB,CAAC;AAE5E,qBAAa,aAAa;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC7B,KAAK,EAAE,WAAW,GAAG,IAAI,CAAQ;IACjC,YAAY,EAAE,YAAY,CAAoB;IAE9C,YAAY,IAAI,OAAO;IAIjB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA2BrB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAQhC,IAAI;CAMnB"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAK5C,OAAO,EAAE,MAAM,EAAgB,MAAM,YAAY,CAAC;AAIlD,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,aAAa,GAAG,gBAAgB,CAAC;AAE5E,qBAAa,aAAa;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC7B,KAAK,EAAE,WAAW,GAAG,IAAI,CAAQ;IACjC,YAAY,EAAE,YAAY,CAAoB;IAE9C,YAAY,IAAI,OAAO;IAIjB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B3B,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAOhC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAQhC,IAAI;CAMnB"}
package/dist/config.js CHANGED
@@ -39,6 +39,12 @@ export class ConfigManager {
39
39
  this.configSource = "not_configured";
40
40
  }
41
41
  }
42
+ configureFromKey(apiKey) {
43
+ ConfigSchema.parse({ geminiApiKey: apiKey });
44
+ this.config = { geminiApiKey: apiKey };
45
+ this.genAI = new GoogleGenAI({ apiKey });
46
+ this.configSource = "environment";
47
+ }
42
48
  async setApiKey(apiKey) {
43
49
  ConfigSchema.parse({ geminiApiKey: apiKey });
44
50
  this.config = { geminiApiKey: apiKey };
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAU,YAAY,EAAE,MAAM,YAAY,CAAC;AAElD,YAAY,EAAE,CAAC;AAIf,MAAM,OAAO,aAAa;IACxB,MAAM,GAAkB,IAAI,CAAC;IAC7B,KAAK,GAAuB,IAAI,CAAC;IACjC,YAAY,GAAiB,gBAAgB,CAAC;IAE9C,YAAY;QACV,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,IAAI;QACR,mCAAmC;QACnC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAC7C,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC;gBACH,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,CAAC;gBAC9D,IAAI,CAAC,KAAK,GAAG,IAAI,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;gBACnE,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC;gBAClC,OAAO;YACT,CAAC;YAAC,MAAM,CAAC;gBACP,4BAA4B;YAC9B,CAAC;QACH,CAAC;QAED,0BAA0B;QAC1B,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,0BAA0B,CAAC,CAAC;YACxE,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACtC,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACzC,IAAI,CAAC,KAAK,GAAG,IAAI,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;YACnE,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,YAAY,GAAG,gBAAgB,CAAC;QACvC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,MAAc;QAC5B,YAAY,CAAC,KAAK,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;QACvC,IAAI,CAAC,KAAK,GAAG,IAAI,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC;QAClC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,0BAA0B,CAAC,CAAC;YACxE,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"image-utils.d.ts","sourceRoot":"","sources":["../src/image-utils.ts"],"names":[],"mappings":"AAKA,wBAAgB,kBAAkB,IAAI,MAAM,CAa3C;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAapD;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,WAAW,GAAG,QAAQ,GAC7B,OAAO,CAAC,UAAU,CAAC,CAarB;AAED,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAMD"}
1
+ {"version":3,"file":"image-utils.d.ts","sourceRoot":"","sources":["../src/image-utils.ts"],"names":[],"mappings":"AAKA,wBAAgB,kBAAkB,IAAI,MAAM,CAiB3C;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAapD;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,WAAW,GAAG,QAAQ,GAC7B,OAAO,CAAC,UAAU,CAAC,CAarB;AAED,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAMD"}
@@ -3,6 +3,9 @@ import fs from "fs/promises";
3
3
  import path from "path";
4
4
  import os from "os";
5
5
  export function getImagesDirectory() {
6
+ if (process.env.IMAGE_OUTPUT_DIR) {
7
+ return process.env.IMAGE_OUTPUT_DIR;
8
+ }
6
9
  const platform = os.platform();
7
10
  if (platform === "win32") {
8
11
  return path.join(os.homedir(), "Documents", "nano-banana-images");
@@ -1 +1 @@
1
- {"version":3,"file":"image-utils.js","sourceRoot":"","sources":["../src/image-utils.ts"],"names":[],"mappings":"AAAA,qBAAqB;AACrB,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,UAAU,kBAAkB;IAChC,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IAE/B,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,oBAAoB,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAClF,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,oBAAoB,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IACjD,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,MAAM,CAAC;QACZ,KAAK,OAAO;YACV,OAAO,YAAY,CAAC;QACtB,KAAK,MAAM;YACT,OAAO,WAAW,CAAC;QACrB,KAAK,OAAO;YACV,OAAO,YAAY,CAAC;QACtB;YACE,OAAO,YAAY,CAAC;IACxB,CAAC;AACH,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,UAAkB,EAClB,MAA8B;IAE9B,MAAM,SAAS,GAAG,kBAAkB,EAAE,CAAC;IACvC,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/C,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,GAAG,MAAM,IAAI,SAAS,IAAI,QAAQ,MAAM,CAAC;IAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAEhD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACjD,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAErC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,SAAiB;IAIvD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC5C,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACjC,QAAQ,EAAE,WAAW,CAAC,SAAS,CAAC;KACjC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"image-utils.js","sourceRoot":"","sources":["../src/image-utils.ts"],"names":[],"mappings":"AAAA,qBAAqB;AACrB,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,UAAU,kBAAkB;IAChC,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACjC,OAAO,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IACtC,CAAC;IAED,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IAE/B,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,oBAAoB,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAClF,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,oBAAoB,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IACjD,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,MAAM,CAAC;QACZ,KAAK,OAAO;YACV,OAAO,YAAY,CAAC;QACtB,KAAK,MAAM;YACT,OAAO,WAAW,CAAC;QACrB,KAAK,OAAO;YACV,OAAO,YAAY,CAAC;QACtB;YACE,OAAO,YAAY,CAAC;IACxB,CAAC;AACH,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,UAAkB,EAClB,MAA8B;IAE9B,MAAM,SAAS,GAAG,kBAAkB,EAAE,CAAC;IACvC,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/C,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,GAAG,MAAM,IAAI,SAAS,IAAI,QAAQ,MAAM,CAAC;IAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAEhD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACjD,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAErC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,SAAiB;IAIvD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC5C,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACjC,QAAQ,EAAE,WAAW,CAAC,SAAS,CAAC;KACjC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=remote.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":""}
package/dist/remote.js ADDED
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env node
2
+ // src/remote.ts
3
+ import express from "express";
4
+ import cors from "cors";
5
+ import { randomUUID } from "crypto";
6
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
7
+ import { NanoBananaMCP } from "./server.js";
8
+ const SESSION_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes
9
+ const sessions = new Map();
10
+ // --- Cleanup stale sessions ---
11
+ const cleanupInterval = setInterval(() => {
12
+ const now = Date.now();
13
+ for (const [id, session] of sessions) {
14
+ if (now - session.lastActivity > SESSION_TIMEOUT_MS) {
15
+ session.transport.close();
16
+ sessions.delete(id);
17
+ }
18
+ }
19
+ }, 60_000);
20
+ // --- Express app ---
21
+ const app = express();
22
+ app.use(cors());
23
+ app.use(express.json());
24
+ // --- Health endpoint ---
25
+ app.get("/health", (_req, res) => {
26
+ res.json({ status: "ok", sessions: sessions.size });
27
+ });
28
+ // --- MCP endpoint ---
29
+ function extractApiKey(req) {
30
+ const auth = req.headers.authorization;
31
+ if (!auth?.startsWith("Bearer "))
32
+ return null;
33
+ return auth.slice(7).trim() || null;
34
+ }
35
+ function isInitializeRequest(body) {
36
+ if (Array.isArray(body)) {
37
+ return body.some((msg) => typeof msg === "object" && msg !== null && msg.method === "initialize");
38
+ }
39
+ return typeof body === "object" && body !== null && body.method === "initialize";
40
+ }
41
+ app.post("/mcp", async (req, res) => {
42
+ const apiKey = extractApiKey(req);
43
+ if (!apiKey) {
44
+ res.status(401).json({ error: "Missing Authorization: Bearer <GEMINI_API_KEY>" });
45
+ return;
46
+ }
47
+ // Check for existing session
48
+ const sessionId = req.headers["mcp-session-id"];
49
+ if (sessionId) {
50
+ const session = sessions.get(sessionId);
51
+ if (!session) {
52
+ res.status(404).json({ error: "Session not found. Send an initialize request to start a new session." });
53
+ return;
54
+ }
55
+ session.lastActivity = Date.now();
56
+ await session.transport.handleRequest(req, res, req.body);
57
+ return;
58
+ }
59
+ // No session ID — must be an initialize request
60
+ if (!isInitializeRequest(req.body)) {
61
+ res.status(400).json({ error: "Missing mcp-session-id header. Send an initialize request first." });
62
+ return;
63
+ }
64
+ // Create new session
65
+ const mcp = new NanoBananaMCP({ apiKey, isRemote: true });
66
+ const transport = new StreamableHTTPServerTransport({
67
+ sessionIdGenerator: () => randomUUID(),
68
+ onsessioninitialized: (newSessionId) => {
69
+ sessions.set(newSessionId, { transport, mcp, lastActivity: Date.now() });
70
+ },
71
+ onsessionclosed: (closedSessionId) => {
72
+ sessions.delete(closedSessionId);
73
+ },
74
+ });
75
+ await mcp.connectTransport(transport);
76
+ await transport.handleRequest(req, res, req.body);
77
+ });
78
+ app.get("/mcp", async (req, res) => {
79
+ const sessionId = req.headers["mcp-session-id"];
80
+ if (!sessionId) {
81
+ res.status(400).json({ error: "Missing mcp-session-id header." });
82
+ return;
83
+ }
84
+ const session = sessions.get(sessionId);
85
+ if (!session) {
86
+ res.status(404).json({ error: "Session not found." });
87
+ return;
88
+ }
89
+ session.lastActivity = Date.now();
90
+ await session.transport.handleRequest(req, res);
91
+ });
92
+ app.delete("/mcp", async (req, res) => {
93
+ const sessionId = req.headers["mcp-session-id"];
94
+ if (!sessionId) {
95
+ res.status(400).json({ error: "Missing mcp-session-id header." });
96
+ return;
97
+ }
98
+ const session = sessions.get(sessionId);
99
+ if (!session) {
100
+ res.status(404).json({ error: "Session not found." });
101
+ return;
102
+ }
103
+ await session.transport.handleRequest(req, res);
104
+ sessions.delete(sessionId);
105
+ });
106
+ // --- Start server ---
107
+ const PORT = parseInt(process.env.PORT || "3000", 10);
108
+ const server = app.listen(PORT, () => {
109
+ console.log(`text2image-mcp remote server listening on port ${PORT}`);
110
+ console.log(`Health: http://localhost:${PORT}/health`);
111
+ console.log(`MCP endpoint: http://localhost:${PORT}/mcp`);
112
+ });
113
+ // --- Graceful shutdown ---
114
+ function shutdown() {
115
+ console.log("\nShutting down...");
116
+ clearInterval(cleanupInterval);
117
+ for (const [id, session] of sessions) {
118
+ session.transport.close();
119
+ sessions.delete(id);
120
+ }
121
+ server.close(() => {
122
+ process.exit(0);
123
+ });
124
+ }
125
+ process.on("SIGINT", shutdown);
126
+ process.on("SIGTERM", shutdown);
127
+ //# sourceMappingURL=remote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote.js","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts CHANGED
@@ -1,11 +1,19 @@
1
+ import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
2
+ export interface NanoBananaMCPOptions {
3
+ apiKey?: string;
4
+ isRemote?: boolean;
5
+ }
1
6
  export declare class NanoBananaMCP {
2
7
  private server;
3
8
  private configManager;
4
9
  private chatSession;
5
10
  private lastImagePath;
6
- constructor();
11
+ private isRemote;
12
+ private injectedApiKey;
13
+ constructor(options?: NanoBananaMCPOptions);
7
14
  private setupHandlers;
8
15
  private routeToolCall;
16
+ connectTransport(transport: Transport): Promise<void>;
9
17
  run(): Promise<void>;
10
18
  }
11
19
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAqBA,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,WAAW,CAAmC;IACtD,OAAO,CAAC,aAAa,CAAuB;;IAW5C,OAAO,CAAC,aAAa;YA2BP,aAAa;IAuDrB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAK3B"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAY1E,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,WAAW,CAAmC;IACtD,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,cAAc,CAAqB;gBAE/B,OAAO,CAAC,EAAE,oBAAoB;IAW1C,OAAO,CAAC,aAAa;YA+BP,aAAa;IAyDrB,gBAAgB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IASrD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAI3B"}
package/dist/server.js CHANGED
@@ -15,23 +15,29 @@ export class NanoBananaMCP {
15
15
  configManager;
16
16
  chatSession = null;
17
17
  lastImagePath = null;
18
- constructor() {
18
+ isRemote;
19
+ injectedApiKey;
20
+ constructor(options) {
21
+ this.isRemote = options?.isRemote ?? false;
22
+ this.injectedApiKey = options?.apiKey;
19
23
  this.configManager = new ConfigManager();
20
- this.server = new Server({ name: "text2image-mcp", version: "2.0.0" }, { capabilities: { tools: {} } });
24
+ this.server = new Server({ name: "text2image-mcp", version: "2.1.0" }, { capabilities: { tools: {} } });
21
25
  this.setupHandlers();
22
26
  }
23
27
  setupHandlers() {
24
- // List tools
25
- this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
26
- tools: [
27
- configureGeminiTokenTool,
28
- getConfigurationStatusTool,
28
+ // List tools — exclude config tools in remote mode
29
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => {
30
+ const tools = [
29
31
  generateImageTool,
30
32
  editImageTool,
31
33
  continueEditingTool,
32
34
  getLastImageInfoTool,
33
- ],
34
- }));
35
+ ];
36
+ if (!this.isRemote) {
37
+ tools.unshift(configureGeminiTokenTool, getConfigurationStatusTool);
38
+ }
39
+ return { tools };
40
+ });
35
41
  // Call tools
36
42
  this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
37
43
  try {
@@ -46,12 +52,14 @@ export class NanoBananaMCP {
46
52
  }
47
53
  async routeToolCall(request) {
48
54
  const { name } = request.params;
49
- // Config tools don't need API key
50
- if (name === "configure_gemini_token") {
51
- return handleConfigureToken(request, this.configManager);
52
- }
53
- if (name === "get_configuration_status") {
54
- return handleGetConfigStatus(this.configManager);
55
+ // Config tools don't need API key (local mode only)
56
+ if (!this.isRemote) {
57
+ if (name === "configure_gemini_token") {
58
+ return handleConfigureToken(request, this.configManager);
59
+ }
60
+ if (name === "get_configuration_status") {
61
+ return handleGetConfigStatus(this.configManager);
62
+ }
55
63
  }
56
64
  // All other tools need configured API
57
65
  if (!this.configManager.isConfigured()) {
@@ -89,10 +97,18 @@ export class NanoBananaMCP {
89
97
  throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
90
98
  }
91
99
  }
100
+ async connectTransport(transport) {
101
+ if (this.injectedApiKey) {
102
+ this.configManager.configureFromKey(this.injectedApiKey);
103
+ }
104
+ else {
105
+ await this.configManager.load();
106
+ }
107
+ await this.server.connect(transport);
108
+ }
92
109
  async run() {
93
- await this.configManager.load();
94
110
  const transport = new StdioServerTransport();
95
- await this.server.connect(transport);
111
+ await this.connectTransport(transport);
96
112
  }
97
113
  }
98
114
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "text2image-mcp",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "description": "MCP server for Google's Gemini image generation API (Flash + Pro) with cross-platform support",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
7
7
  "bin": {
8
- "text2image-mcp": "dist/index.js"
8
+ "text2image-mcp": "dist/index.js",
9
+ "text2image-mcp-remote": "dist/remote.js"
9
10
  },
10
11
  "files": [
11
12
  "dist/",
@@ -15,7 +16,9 @@
15
16
  "scripts": {
16
17
  "build": "tsc",
17
18
  "start": "node dist/index.js",
19
+ "start:remote": "node dist/remote.js",
18
20
  "dev": "tsx src/index.ts",
21
+ "dev:remote": "tsx src/remote.ts",
19
22
  "test": "jest",
20
23
  "lint": "eslint src/**/*.ts",
21
24
  "typecheck": "tsc --noEmit",
@@ -49,10 +52,14 @@
49
52
  "dependencies": {
50
53
  "@google/genai": "^1.16.0",
51
54
  "@modelcontextprotocol/sdk": "^1.0.0",
55
+ "cors": "^2.8.5",
52
56
  "dotenv": "^16.4.5",
57
+ "express": "^5.0.1",
53
58
  "zod": "^3.22.4"
54
59
  },
55
60
  "devDependencies": {
61
+ "@types/cors": "^2.8.17",
62
+ "@types/express": "^5.0.0",
56
63
  "@types/node": "^20.11.0",
57
64
  "@typescript-eslint/eslint-plugin": "^6.19.0",
58
65
  "@typescript-eslint/parser": "^6.19.0",