text2image-mcp 2.0.0 → 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 +67 -5
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +6 -0
- package/dist/config.js.map +1 -1
- package/dist/image-utils.d.ts.map +1 -1
- package/dist/image-utils.js +3 -0
- package/dist/image-utils.js.map +1 -1
- package/dist/remote.d.ts +3 -0
- package/dist/remote.d.ts.map +1 -0
- package/dist/remote.js +127 -0
- package/dist/remote.js.map +1 -0
- package/dist/server.d.ts +9 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +33 -17
- package/dist/server.js.map +1 -1
- package/package.json +12 -5
package/README.md
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
A Model Context Protocol (MCP) server that provides AI image generation and editing capabilities using Google's Gemini API. Supports both **Gemini 2.5 Flash** (fast, efficient) and **Gemini 3 Pro** (high quality, 4K, search grounding). Generate stunning images, edit existing ones, and iterate on your creations with simple text prompts.
|
|
6
6
|
|
|
7
|
-
<a href="https://glama.ai/mcp/servers/@
|
|
8
|
-
<img width="380" height="200" src="https://glama.ai/mcp/servers/@
|
|
7
|
+
<a href="https://glama.ai/mcp/servers/@kishorkukreja/Nano-Banana-MCP">
|
|
8
|
+
<img width="380" height="200" src="https://glama.ai/mcp/servers/@kishorkukreja/Nano-Banana-MCP/badge" alt="Nano-Banana-MCP MCP server" />
|
|
9
9
|
</a>
|
|
10
10
|
|
|
11
11
|
## ✨ Features
|
|
@@ -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`
|
|
@@ -306,7 +368,7 @@ This project was created with Claude Code and follows these technologies:
|
|
|
306
368
|
|
|
307
369
|
```bash
|
|
308
370
|
# Clone the repository
|
|
309
|
-
git clone https://github.com/
|
|
371
|
+
git clone https://github.com/kishorkukreja/Nano-Banana-MCP.git
|
|
310
372
|
cd Nano-Banana-MCP
|
|
311
373
|
|
|
312
374
|
# Install dependencies
|
|
@@ -350,9 +412,9 @@ MIT License - see [LICENSE](LICENSE) file for details.
|
|
|
350
412
|
|
|
351
413
|
## 📞 Support
|
|
352
414
|
|
|
353
|
-
- 🐛 **Issues**: [GitHub Issues](https://github.com/
|
|
415
|
+
- 🐛 **Issues**: [GitHub Issues](https://github.com/kishorkukreja/Nano-Banana-MCP/issues)
|
|
354
416
|
- 📖 **Documentation**: This README and inline code comments
|
|
355
|
-
- 💬 **Discussions**: [GitHub Discussions](https://github.com/
|
|
417
|
+
- 💬 **Discussions**: [GitHub Discussions](https://github.com/kishorkukreja/Nano-Banana-MCP/discussions)
|
|
356
418
|
|
|
357
419
|
---
|
|
358
420
|
|
package/dist/config.d.ts
CHANGED
package/dist/config.d.ts.map
CHANGED
|
@@ -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;
|
|
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 };
|
package/dist/config.js.map
CHANGED
|
@@ -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,
|
|
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"}
|
package/dist/image-utils.js
CHANGED
|
@@ -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");
|
package/dist/image-utils.js.map
CHANGED
|
@@ -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"}
|
package/dist/remote.d.ts
ADDED
|
@@ -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
|
-
|
|
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
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"
|
|
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
|
-
|
|
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.
|
|
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 (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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.
|
|
111
|
+
await this.connectTransport(transport);
|
|
96
112
|
}
|
|
97
113
|
}
|
|
98
114
|
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EAGtB,SAAS,EACT,QAAQ,GACT,MAAM,oCAAoC,CAAC;
|
|
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.
|
|
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": "
|
|
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",
|
|
@@ -35,13 +38,13 @@
|
|
|
35
38
|
],
|
|
36
39
|
"author": "Generated by Claude Code",
|
|
37
40
|
"license": "MIT",
|
|
38
|
-
"homepage": "https://github.com/
|
|
41
|
+
"homepage": "https://github.com/kishorkukreja/Nano-Banana-MCP#readme",
|
|
39
42
|
"repository": {
|
|
40
43
|
"type": "git",
|
|
41
|
-
"url": "git+https://github.com/
|
|
44
|
+
"url": "git+https://github.com/kishorkukreja/Nano-Banana-MCP.git"
|
|
42
45
|
},
|
|
43
46
|
"bugs": {
|
|
44
|
-
"url": "https://github.com/
|
|
47
|
+
"url": "https://github.com/kishorkukreja/Nano-Banana-MCP/issues"
|
|
45
48
|
},
|
|
46
49
|
"engines": {
|
|
47
50
|
"node": ">=18.0.0"
|
|
@@ -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",
|