mcp-openai-platform

mcp-openai-platform

A local MCP server exposing the OpenAI platform REST API as tools for file management, fine-tuning, inference, images, audio, batch processing, and organization usage/costs.

Category
Visit Server

README

mcp-openai-platform

A local MCP (Model Context Protocol) server exposing the OpenAI platform REST API as tools — files, fine-tuning, inference, images, audio, batch, and organization usage/costs.

Built for this project after doing a full fine-tuning run by hand with curl; the tool descriptions encode the gotchas found along the way (see Notable behaviours) so they don't have to be rediscovered.

What this is (and isn't)

This is: a stdio MCP server that your MCP client (Claude Code, etc.) runs locally. The client calls these tools; the tools call OpenAI's REST API.

Claude Code (MCP client)
  → mcp-openai-platform (local stdio server)
    → https://api.openai.com/v1/...

This is not: a server for OpenAI's models to call. OpenAI's own docs on MCP and connectors and Secure MCP Tunnels describe the opposite direction — the Responses API consuming a remote MCP server over the network, with OAuth and tunnels. None of that applies here; this is a plain local server and needs no OAuth, no tunnel, no public URL.

Install

Requires Node.js 18+ (uses built-in fetch and FormData; developed on Node 24).

cd mcp-openai
npm install
npm run build          # compiles src/ → dist/

Verify the build produced dist/index.js:

ls dist/               # index.js, openai-client.js

The server is now runnable but does nothing on its own — it speaks MCP over stdio and needs a client to drive it. Register it using one of the methods below.

Adding it to an agent / MCP client

The server is a stdio MCP server, so registration is the same shape everywhere: command = node, args = absolute path to dist/index.js, env = your API keys.

Use the absolute path — MCP clients don't reliably resolve relative paths, and the working directory at launch isn't guaranteed.

Claude Code — CLI (quickest)

claude mcp add openai-platform \
  --env OPENAI_API_KEY=sk-proj-... \
  --env OPENAI_ADMIN_API_KEY=sk-admin-... \
  -- node /absolute/path/to/mcp-openai/dist/index.js

On Windows, use the Windows-style absolute path:

claude mcp add openai-platform ^
  --env OPENAI_API_KEY=sk-proj-... ^
  -- node E:\wamp64\www\Ticketing_new\mcp-openai\dist\index.js

Add --scope project to write it into the project's .mcp.json (shared with the repo) instead of your personal config. Then:

claude mcp list           # confirm it's registered
claude mcp get openai-platform

Claude Code — project config file

Edit .mcp.json at the project root (this is what this project uses):

{
  "mcpServers": {
    "openai-platform": {
      "type": "stdio",
      "command": "node",
      "args": ["E:\\wamp64\\www\\Ticketing_new\\mcp-openai\\dist\\index.js"],
      "env": {
        "OPENAI_API_KEY": "sk-proj-...",
        "OPENAI_ADMIN_API_KEY": "sk-admin-..."
      }
    }
  }
}

Note the escaped backslashes — .mcp.json is JSON, so Windows paths need \\. Forward slashes also work on Windows if you prefer.

Claude Desktop

Edit the config file directly, then fully quit and reopen the app:

  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

Same mcpServers block as above.

Other MCP clients

Anything that speaks MCP over stdio works — Cursor, Windsurf, Zed, Continue, or a custom client built on the MCP SDK. The config key names vary slightly by app, but all of them need the same three things:

command: node
args:    ["<absolute path>/mcp-openai/dist/index.js"]
env:     { OPENAI_API_KEY: "...", OPENAI_ADMIN_API_KEY: "..." }

Verifying it works

After registering, restart the client and ask it to list your fine-tuning jobs, or check the tool list directly. In Claude Code:

/mcp

You should see openai-platform as connected with 31 tools. If it shows as failed, see Troubleshooting.

Restart the client after every rebuild — the server process is spawned at client startup, so a recompiled dist/ won't be picked up until it relaunches.

Troubleshooting

Symptom Cause Fix
Server shows "failed" / exits immediately OPENAI_API_KEY not set The server exits at startup without it. Check the env block spelling
Cannot find module .../dist/index.js Not built, or wrong path Run npm run build; use an absolute path in the config
Tools missing after a code change Client still running the old process Restart the MCP client
403 Missing scopes: api.usage.read Using a project key for org tools Set OPENAI_ADMIN_API_KEY to an Admin key — see Authentication
429 insufficient_quota on every call Account balance/billing, not code Check platform.openai.com/settings/organization/billing
Windows path errors in JSON Unescaped backslashes Use \\ or forward slashes in .mcp.json

Why a local path instead of npm

Deliberate. Publishing would mean a version bump + republish for every tweak, and npx -y <pkg> re-resolves from the registry on each launch. A direct node dist/index.js path skips all of that, and the project-specific guidance baked into tool descriptions isn't meaningful to anyone else. If this ever needs to run on other machines, publishing is a small step to take then.

Authentication — two keys, two tiers

Env var Used for Where to get it
OPENAI_API_KEY Files, fine-tuning, inference, images, audio, batch Project API key, platform.openai.com/api-keys
OPENAI_ADMIN_API_KEY openai_get_org_costs, openai_get_org_usage* Admin key, platform.openai.com/settings/organization/admin-keys, needs the api.usage.read scope

OPENAI_API_KEY is required — the server exits at startup without it. OPENAI_ADMIN_API_KEY is optional; only the three org tools need it, and they return a clear error explaining what's missing if it isn't set.

These are genuinely different credential types. A project key — even one with full permissions inside its project — gets 403 Missing scopes: api.usage.read on the /organization/* endpoints. That's by design, not a misconfiguration.

Tools (31)

Files

Tool Notes
openai_upload_file Local path + purpose (fine-tune, batch, assistants, …) → file ID
openai_list_files Optional purpose filter
openai_get_file Metadata for one file
openai_download_file_content Pass decode_base64: true for fine-tuning result files
openai_delete_file Irreversible

Models

Tool Notes
openai_list_models filter does a case-insensitive substring match on model IDs
openai_get_model Details for one model

Fine-tuning

Tool Notes
openai_create_finetune_job Costs real money — see Cost
openai_get_finetune_job Status, trained_tokens, fine_tuned_model, result_files
openai_list_finetune_jobs
openai_cancel_finetune_job
openai_pause_finetune_job / openai_resume_finetune_job
openai_list_finetune_events Step-by-step log — the place to look when a job fails
openai_list_finetune_checkpoints Intermediate models, each a usable model ID

Inference

Tool Notes
openai_chat_completion Works with fine-tuned models (ft:...). Supports response_format structured outputs. No streaming — see below
openai_create_embedding
openai_create_moderation input accepts a string or an array of text/image parts

Images

openai_generate_image, openai_edit_image (local file paths + optional mask), openai_create_image_variation (dall-e-2 only, per OpenAI).

Audio

Tool Notes
openai_create_speech Writes the audio to output_path, returns path + byte count
openai_transcribe_audio timestamp_granularities requires response_format: "verbose_json"
openai_translate_audio Translates to English

Batch

openai_create_batch, openai_get_batch, openai_list_batches, openai_cancel_batch. Discounted vs. synchronous calls; results arrive within the completion window (default 24h).

Organization — requires admin key

Tool Notes
openai_get_org_costs Daily aggregate spend
openai_get_org_usage_completions Token usage, optionally grouped by model
openai_get_org_usage Usage for embeddings / images / moderations / audio / vector stores / etc.

Notable behaviours

Things that cost real debugging time and are now encoded in the tool descriptions:

  • No fine-tuning usage endpoint exists. OpenAI provides /organization/usage/{completions,embeddings,images,moderations,audio_*,vector_stores,…} — but nothing for fine-tuning training. Training cost only appears folded into the daily total from openai_get_org_costs, so you infer it from a spike on the training day.

  • Fine-tuning result files may come back base64-encoded. The training-metrics CSV downloaded raw looks like garbage and wc -l reports 0 lines. openai_download_file_content takes decode_base64: true for this.

  • Bare model aliases can reject fine-tuning. gpt-4o-mini returned model_not_available, while the dated snapshot gpt-4o-mini-2024-07-18 was fine. Use openai_list_models with a ft: filter to see which base models already have working fine-tunes on the account.

  • insufficient_quota (429) is an account problem, not a code problem. If openai_list_models works but every inference call 429s, it's billing/balance — not scopes, not rate limits. A single fine-tuning job can exhaust a small balance and take unrelated production traffic down with it.

  • Streaming is intentionally not exposed. An MCP tool result is a single payload, so a streamed body would only be reassembled before returning.

  • TLS note (PHP callers, not this server). Node's fetch uses the system trust store and works fine. The PHP scripts in ../pnr_finetune/ needed an explicit CA bundle because that install has curl.cainfo unset — the fix there was CURLOPT_CAINFO, not disabling verification.

Cost

openai_create_finetune_job spends money. Confirmed against a real bill: fine-tuning gpt-4o-2024-08-06 is $25 per 1M trained tokens — a 1,603,698-token job produced a $40.09 charge against a $40.15 daily total (the remainder being that day's inference).

Check the account's balance/limit before starting a job. Inference tools cost per-token at each model's own rate.

Development

npm run build     # compile once
npm run dev       # tsc --watch

Adding a tool means four edits, all in the obvious places:

  1. A method on OpenAIClient in src/openai-client.ts
  2. A zod schema in src/index.ts
  3. An entry in the TOOLS array
  4. A case in dispatch()

Rebuild and restart the MCP client to pick up changes.

Manual smoke test

node -e "
const {spawn}=require('child_process');
process.env.OPENAI_API_KEY='sk-...';
const p=spawn('node',['dist/index.js'],{env:process.env});
let b=''; p.stdout.on('data',d=>b+=d);
setTimeout(()=>p.stdin.write(JSON.stringify({jsonrpc:'2.0',id:1,method:'initialize',params:{protocolVersion:'2024-11-05',capabilities:{},clientInfo:{name:'t',version:'1'}}})+'\n'),300);
setTimeout(()=>p.stdin.write(JSON.stringify({jsonrpc:'2.0',id:2,method:'tools/list',params:{}})+'\n'),800);
setTimeout(()=>{console.log(b);p.kill();},2000);
"

Security

  • .mcp.json holds keys in plaintext. It matches how the other servers in this project are configured, but treat the file accordingly and keep it out of anywhere it'd be shared.
  • Never paste an API key — especially an Admin key — into a chat or terminal session that gets logged. If that happens, rotate it immediately at the admin-keys page; assume it's compromised regardless of how briefly it was used.
  • openai_delete_file and openai_cancel_* are destructive and take effect immediately.

Related

  • ../pnr_finetune/ — the dataset builder and evaluation scripts this server was extracted from
  • ../docs/openai-fine-tuning-guide.md — full walkthrough of the fine-tuning run, with curl equivalents
  • ../docs/openai-fine-tuning-general-guide.md — task-agnostic fine-tuning playbook

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured