diff --git a/README.md b/README.md index 805e15d..9668d36 100644 --- a/README.md +++ b/README.md @@ -53,12 +53,44 @@ Add to Claude Desktop or VSCode (including Cursor/Windsurf) config: } ``` +Also supports Azure deployments: + +```json +{ + "mcpServers": { + "openai-gpt-image-mcp": { + "command": "node", + "args": ["/absolute/path/to/dist/index.js"], + "env": { + "AZURE_OPENAI_API_KEY": "sk-...", + "AZURE_OPENAI_ENDPOINT": "my.endpoint.com", + "OPENAI_API_VERSION": "2024-12-01-preview" + } + } + } +} +``` + +Also supports supplying an environment files: + +```json +{ + "mcpServers": { + "openai-gpt-image-mcp": { + "command": "node", + "args": ["/absolute/path/to/dist/index.js", "--env-file", "./deployment/.env"] + } + } +} +``` + --- ## ⚡ Advanced - For `create-image`, set `n` to generate up to 10 images at once. - For `edit-image`, provide a mask image (file path or base64) to control where edits are applied. +- Provide an environment file with `--env-file path/to/file/.env` - See `src/index.ts` for all options. --- @@ -110,4 +142,5 @@ MIT - Built with [@modelcontextprotocol/sdk](https://www.npmjs.com/package/@modelcontextprotocol/sdk) - Uses [openai](https://www.npmjs.com/package/openai) Node.js SDK -- Built by [SureScale.ai](https://surescale.ai) \ No newline at end of file +- Built by [SureScale.ai](https://surescale.ai) +- Contributions from [Axle Research and Technology](https://axleinfo.com/) \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 7b5cb13..2e766c4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,10 +4,44 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; -import { OpenAI, toFile } from "openai"; +import { OpenAI, AzureOpenAI, toFile } from "openai"; import fs from "fs"; import path from "path"; +// Function to load environment variables from a file +const loadEnvFile = (filePath: string) => { + try { + const envConfig = fs.readFileSync(filePath, "utf8"); + envConfig.split("\n").forEach((line) => { + const trimmedLine = line.trim(); + if (trimmedLine && !trimmedLine.startsWith("#")) { + const [key, ...valueParts] = trimmedLine.split("="); + const value = valueParts.join("=").trim(); + if (key) { + // Remove surrounding quotes if present + process.env[key.trim()] = value.startsWith("'") && value.endsWith("'") || value.startsWith("\"") && value.endsWith("\"") + ? value.slice(1, -1) + : value; + } + } + }); + console.log(`Loaded environment variables from ${filePath}`); + } catch (error) { + console.warn(`Warning: Could not read environment file at ${filePath}:`, error); + } +}; + +// Parse command line arguments for --env-file +const cmdArgs = process.argv.slice(2); +const envFileArgIndex = cmdArgs.findIndex(arg => arg === "--env-file"); +if (envFileArgIndex !== -1 && cmdArgs[envFileArgIndex + 1]) { + console.log("Loading environment variables from file:", cmdArgs[envFileArgIndex + 1]); + const envFilePath = cmdArgs[envFileArgIndex + 1]; + loadEnvFile(envFilePath); +} else { + console.log("No environment file provided"); +} + (async () => { const server = new McpServer({ name: "openai-gpt-image-mcp", @@ -60,7 +94,9 @@ import path from "path"; "create-image", (createImageSchema as any)._def.schema.shape, async (args, _extra) => { - const openai = new OpenAI(); + // If AZURE_OPENAI_API_KEY is defined, use the AzureOpenAI class + const openai = process.env.AZURE_OPENAI_API_KEY ? new AzureOpenAI() : new OpenAI(); + // Only allow gpt-image-1 const { prompt, @@ -217,7 +253,7 @@ import path from "path"; throw new Error("Invalid 'mask' input: Must be an absolute path or a base64-encoded string."); } - const openai = new OpenAI(); + const openai = process.env.AZURE_OPENAI_API_KEY ? new AzureOpenAI() : new OpenAI(); const { image: imageInput, prompt,