Files
chatgpt-mcp/ARCHITECTURE.md
T

16 KiB

ARCHITECTURE.md

ChatGPT MCP Server Architecture

1. Project Purpose

The ChatGPT MCP Server is a local MCP server that allows Claude Code to ask ChatGPT for focused second-opinion help.

Claude Code remains the primary coding agent.

ChatGPT acts only as:

  • Reviewer
  • Planner
  • Debugging assistant
  • Architecture advisor
  • Risk checker
  • Task decomposition helper

The server must not:

  • Modify files
  • Run shell commands
  • Access Git automatically
  • Deploy anything
  • Send whole repositories by default
  • Send secrets
  • Make autonomous decisions

2. Local AI Workflow

This project uses a hybrid local/cloud assistant model.

Claude Code
  ↓
Local Ollama model: Qwen3.6:35b-a3b
  ↓
Primary coding, editing, testing, and implementation

When Claude Code wants an external second opinion:

Claude Code
  ↓
Local ChatGPT MCP Server
  ↓
OpenAI Responses API
  ↓
ChatGPT review response
  ↓
Claude Code

ChatGPT is advisory only.

Claude Code remains responsible for:

  • Coding
  • File edits
  • Running tests
  • Applying changes
  • Git operations
  • Final decisions

3. Technical Stack

Use a simple JavaScript MVP.

Node.js 22+
JavaScript ESM
MCP SDK
OpenAI SDK
OpenAI Responses API
Zod
Vitest
stdio transport
Local macOS execution
Environment variables

Use JavaScript instead of TypeScript to keep the first version simple and reviewable.

TypeScript can be added later only if the project grows enough to justify it.


4. High-Level Architecture

Claude Code
  |
  | MCP stdio
  v
src/server.js
  |
  v
MCP tool router
  |
  v
Tool handler
  |
  v
Input validation with Zod
  |
  v
Secret redaction
  |
  v
Context size checks
  |
  v
Prompt builder
  |
  v
OpenAI Responses API
  |
  v
Structured advisory response

The MCP server is a bridge and prompt wrapper. It is not an autonomous agent.


5. Repository Structure

chatgpt-mcp/
├── README.md
├── ARCHITECTURE.md
├── TASKS.md
├── PROJECT_STATE.md
├── AGENT_HANDOFF.md
├── package.json
├── .env.example
├── .gitignore
├── src/
│   ├── server.js
│   ├── tools/
│   │   ├── ask-chatgpt.js
│   │   ├── review-plan.js
│   │   ├── review-code.js
│   │   ├── debug-issue.js
│   │   ├── architecture-review.js
│   │   └── schemas.js
│   ├── openai/
│   │   ├── client.js
│   │   └── responses.js
│   ├── prompts/
│   │   ├── base.js
│   │   ├── ask-chatgpt.js
│   │   ├── review-plan.js
│   │   ├── review-code.js
│   │   ├── debug-issue.js
│   │   └── architecture-review.js
│   ├── config/
│   │   ├── env.js
│   │   └── defaults.js
│   └── utils/
│       ├── redact.js
│       ├── context-budget.js
│       ├── errors.js
│       └── logging.js
├── context/
│   ├── project-context.md
│   ├── mcp-context.md
│   ├── openai-context.md
│   ├── claude-context.md
│   ├── security-context.md
│   ├── user-context.md
│   ├── infrastructure-context.md
│   ├── development-context.md
│   ├── repository-context.md
│   ├── current-environment.md
│   └── company-context.md
└── test/
    ├── tools/
    ├── prompts/
    ├── utils/
    └── fixtures/

6. MCP Tools

Start with five focused tools.

6.1 ask_chatgpt

General second-opinion question.

Use for:

  • General advice
  • Alternatives
  • Risks
  • Clarification
  • Breaking down tasks

6.2 review_plan

Reviews a proposed implementation plan before Claude Code acts.

Use for:

  • Missing steps
  • Unsafe assumptions
  • Scope creep
  • Better sequencing
  • Test gaps

6.3 review_code

Reviews focused snippets, patches, or diffs.

Use for:

  • Correctness
  • Bugs
  • Maintainability
  • Security issues
  • Tests
  • Simpler approaches

6.4 debug_issue

Reviews errors, logs, failed tests, or stack traces.

Use for:

  • Likely root causes
  • Debugging steps
  • Minimal experiments
  • What not to change yet

6.5 architecture_review

Reviews architecture decisions and trade-offs.

Use for:

  • Local vs cloud trade-offs
  • Simplicity
  • Maintainability
  • Operational risk
  • Vendor lock-in
  • Future extension paths

7. Tool Input Schema

All tools should share a common shape.

{
  question: string,
  context?: string,
  constraints?: string[],
  expectedOutput?: string,
  projectSummary?: string,
  taskSummary?: string,
  relevantFiles?: [
    {
      path: string,
      content: string,
      language?: string
    }
  ],
  logs?: string
}

Rules:

  • question is required.
  • Context must be focused.
  • Do not send whole repositories.
  • Do not send secrets.
  • Do not send .env files.
  • Do not send unrelated large files.

8. Tool Output Format

Default output should be structured and concise.

Summary:
...

Recommendation:
...

Key Concerns:
1. ...
2. ...

Suggested Next Steps:
1. ...
2. ...

Confidence:
Low | Medium | High

Notes:
...

For code review, include:

Issues by Severity:
...

Suggested Fixes:
...

Test Suggestions:
...

For debugging, include:

Likely Causes:
...

Fast Checks:
...

Minimal Safe Experiments:
...

What Not To Do Yet:
...

9. Context Model

Use layered context.

1. Company/development preferences
2. Project context
3. Claude Code role context
4. Current task context
5. Specific question
6. Relevant snippets/logs

For MVP, do not automatically load every context file.

Recommended MVP behaviour:

  • Use built-in base prompt rules.
  • Accept focused context from Claude Code tool calls.
  • Keep automatic context loading disabled by default.

Later enhancement:

  • Optional loading of selected files from /context.
  • Never load secrets or environment files.

10. Prompt Rules

All prompts must reinforce:

  • Claude Code is the primary coding agent.
  • ChatGPT is advisory only.
  • ChatGPT must not claim to have run commands or tests.
  • ChatGPT must not ask for secrets.
  • ChatGPT must not request the whole repo.
  • ChatGPT should prefer small, reviewable changes.
  • ChatGPT should call out uncertainty.

11. Base Prompt

You are ChatGPT acting as a second-opinion assistant for Claude Code.

Claude Code is the primary coding agent and is currently backed by a local Ollama coding model.

You are not responsible for editing files, running commands, deploying, committing code, or making autonomous decisions.

Your role:
- Review plans
- Review code snippets
- Analyse architecture
- Debug issues
- Identify risks
- Suggest safer implementation approaches
- Break work into smaller steps

Rules:
- Be concise and actionable.
- Use only the context provided.
- Do not assume access to the full repository.
- Do not request secrets.
- Do not recommend sending entire repositories.
- Prefer small reviewable changes.
- Prefer simple architecture.
- Prefer local/self-hosted options where practical.
- Call out uncertainty clearly.
- Avoid over-engineering.
- Do not pretend to have executed code or tests.

12. OpenAI Integration

Use OpenAI as a second-opinion provider only. The integration lives behind the provider abstraction layer:

src/providers/factory.js    — createChatProvider(config) validates and returns configured provider
src/providers/openai.js      — openaiProvider.send(input, config) thin adapter
src/openai/client.js         — createOpenAIClient(config) low-level client
src/openai/responses.js      — sendOpenAIResponse(client, params) API call wrapper

Provider Selection

Configured via CHATGPT_MCP_PROVIDER env var (defaults to "openai"):

CHATGPT_MCP_PROVIDER=openai   # or "manual" for copy-paste workflow

Supported provider values:

Value Description Requires API key?
openai Default — calls ChatGPT via OpenAI API Yes
manual Copy-paste — wraps prompts in a ready-to-copy format No
ollama Local AI — uses Ollama /api/chat endpoint with Qwen3 No

The factory whitelists "openai", "manual", and "ollama". Any unrecognized value throws at provider creation time (not config load time). Null/NaN/falsy values default to "openai" for safe fallback.

OpenAI-specific Environment Variables

OPENAI_API_KEY=                 # required — no default, throws if missing
OPENAI_MODEL=gpt-5.1
OPENAI_TEMPERATURE=0.2
OPENAI_MAX_OUTPUT_TOKENS=2000

Ollama-specific Environment Variables

OLLAMA_BASE_URL=http://localhost:11434   # Ollama API endpoint
OLLAMA_MODEL=qwen3:latest                # default model for chat requests
OLLAMA_TEMPERATURE=0.2                   # sampling temperature
OLLAMA_TIMEOUT=60                         # request timeout in seconds

The provider pattern makes it straightforward to add other providers (Anthropic, custom) — implement the send(request, config) interface and register it in the factory's whitelist. Ollama is already implemented.


13. Configuration

Use .env.example:

OPENAI_API_KEY=
OPENAI_MODEL=gpt-5.1
OPENAI_TEMPERATURE=0.2
OPENAI_MAX_OUTPUT_TOKENS=2000

CHATGPT_MCP_LOG_LEVEL=info
CHATGPT_MCP_ENABLE_FILE_CONTEXT=false
CHATGPT_MCP_CONTEXT_DIR=./context
CHATGPT_MCP_MAX_INPUT_CHARS=30000
CHATGPT_MCP_MAX_FILE_CHARS=12000
CHATGPT_MCP_MAX_FILES=5
CHATGPT_MCP_MAX_LOG_CHARS=10000
CHATGPT_MCP_REDACT_SECRETS=true

Rules:

  • Fail fast if OPENAI_API_KEY is missing and provider is openai.
  • OPENAI_API_KEY is optional for manual and ollama providers.
  • Do not hardcode secrets.
  • Do not read .env content into prompts.
  • Keep context loading disabled by default.

14. Security Rules

The server must never automatically include:

.env
.env.*
*.pem
*.key
id_rsa
id_ed25519
.ssh/*
node_modules/*
dist/*
build/*
coverage/*
.git/*

Redact likely secrets before API calls.

Patterns to redact:

  • API keys
  • Tokens
  • Passwords
  • Bearer tokens
  • Private keys
  • SSH keys
  • PEM blocks
  • Database URLs with credentials
  • Git credentials

Replacement:

[REDACTED]

Logging must not include:

  • Full prompts
  • Source code
  • Secrets
  • Environment variables
  • Full OpenAI responses by default

15. Context Size Management

MVP should use character limits.

Recommended defaults:

Max total input: 30000 chars
Max single file: 12000 chars
Max files: 5
Max logs: 10000 chars

Priority when trimming:

  1. Repeated logs
  2. Long file snippets
  3. General context
  4. Project summary

Never silently drop the main question.

If context is still too large, reject with:

Input is too large for a focused review. Please retry with only the specific files, diff, or error section relevant to the question.

16. Logging

Log safe metadata only:

  • Tool name
  • Timestamp
  • Model
  • Input size
  • Output size
  • Duration
  • Success/failure
  • Error type

Use stderr for MVP.

No database.

No telemetry.

No external logging service.


17. Error Handling

Configuration errors

Example (when using openai provider):

Configuration error: OPENAI_API_KEY is required for the openai provider.

Validation errors

Example:

Validation error: question is required.

Context errors

Example:

Input is too large. Provide a smaller focused snippet.

OpenAI errors

Handle:

  • Authentication failure
  • Rate limits
  • Timeout
  • Model unavailable
  • Network failure

Return safe messages only.

Do not expose stack traces unless debug mode is explicitly enabled.


18. Claude Code MCP Configuration

Production-style local config:

{
  "mcpServers": {
    "chatgpt-mcp": {
      "command": "node",
      "args": ["/absolute/path/to/chatgpt-mcp/src/server.js"],
      "env": {
        "OPENAI_API_KEY": "your-openai-api-key",
        "OPENAI_MODEL": "gpt-5.1"
      }
    }
  }
}

Development config:

{
  "mcpServers": {
    "chatgpt-mcp": {
      "command": "npm",
      "args": ["run", "dev:mcp"],
      "cwd": "/absolute/path/to/chatgpt-mcp",
      "env": {
        "OPENAI_API_KEY": "your-openai-api-key"
      }
    }
  }
}

The server runs locally on macOS using stdio.

It does not need to be deployed for the MVP.


19. Development Workflow

Use the normal Gitea workflow.

Feature branch
→ Commit
→ Pull request
→ Merge

Branch examples:

feature/TASK-001
fix/TASK-002
docs/TASK-003

Commit examples:

feat: add ask_chatgpt tool
fix: redact bearer tokens
docs: update MCP setup instructions
test: add prompt builder tests
chore: initialise project

Rules:

  • One task per change.
  • Keep changes small.
  • Update docs when behaviour changes.
  • Do not add hidden behaviour.
  • Do not add automatic repository scanning in MVP.
  • Do not add deployment automation until the local MVP works.

20. Testing Strategy

Use Vitest.

Test areas:

  • Config loading
  • Secret redaction
  • Context budget checks
  • Prompt construction
  • Tool schema validation
  • OpenAI wrapper with mocked responses
  • Error formatting

Manual smoke tests:

  1. Start MCP server locally.
  2. Confirm Claude Code can discover tools.
  3. Call ask_chatgpt.
  4. Call review_plan.
  5. Call review_code.
  6. Call debug_issue.
  7. Confirm no files were modified by the MCP server.
  8. Confirm fake secrets are redacted.

21. MVP Scope

Smallest useful MVP:

Node.js JavaScript project
MCP stdio server
OpenAI Responses API wrapper
Config loader
Secret redaction
Context size checks
ask_chatgpt tool
README setup instructions

Do not build all advanced features first.

After the MVP works, add the other tools one at a time.


  1. Create repository skeleton.
  2. Add package.json.
  3. Add .env.example.
  4. Add config loader.
  5. Add redaction utility.
  6. Add context budget utility.
  7. Add OpenAI client wrapper.
  8. Add base prompt.
  9. Add ask_chatgpt.
  10. Add MCP stdio server.
  11. Test with Claude Code.
  12. Add review_plan.
  13. Add review_code.
  14. Add debug_issue.
  15. Add architecture_review.
  16. Add README examples.
  17. Add tests.
  18. Update PROJECT_STATE.md.

23. Future Roadmap

The following items remain from the original planning scope:

Near term (post-v1)

  • Add context file opt-in loading from /context directory
  • Add structured response formatting enhancements

Medium term

  • Add Anthropic provider adapter (abstraction layer ready; implement send(request, config) interface)
  • Add model-per-tool configuration
  • Add timeout/retry tuning per provider

Later

  • Add Dockerfile
  • Add CI/CD pipeline (Jenkins validation, Gitea PR workflow)
  • Add safe project summary generation
  • Add optional OpenHands integration
  • Add streaming responses support
  • Add cost tracking per tool call

24. Key Risks

Risk: Secret leakage

Mitigation:

  • Explicit context only.
  • Redaction.
  • No automatic .env loading.
  • Safe logging.

Risk: Too much context

Mitigation:

  • Character limits.
  • File count limits.
  • Focused tool inputs.
  • Reject oversized requests.

Risk: ChatGPT overrules Claude Code

Mitigation:

  • Prompt says advisory only.
  • Claude Code remains executor.
  • Responses include assumptions and confidence.

Risk: Over-engineering

Mitigation:

  • JavaScript MVP.
  • One tool first.
  • No automatic repo scanning.
  • No deployment work until local MVP works.

Risk: Conflicting advice between Qwen and ChatGPT

Mitigation:

  • Treat ChatGPT as second opinion only.
  • Use it for risk checks and alternatives.
  • Claude Code decides what to implement.

25. Decision Summary

Use JavaScript, not TypeScript, for the MVP.

Use Claude Code with local Ollama/Qwen as the main coding assistant.

Use ChatGPT through MCP only as a focused external reviewer.

Keep the system local-first, simple, explicit, and non-mutating.