Files
chatgpt-mcp/AGENT_HANDOFF.md
T

12 KiB

AGENT_HANDOFF.md

Completed

Phase 0 — Repository Setup

  • Repository skeleton (TASK 0.1)
  • package.json with dependencies (TASK 0.2)

Phase 1 — Core Utilities

  • Configuration loader (src/config/env.js) — TASK 1.1
  • Secret redaction utility (src/utils/redact.js) — TASK 1.2
  • Context budget utility (src/utils/context-budget.js) — TASK 1.3
  • Safe logging helper (src/utils/logging.js) — TASK 1.4

Phase 2 — OpenAI Integration

  • OpenAI client wrapper (src/openai/client.js) — TASK 2.1
  • Response builder (src/openai/responses.js) — TASK 2.2
  • Error handling and edge cases (tests) — TASK 2.3

Phase 3 — Tool Inputs and Prompts

  • Zod input validation schemas (src/tools/schemas.js, tests) — TASK 3.1
  • Base prompt template (src/prompts/base.js, tests) — TASK 3.2
  • ask_chatgpt prompt builder (src/prompts/ask-chatgpt.js, tests) — TASK 3.3
  • review_plan prompt builder (src/prompts/review-plan.js, tests) — TASK 3.4
  • review_code prompt builder (src/prompts/review-code.js, tests) — TASK 3.5
  • debug_issue prompt builder (src/prompts/debug-issue.js, tests) — TASK 3.6
  • architecture_review prompt builder (src/prompts/architecture-review.js, tests) — TASK 3.7

Next Phase

Phase 4 - Tool Handlers

Build the MCP tool handlers that:

  1. Register each tool with the MCP server.
  2. Validate input using schemas.js.
  3. Call the appropriate prompt builder.
  4. Send the prompt to OpenAI via responses.js.
  5. Return structured advisory output to Claude Code.

Completed (Phase 4)

All five MCP tool handlers are complete:

Handler File Tests
handleAskChatGpt src/tools/ask-chatgpt.js 27
handleReviewPlan src/tools/review-plan.js 28
handleReviewCode src/tools/review-code.js 28
handleDebugIssue src/tools/debug-issue.js 28
handleArchitectureReview src/tools/architecture-review.js 28

Total: 139 orchestration-only tests, all passing.

Completed (Phase 5)

All five MCP tools registered: ask_chatgpt, review_plan, review_code, debug_issue, architecture_review.

Completed (Phase 6) — Provider Abstraction

Decoupled tool handlers from OpenAI implementation via a provider abstraction layer:

src/providers/factory.js

  • createChatProvider(config) validates chatgptMcpProvider against whitelist
  • Defaults to "openai" for any falsy/unknown value (null, NaN, numeric)
  • Throws with descriptive message on unrecognized provider names

src/providers/openai.js

  • openaiProvider.send(input, config) — thin adapter wrapping OpenAI modules
  • Internally calls createOpenAIClient(config) then sendOpenAIResponse(client, params)
  • Params include: input as system messages array, model, temperature, maxOutputTokens from config

Handler changes (all 5)

  • Old interface: { loadConfig, createOpenAIClient, sendOpenAIResponse }
  • New interface: { loadConfig, createProvider }
  • Each handler calls provider = deps.createProvider(config) then provider.send(budget.input, config)
  • Handler logic unchanged — only dependency injection changed

CHATGPT_MCP_PROVIDER env var

  • Defaults to "openai" when not set
  • Accepts any string at loadConfig time; validation happens in factory at provider creation
  • Currently only "openai" is whitelisted; others throw at createChatProvider() time

Completed (Phase 7) — Tests

Handler tests updated (5 files, all using { loadConfig, createProvider } mock pattern)

File Tests Status
test/tools/ask-chatgpt.test.js 27
test/tools/review-plan.test.js 28
test/tools/review-code.test.js 27
test/tools/debug-issue.test.js 28
test/tools/architecture-review.test.js 27

New provider/config tests (3 files)

File Tests Status
test/providers/factory.test.js ~30 covers default, whitelist, edge cases
test/providers/openai.test.js 27 covers all send delegation paths
test/config/env.test.js +4 (added section) covers chatgptMcpProvider env var

Final verification

  • All 579 tests pass across 20 test files (up from ~523)
  • npm start → tools/list shows same 5 tools, unchanged schemas
  • Zero regression in existing test coverage

Completed (Phase 8) — Manual Export Provider

src/providers/manual-export.js

  • manualExportProvider.send(request, config) — zero-API-cost provider
  • Wraps pre-built prompt in copy/paste-ready format for ChatGPT Web (https://chatgpt.com)
  • Detects tool name from input fields: debug_issue, review_code, architecture_review, review_plan, ask_chatgpt
  • Adds box-delimited display with prefixes, corner delimiters (┌ ┐ └ ┘)
  • Includes instructions section (5 numbered steps), metadata section (tool, provider, length)
  • Warns on prompts over 30k characters
  • Handles empty/missing prompt gracefully with advisory message
  • Preserves unicode, markdown code blocks, JSON, special HTML characters exactly

Factory integration

  • "manual" added to SUPPORTED_PROVIDERS whitelist in src/providers/factory.js
  • CHATGPT_MCP_PROVIDER=manual switches all tool handlers to manual export mode
  • Defaults to "openai" when not set — OpenAI behaviour unchanged
  • Same provider interface: { send(request, config) => Promise<{ content: string }> }

Tests added (Phase 8)

File Tests Coverage
test/providers/manual-export.test.js 56 structure, tool detection, unicode, long prompts, edge cases, repeatability, visual layout
test/providers/factory.test.js +9 manual provider tests factory integration with "manual"

Final verification

  • All 644 tests pass across 21 test files, zero regressions
  • npm start → tools/list shows same 5 tools, unchanged schemas
  • No chat.openai.com references in codebase — only chatgpt.com
  • MCP initialize handshake succeeds with chatgpt-mcp v0.1.0

Completed (Phase 9) — Ollama Provider

src/providers/ollama.js

  • ollamaProvider.send(reviewRequest, config) — local AI provider using Ollama /api/chat endpoint
  • Uses native fetch() for HTTP calls — zero new dependencies
  • Implements same provider interface as openai and manual: { send(request, config) => Promise<{ content: string }> }

Provider details

  • Request format: OpenAI-compatible chat API (model, messages, stream, options)
  • Response parsing: Extracts data.message.content from Ollama response
  • Error categories: OllamaTimeoutError, OllamaModelNotFoundError (404), OllamaValidationError (422), OllamaApiNotAvailableError (501), OllamaRequestError (fallback)
  • Base URL normalization: Strips trailing slashes for safe path concatenation

Environment variables

Variable Default Description
OLLAMA_BASE_URL http://localhost:11434 Ollama API endpoint
OLLAMA_MODEL qwen3:latest Model name for chat requests
OLLAMA_TEMPERATURE 0.2 Sampling temperature
OLLAMA_TIMEOUT 60 Request timeout in seconds

Factory integration

  • "ollama" added to SUPPORTED_PROVIDERS whitelist in src/providers/factory.js: Set(["openai", "manual", "ollama"])
  • CHATGPT_MCP_PROVIDER=ollama switches all tool handlers to local Ollama mode
  • Defaults to "openai" when not set — OpenAI behaviour unchanged
  • Same provider interface as openai and manual providers

Current provider status

Provider Env Value Type Requires API key?
openai CHATGPT_MCP_PROVIDER=openai Cloud (OpenAI Responses API) Yes (OPENAI_API_KEY)
manual CHATGPT_MCP_PROVIDER=manual Local (copy-paste) No
ollama CHATGPT_MCP_PROVIDER=ollama Local (Ollama /api/chat) No

Completed (Phase 5)

All five MCP tools registered: ask_chatgpt, review_plan, review_code, debug_issue, architecture_review.

Task 5.1 - MCP server skeleton

Minimal MCP stdio server in src/server.js. MCP initialize handshake succeeds. No tools registered yet.

Task 5.2 - Register ask_chatgpt MCP tool

ask_chatgpt is now registered as an MCP tool on the server (src/server.js).

Registration details:

  • Uses shared baseInputSchema (question required + context, constraints, expectedOutput, projectSummary, taskSummary, relevantFiles, logs optional).
  • External deps injected via dependency injection: { loadConfig, createProvider } — provider abstraction (Phase 6).
  • Returns structured MCP tool result: { content: [{ type: "text", text }], isError, warnings }.

Smoke test results (all passing):

  • initialize → server returns chatgpt-mcp v0.1.0
  • tools/list → exposes ask_chatgpt with correct schema
  • tools/call (happy path, mocked OpenAI) → { content: [...], isError: false } with answer
  • tools/call (minimal input { question: "hi" }) → works
  • tools/call (full input, all 10 schema fields) → handled correctly
  • tools/call (missing OPENAI_API_KEY) → structured MCP error "Error: Configuration error: OPENAI_API_KEY is missing."
  • tools/call (invalid API key) → structured MCP error "OpenAI API error (OpenAIAuthError): 401"
  • All 523 unit tests pass across 18 test files

Production code (src/server.js): ~39 lines, single ask_chatgpt tool registered with MCP via Stdio transport.

Task 5.3 - Register remaining MCP tools

Four additional MCP tools registered on the server (src/server.js):

Tool Handler
review_plan handleReviewPlan
review_code handleReviewCode
debug_issue handleDebugIssue
architecture_review handleArchitectureReview

All five MCP tools now registered: ask_chatgpt, review_plan, review_code, debug_issue, architecture_review.

Smoke test results (all passing):

  • initialize → server returns chatgpt-mcp v0.1.0
  • tools/list → 5 tools total
  • tools/call reaches handlers for all 5 tools
  • missing OPENAI_API_KEY → structured tool errors: "Error: Configuration error: OPENAI_API_KEY is missing."
  • npm test → 523 tests pass across 18 test files, no regressions

Implementation notes:

  • Each tool registered explicitly with its own registerTool() call — no registry abstraction.
  • All handlers use existing modules only (no new imports or files).
  • SDK quirk: isError: true wraps results in JSON-RPC error envelope (code: -32603).

Task 5.4 - Normalize MCP tool error formatting

MCP tool error formatting normalized in src/server.js. All 5 tool registrations now produce a single "Error:" prefix — no more duplicate "Error: Error:" strings.

Changes: Each tool callback normalizes the error text before returning:

  • If result.error already starts with "Error:", it is used as-is.
  • Otherwise, "Error: " is prepended.
  • result.ok responses are unchanged.

Smoke tests: npm test 523 passed · tools/list 5 tools · ask_chatgpt single prefix · review_plan single prefix

Task 5.5 - Claude Code MCP configuration and local end-to-end setup

Project-local Claude Code discovery configured:

  • .claude/ added to .gitignore — no machine-specific paths in repo
  • README.md updated with Setup, MCP Tools, and Running sections
  • MCP config uses "command": "npm", "args": ["start"] — platform-independent
  • All 5 tools documented: ask_chatgpt, review_plan, review_code, debug_issue, architecture_review

Next Pending

No pending tasks. MVP complete. Future work: Anthropic provider, streaming responses, cost tracking, Dockerfile, CI pipeline, safe project summary generation.

General Rules

  • Read ARCHITECTURE.md before making changes.
  • Work incrementally.
  • Keep changes small.
  • Do not implement multiple phases at once.
  • Do not add features not described in ARCHITECTURE.md.
  • Update documentation when appropriate.
  • Claude Code is the implementation agent.
  • ChatGPT MCP is advisory only.