Skip to main content
Glama

simple-gpt-mcp

A small, independent stdio MCP server for OpenAI conversations with persistent sessions and explicit request recovery.

Version 0.1.0 implements the core chat/session release. Web search, attachments, and hosted Python remain future milestones in SPEC.md.

Setup

Requires Node.js 22.16.0 or newer and pnpm (version pinned through packageManager in package.json). Development is pinned to 22.23.2 in .node-version; installation refuses an older Node. CI is configured for Node 22 and 24 on Linux and macOS. Node 22 may print an experimental SQLite warning to stderr; MCP stdout remains intact.

git clone https://github.com/joon-aca/simple-gpt-mcp.git
cd simple-gpt-mcp
make mcp-config

make mcp-config installs dependencies when the lockfile changes, builds dist/, and prints this checkout's host configuration: JSON for hosts such as Claude Desktop and a claude mcp add command for Claude Code. Both use absolute paths to the Node binary and entry point, so hosts without your shell PATH still work. Replace the key and model placeholders when pasting; the command never writes credentials anywhere.

The server does not auto-load .env; .env.example lists environment options. An API key is required at startup. A model can instead be supplied in each new chat call; no default model is silently selected.

Tests exercise the official current MCP client and a separate 2025-11-25 legacy client. A specific desktop host has not been tested interactively.

Related MCP server: OpenAI Assistant MCP Server

Tools

chat

Start a session:

{
  "message": "Explain this design tradeoff in plain English.",
  "instructions": "Be concise and state important assumptions.",
  "max_output_tokens": 2048
}

Continue using its returned ID:

{
  "session_id": "returned-session-uuid",
  "message": "What would you implement first?"
}

Replace UUID placeholders with returned IDs. Results include request/session/response IDs, actual model, status, text, effective non-secret settings, and raw token usage. There is no guessed dollar cost. Tools return structured content and a JSON text representation.

Optional settings: model, instructions, reasoning_effort, verbosity, max_output_tokens, timeout_ms. Continuation overrides apply to that call only. Empty instructions clears instructions for the call. Stable instructions are resent on every request. OpenAI validates model-specific option compatibility; rejected settings become structured failures rather than automatic downgrades. Failures carry OpenAI's upstream_code, upstream_param, and upstream_request_id when available, for example unsupported_parameter on reasoning.effort. OpenAI's free-text error message is never returned because it can echo request content.

Supply a UUID request_id to safely repeat the exact same call after losing its result. Identical arguments return the existing request/result without another model call; different arguments with the same ID are rejected. Generate the ID once before calling and preserve it across retries. Replay protection ends when the session is deleted.

Completed responses and refusals advance the predecessor pointer. Failed/incomplete responses do not. Only completed chat results have isError: false; refusals, incomplete results, failures, and replays of running or abandoned requests have explicit statuses and isError: true. Unresolved requests block new work on their session.

sessions

{ "operation": "list", "limit": 20 }

Metadata is listed in UUID order; pass next_cursor as after to continue. Fresh state returns an empty list.

{ "operation": "get", "session_id": "returned-session-uuid" }

get shows defaults, timestamps, latest response ID, and active request ID. Instruction text and model responses are excluded from metadata.

{
  "operation": "configure",
  "session_id": "returned-session-uuid",
  "instructions": "Use concise technical explanations.",
  "max_output_tokens": 4096
}

configure changes persistent defaults. delete with session_id removes local session/request/results. Both reject active or unresolved work. Local deletion does not delete data stored by OpenAI.

request_status

{ "request_id": "returned-request-uuid", "action": "inspect" }

For recovery_required, retrieve the locally recorded upstream response:

{ "request_id": "returned-request-uuid", "action": "recover" }

Recovery retrieves; it never generates again. An in-progress response remains recoverable, and so does a request whose retrieval failed transiently (rate limit, authentication, server error); retry recover later. Only a recorded response that OpenAI no longer has (404) fails recovery for good. If no response ID was received, status is unknown_outcome: inspect upstream records before deciding to make a new request.

Explicitly unblock an unresolved session while retaining its previous successful context:

{ "request_id": "returned-request-uuid", "action": "abandon" }

Abandonment does not cancel upstream work or prevent billing. Live requests cannot be abandoned; cancel the active call or wait first. After a hard crash, the claim expires at the original deadline plus a 30-second safety window. Stale workers cannot commit over recovered or abandoned work.

Limits and data handling

Policy

Default

Total deadline

120 seconds; per-call override 1–600 seconds

Output tokens

8192; per-call maximum 32768

Combined prompt/instructions

256 KiB

Normalized result envelope

256 KiB; text/refusal limited to half to reserve metadata space

Single stream event or JSON body

8 × result-byte limit

Concurrent requests per database

4

Sessions / request records

1000 / 10000

Content budget

64 MiB, plus bounded metadata and small failure records

Idle session expiry

30 days without activity, unless a request is unresolved

Terminal result retention

30 days

See .env.example for configurable policies. Set the MCP host's tool timeout above the server deadline to receive the server's timeout result. Otherwise preserve a client-generated request ID and inspect/recover after reconnecting.

State locations: ~/Library/Application Support/simple-gpt-mcp on macOS; $XDG_DATA_HOME/simple-gpt-mcp or ~/.local/share/simple-gpt-mcp on Linux; %LOCALAPPDATA%/simple-gpt-mcp on Windows. Override with an absolute SIMPLE_GPT_MCP_DATA_DIR. CI targets Linux/macOS; Windows is unverified.

SQLite stores persistent session instructions, normalized assistant results, token usage, IDs, settings, and a SHA-256 digest of caller arguments for replay detection. User messages, per-call instruction overrides, keys, and raw payloads are not stored as transcript content. Treat digests as sensitive metadata too. The database is unencrypted; private POSIX permissions apply where supported. Use a dedicated local directory rather than a shared/network filesystem.

Retention runs at startup and on tool use. A session idle for the retention period is deleted with its request history, including replay tombstones, so one-shot questions never exhaust the session or request limits. A session with an unresolved request stays until that request is recovered or abandoned. In sessions still in use, terminal result content older than the retention period is pruned while ID/settings/usage tombstones remain; a pruned replay returns result_pruned without generating again. SQLite can retain allocated disk space after pruning; the content budget does not promise a fixed physical database size.

Requests explicitly enable upstream storage for chaining/recovery. Local metadata cannot make remote history persist indefinitely. Missing/expired history requires an explicit new session; context is never silently reset or truncated. OpenAI instruction-continuity guidance.

Logs contain metadata only on stderr. An INTERNAL_ERROR result has a matching internal_error event with the error class and stable codes (for example ERR_SQLITE_ERROR / database is locked), never the error message. Content logging is not implemented; SDK logging is forced off even if OPENAI_LOG is set. There are no tools for local file access, local code execution, or downstream MCP connections. Optional OPENAI_BASE_URL is trusted startup configuration: credentials go to that URL, so use only a trusted service. HTTPS is required except for loopback test endpoints.

Development and verification

make check

check is exactly what CI runs: source/test type checks, lint, a non-mutating format check, build, and tests with coverage gates. Bare make lists the other targets (test, dev, format, audit, clean). Tests use temporary SQLite and a loopback fake OpenAI HTTP server with synthetic credentials. They exercise the actual SDK and stdio processes, restart continuity, two-process exclusion, current/legacy MCP, recovery (including transient retrieval failures), deadlines/cancellation, realistic token-by-token streams, pruning and session expiry, limits, and privacy/error handling.

Coverage gates cover source modules. The entry point is excluded from in-process coverage because protocol tests exercise it as an actual child process.

No live model call is part of testing. A real-account/model smoke test remains a manual, explicitly authorized step. CI includes dependency auditing. The package is not published to npm.

See SPEC.md for decisions, acceptance gates, and future milestones.

License

MIT

Available Tools

3 tools
chatB

Ask an OpenAI model or continue a persistent session. Explicit per-call overrides; no local code or file access. Save request_id for interruption recovery.

NameRequiredDescriptionDefault
modelNo
messageYes
verbosityNo
request_idNo
session_idNo
timeout_msNo
instructionsNo
reasoning_effortNo
max_output_tokensNo

Output Schema

NameRequiredDescription
statusYes

TDQS

B3.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover safety (readOnlyHint=false, openWorldHint=true, destructiveHint=false), and the description adds real context: no local code or file access, per-call overrides rather than stored config, and that request_id enables recovery from interruption. It does not explain error/timeout behavior despite exposing a timeout_ms parameter.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short clauses, front-loaded with the action and continuation mode, then constraints. Dense and wasteful-free, though arguably over-compressed given the undocumented 9-parameter surface.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, and the safety profile is annotated. But with 9 undescribed parameters and sibling tools that overlap in purpose, the description leaves notable gaps about parameter roles and interruption/retry semantics.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 9 parameters, so the description must carry the load and largely doesn't. It only gestures at session_id, request_id, and the override family; it never explains message vs instructions, verbosity, reasoning_effort, max_output_tokens, or timeout_ms semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Ask an OpenAI model') plus the session-continuation mode, which distinguishes it from sessions and request_status. It does not explicitly name those siblings or state the boundary between chatting and managing sessions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Continue a persistent session' and 'save request_id for interruption recovery' imply when session_id/request_id matter, but there is no explicit when-to-use guidance versus the sibling tools (e.g. use request_status instead to poll, sessions to manage sessions).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

request_statusA
Destructive

Inspect a known local request, recover its recorded OpenAI response without generating a new one, or explicitly abandon an unresolved request. Abandoning does not cancel upstream work or prevent billing.

NameRequiredDescriptionDefault
actionNoinspect
request_idYes

Output Schema

NameRequiredDescription
statusYes

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true and openWorldHint=true, but the description earns credit for explaining what destruction actually means here: abandoning does not cancel upstream work or prevent billing. The clarification that recover returns a recorded response 'without generating a new one' also prevents a costly misread of the tool's effect.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler. The three modes are enumerated up front and the billing caveat is placed immediately after the abandon clause where it matters most.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return shapes need not be described, and annotations cover the safety profile. What remains thin is failure behavior, e.g. what inspect returns for an unresolved request or what recover does when no response was recorded. Otherwise the description is sufficient to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the load. It does define the semantics of each action value well, but never mentions request_id directly, its UUID format, where such an id comes from, or that action defaults to inspect. That leaves the required parameter's meaning to be inferred from 'a known local request'.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names three concrete operations on a specific resource (a known local request): inspect, recover a recorded response, and abandon. This maps cleanly onto the action enum, so an agent knows exactly what the tool does. It stops short of differentiating itself from the chat and sessions siblings by name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Each mode carries its own trigger condition: 'inspect a known local request', 'recover its recorded OpenAI response without generating a new one', 'explicitly abandon an unresolved request'. That is clear when-to-use guidance for all three paths. It does not say when to prefer this over the chat or sessions siblings, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sessionsA
Destructive

List/get local session metadata, configure defaults, or DELETE local session data. Never deletes upstream OpenAI data. Instructions and response contents are excluded from metadata.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
statusYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds two pieces of real behavioral context beyond the annotations: deletion is scoped to local storage and never touches upstream OpenAI data, and instructions/response contents are stripped from returned metadata. The destructiveHint=true annotation is consistent with the capitalized DELETE, though the description could say whether deletion is reversible or what a get returns for a missing id.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the operation list, and every clause carries information (the upstream-data caveat and the metadata exclusion rule are both load-bearing). The only minor waste is the capitalized DELETE, which reads as emphasis rather than content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a four-operation tool with annotations and an output schema, the description covers the operation set, the scope of destruction, and the shape of returned metadata. Remaining gaps (pagination via after/limit, per-operation prerequisites) are secondary given the oneOf schema already constrains invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so session_id, after, limit, and the configure fields are already documented structurally; the description adds nothing per-parameter. Baseline 3 applies, since 'configure defaults' only loosely hints at what model/verbosity/reasoning_effort/timeout_ms are for.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names each operation explicitly (list/get metadata, configure defaults, delete) against a specific resource, which is exactly what an agent needs for a single multiplexed tool. 'Local session data' vs 'upstream OpenAI data' also distinguishes it from the chat and request_status siblings, which act on conversation content rather than session records.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Operation names imply which variant to pick, and the schema's oneOf makes the required fields per operation unambiguous. However, there is no explicit guidance on when to list vs get vs configure, nor any statement of prerequisites (e.g., must a session exist before configuring it), and no exclusion rules beyond the upstream-data caveat.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.1.0
    • First observedchat
    • First observedrequest_status
    • First observedsessions

TDQS

A3.7/5.0

Scored across 3 tools

Disambiguation4/5

Each tool targets a distinct layer: chat generates model responses, sessions manages session-level metadata/config, and request_status handles individual request recovery. The main risk is mild confusion between chat and request_status around retrieving responses, but the descriptions explicitly contrast generating vs. recovering without generating.

Naming Consistency3/5

Names mix conventions: 'chat' is a bare verb, 'sessions' a plural noun, and 'request_status' a snake_case noun phrase. Each name is readable and meaningful in isolation, but there is no predictable pattern across the set.

Tool Count4/5

Three tools is a compact but reasonable surface for this scope, and each tool earns its place. However, each tool bundles multiple operations (sessions does list/get/configure/delete; request_status does inspect/recover/abandon), which slightly overloads the small set.

Completeness4/5

The surface covers response generation, session lifecycle management, and request interruption recovery, which are the core workflows. Minor gaps exist around model discovery and retrieving session response contents, but the stated exclusions and recovery paths make these workable.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    Enables Claude and other MCP-compatible tools to communicate with OpenAI's GPT models (GPT-5, GPT-5-mini, o3) with conversation history and session management. Features advanced controls like reasoning effort settings, token tracking, and parallel conversation sessions for efficient AI workflows.
    13 npm
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    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.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables durable bidirectional handoffs between any MCP client and OpenAI Codex Desktop tasks, with persistent callbacks, acknowledgements, and session-scoped state across restarts.
    1
    Apache 2.0