diff --git a/BRANCH_STATUS.md b/BRANCH_STATUS.md deleted file mode 100644 index 63f99223..00000000 --- a/BRANCH_STATUS.md +++ /dev/null @@ -1,102 +0,0 @@ -# Branch Status Summary: copilot/create-serena-mcp-server-image - -## Current Status - -This branch has successfully created the foundational infrastructure for a Serena MCP server container image that supports Python, Java, JavaScript, and Go. - -## What Has Been Completed - -### 1. Serena Container Implementation ✅ -- **Dockerfile** (`containers/serena-mcp-server/Dockerfile`) - - Multi-language runtime support: - - Python 3.11 (base image) - - Java (OpenJDK 21 via default-jdk) - - Node.js + npm (for JavaScript/TypeScript) - - Go (golang-go package) - - Attempts to install Serena from PyPI/GitHub - - Pre-installs common language servers (typescript-language-server, gopls, python-lsp-server) - - Configured with proper environment variables and entry points - -### 2. GitHub Actions Workflow ✅ -- **Container Build Workflow** (`.github/workflows/serena-container.yml`) - - Multi-architecture support (linux/amd64, linux/arm64) - - Automatic builds on main branch pushes - - Manual workflow dispatch for versioning - - Pushes to GitHub Container Registry (GHCR) - - Uses Docker Buildx for efficient multi-platform builds - -### 3. Configuration Integration ✅ -- **config.toml**: Added Serena server entry with workspace mounting -- **config.json**: Added Serena server configuration example -- **agent-configs/codex.config.toml**: Added Serena MCP server endpoint - -### 4. Documentation ✅ -- **README.md**: Comprehensive usage guide for the Serena container - - Language-specific notes for Python, Java, JavaScript/TypeScript, Go - - Configuration examples - - Troubleshooting tips -- **test.sh**: Automated test script for validating language support -- **BUILD_NOTES.md**: Documents build issues and solutions - -## What Still Needs to Be Done - -### 1. Container Build Verification ⚠️ -**Status**: Dockerfile created but not successfully built locally due to SSL/TLS certificate issues in the test environment. - -**Issue**: The local build environment has SSL certificate verification problems that prevent: -- Installing Serena from GitHub/PyPI -- Installing npm packages globally -- Running go install commands - -**Solution**: The container should build successfully in GitHub Actions CI/CD environment where network access is properly configured. - -### 2. End-to-End Testing 🔲 -Once the container builds successfully in CI/CD: -- Test Python language server functionality -- Test Java language server functionality -- Test JavaScript/TypeScript language server functionality -- Test Go language server functionality -- Verify MCP protocol compliance -- Test with actual MCP clients (Claude Desktop, etc.) - -### 3. Production Readiness 🔲 -- Version tagging strategy -- Container image optimization (size reduction) -- Security scanning -- Performance benchmarking -- User documentation updates - -## Next Steps - -1. **Merge to Main** - This will trigger the GitHub Actions workflow to build the container in a proper CI/CD environment -2. **Verify Build** - Check that the workflow successfully builds and pushes to GHCR -3. **Test Container** - Pull the built image and run integration tests -4. **Iterate** - Fix any issues discovered during testing -5. **Document** - Update main README with Serena container usage - -## Technical Details - -### Container Registry -- **Image Name**: `ghcr.io/githubnext/serena-mcp-server` -- **Tags**: `latest` (from main branch), `` (from commits), `` (manual dispatch) - -### Dependencies Installed -- **System packages**: build-essential, git, curl, wget, default-jdk, nodejs, npm, golang-go, ca-certificates -- **Python packages**: Serena, python-lsp-server, pylsp-mypy, pyright (via Serena) -- **Node packages**: typescript, typescript-language-server, @vscode/java-language-server -- **Go tools**: gopls (Go language server) - -### Configuration -- **Workspace mount**: `/workspace` (should be mapped to user's codebase) -- **Cache directory**: `/tmp/serena-cache` -- **Entry point**: `serena-mcp-server` command -- **Transport**: stdio (standard MCP protocol) - -## Summary - -**The branch is ready for merge and automated build.** All infrastructure code, documentation, and configuration are complete. The only remaining work is to: -1. Let GitHub Actions build the container (which should succeed) -2. Test the built container -3. Make any necessary refinements based on testing - -The local build issues are environment-specific and will not affect the CI/CD build process. diff --git a/HTTP_MCP_SERVERS.md b/HTTP_MCP_SERVERS.md deleted file mode 100644 index 21e12bbc..00000000 --- a/HTTP_MCP_SERVERS.md +++ /dev/null @@ -1,168 +0,0 @@ -# HTTP MCP Server Support - -The MCP Gateway now supports routing requests to HTTP-based MCP servers that are already running. This is useful for integrating with externally managed MCP services. - -## Configuration - -To configure an HTTP MCP server, use the following format in your configuration: - -```json -{ - "mcpServers": { - "safeinputs": { - "type": "http", - "url": "http://host.docker.internal:3000/", - "headers": { - "Authorization": "your-auth-secret" - } - } - }, - "gateway": { - "port": 3001, - "domain": "localhost", - "apiKey": "gateway-api-key" - } -} -``` - -### Configuration Fields - -- `type`: Must be `"http"` for HTTP-based MCP servers -- `url`: The HTTP endpoint URL for the MCP server (required) -- `headers`: Optional HTTP headers to include in requests (commonly used for authentication) - -### Environment Variable Expansion - -You can use environment variable expansion in header values: - -```json -{ - "mcpServers": { - "safeinputs": { - "type": "http", - "url": "http://host.docker.internal:3000/", - "headers": { - "Authorization": "${SAFEINPUTS_AUTH_TOKEN}" - } - } - } -} -``` - -Set the environment variable before starting the gateway: - -```bash -export SAFEINPUTS_AUTH_TOKEN="your-secret-token" -cat config.json | ./awmg --config-stdin --routed -``` - -## Routing - -In routed mode, HTTP MCP servers are accessible at: - -``` -http://gateway-host:gateway-port/mcp/ -``` - -For example, with the configuration above: -- Gateway running on `localhost:3001` -- HTTP server configured as `safeinputs` -- Access via: `http://localhost:3001/mcp/safeinputs` - -## How It Works - -1. When the gateway receives a configuration for an HTTP MCP server: - - It stores the URL and headers - - It creates an HTTP connection (no process launch required) - -2. When a client sends a request to `/mcp/safeinputs`: - - The gateway validates the client's authorization - - It forwards the JSON-RPC request to the HTTP backend - - It includes the configured headers (e.g., Authorization) - - It returns the response from the HTTP backend to the client - -3. The HTTP backend never sees the gateway's API key - only its own configured headers. - -## Example: Safeinputs Service - -If you have a safeinputs MCP server already running at `http://host.docker.internal:3000/`: - -1. Create a config file: - -```json -{ - "mcpServers": { - "safeinputs": { - "type": "http", - "url": "http://host.docker.internal:3000/", - "headers": { - "Authorization": "safeinputs-secret-key" - } - } - }, - "gateway": { - "port": 3001, - "domain": "localhost", - "apiKey": "gateway-api-key" - } -} -``` - -2. Start the gateway: - -```bash -cat config.json | ./awmg --config-stdin --routed -``` - -3. Send requests to the gateway: - -```bash -curl -X POST http://localhost:3001/mcp/safeinputs \ - -H "Authorization: gateway-api-key" \ - -H "Content-Type: application/json" \ - -d '{ - "jsonrpc": "2.0", - "id": 1, - "method": "tools/list" - }' -``` - -The gateway will: -- Validate your `gateway-api-key` -- Forward the request to `http://host.docker.internal:3000/` -- Include `Authorization: safeinputs-secret-key` header -- Return the tools list from the safeinputs backend - -## Mixed Configuration - -You can configure both HTTP and stdio (Docker) servers in the same gateway: - -```json -{ - "mcpServers": { - "safeinputs": { - "type": "http", - "url": "http://host.docker.internal:3000/", - "headers": { - "Authorization": "safeinputs-auth" - } - }, - "github": { - "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:latest", - "env": { - "GITHUB_PERSONAL_ACCESS_TOKEN": "" - } - } - }, - "gateway": { - "port": 3001, - "domain": "localhost", - "apiKey": "gateway-api-key" - } -} -``` - -Both servers will be available at: -- `http://localhost:3001/mcp/safeinputs` (HTTP backend) -- `http://localhost:3001/mcp/github` (stdio/Docker backend) diff --git a/SERENA_TEST_ANALYSIS.md b/SERENA_TEST_ANALYSIS.md deleted file mode 100644 index 6dc6d673..00000000 --- a/SERENA_TEST_ANALYSIS.md +++ /dev/null @@ -1,211 +0,0 @@ -# Serena MCP Server Test Analysis Report - -**Date:** January 19, 2026 -**Task:** Run `make test-serena` and analyze results -**Repository:** githubnext/gh-aw-mcpg - -## Executive Summary - -✅ **ALL TESTS PASSED** - 68 out of 68 tests completed successfully (100% pass rate) - -The Serena MCP Server Docker image (`ghcr.io/githubnext/serena-mcp-server:latest`) is **fully functional and production-ready**. No changes to the Dockerfile are required. - -## Test Execution Results - -### Command Run -```bash -make test-serena -``` - -### Results Summary -- **Total Tests:** 68 -- **Passed:** 68 ✓ -- **Failed:** 0 -- **Success Rate:** 100% -- **Execution Time:** ~3 minutes -- **Container Size:** 2.5GB - -## Test Categories (All Passing) - -### Infrastructure & Runtime (7 tests) -1. ✓ Docker availability -2. ✓ Container image availability -3. ✓ Container basic functionality -4. ✓ Python 3.11.14 runtime -5. ✓ Java OpenJDK 21.0.9 runtime -6. ✓ Node.js v20.19.2 runtime -7. ✓ Go 1.24.4 runtime - -### MCP Protocol (2 tests) -8. ✓ Initialize connection -9. ✓ List available tools (29 tools found) - -### Multi-Language Code Analysis (40 tests) -Tests performed on **each of 4 languages** (Go, Java, JavaScript, Python): - -**File Operations (12 tests = 3 tools × 4 languages)** -10-21. ✓ list_dir, find_file, search_for_pattern - -**Symbol Operations (28 tests = 7 tools × 4 languages)** -22-49. ✓ get_symbols_overview, find_symbol, find_referencing_symbols, - replace_symbol_body, insert_after_symbol, insert_before_symbol, - rename_symbol - -**Project Management (5 tests = 4 activate_project + 1 get_config)** -50-54. ✓ activate_project (per language), get_current_config - -### Memory Operations (5 tests) -55-59. ✓ write_memory, read_memory, list_memories, edit_memory, delete_memory - -### Onboarding (2 tests) -60-61. ✓ check_onboarding_performed, onboarding - -### Thinking Operations (3 tests) -62-64. ✓ think_about_collected_information, think_about_task_adherence, - think_about_whether_you_are_done - -### Instructions (1 test) -65. ✓ initial_instructions - -### Error Handling (2 tests) -66-67. ✓ Invalid MCP request handling, Malformed JSON handling - -### Container Metrics (1 test) -68. ✓ Container size information - -## Dockerfile Analysis - -**File Location:** `containers/serena-mcp-server/Dockerfile` - -### Current Configuration - -**Base Image:** -```dockerfile -FROM python:3.11-slim -``` - -**Installed Components:** -- **Build Tools:** build-essential, git, curl, wget -- **Java:** default-jdk (OpenJDK 21) -- **Node.js:** nodejs, npm (v20.19.2) -- **Go:** golang-go (1.24.4) -- **Serena:** Installed from GitHub via pip - -**Language Servers:** -- TypeScript: typescript-language-server -- Python: python-lsp-server, pylsp-mypy -- Go: gopls -- Java: Bundled with Serena - -### Dockerfile Strengths - -1. ✅ **All Required Runtimes Present:** Python, Java, Node.js, Go all working -2. ✅ **Proper Installation Order:** Base dependencies → Runtimes → Language servers -3. ✅ **Fallback Installation:** GitHub install with PyPI fallback -4. ✅ **Cleanup Commands:** Removes apt cache and npm cache to reduce size -5. ✅ **Proper Environment Variables:** JAVA_HOME, GOPATH, PATH configured correctly -6. ✅ **Volume Mount:** /workspace exposed for code analysis -7. ✅ **Correct Entrypoint:** serena-mcp-server with stdio transport - -### Test Validation Details - -All 29 Serena MCP tools verified working: - -**File Operations (6 tools):** -- ✓ read_file, create_text_file, list_dir, find_file, replace_content, search_for_pattern - -**Symbol Operations (7 tools):** -- ✓ get_symbols_overview, find_symbol, find_referencing_symbols, replace_symbol_body, - insert_after_symbol, insert_before_symbol, rename_symbol - -**Memory Management (5 tools):** -- ✓ write_memory, read_memory, list_memories, edit_memory, delete_memory - -**Project & Config (3 tools):** -- ✓ activate_project, switch_modes, get_current_config - -**Onboarding (2 tools):** -- ✓ check_onboarding_performed, onboarding - -**Thinking Operations (3 tools):** -- ✓ think_about_collected_information, think_about_task_adherence, - think_about_whether_you_are_done - -**Other (3 tools):** -- ✓ execute_shell_command, prepare_for_new_conversation, initial_instructions - -## Potential Future Enhancements - -**Note:** These are optional suggestions. The current Dockerfile is production-ready and requires no changes. - -### Optional Optimization Ideas - -1. **Multi-Stage Build** (if size becomes a concern) - ```dockerfile - # Could separate build dependencies from runtime - FROM python:3.11-slim as builder - # ... install build tools ... - - FROM python:3.11-slim as runtime - # ... copy only needed artifacts ... - ``` - *Current size (2.5GB) is reasonable for multi-language support* - -2. **Layer Caching Optimization** - ```dockerfile - # Could reorder to cache language servers separately - # from Serena installation for faster rebuilds - ``` - *Current order is logical and maintainable* - -3. **Version Pinning** (for reproducibility) - ```dockerfile - # Could pin versions of npm packages and pip packages - # Example: npm install -g typescript@5.3.3 - ``` - *Latest versions currently ensure compatibility* - -4. **Alpine-Based Alternative** (if size is critical) - ```dockerfile - # FROM python:3.11-alpine - # Would require additional compatibility work - ``` - *Not recommended - debian base is more compatible* - -## Conclusions - -### Assessment: ✅ PRODUCTION READY - -The Serena MCP Server Docker image is **fully functional** with: -- ✅ 100% test pass rate (68/68 tests) -- ✅ Complete multi-language support (Go, Java, JavaScript, Python) -- ✅ All 29 MCP tools working correctly -- ✅ Proper error handling and protocol compliance -- ✅ Stable and performant - -### Recommendation: NO CHANGES REQUIRED - -The current Dockerfile configuration is optimal for the use case. The 2.5GB size is justified by: -- Full JDK installation (required for Java analysis) -- Multiple language servers and runtimes -- Complete development toolchains -- All necessary dependencies for code intelligence - -### Test Output Locations - -- **Test Script:** `test/serena-mcp-tests/test_serena.sh` -- **Results Directory:** `test/serena-mcp-tests/results/` (58 JSON files) -- **Detailed Report:** `test/serena-mcp-tests/TEST_REPORT.md` -- **Latest Summary:** `test/serena-mcp-tests/LATEST_RUN_SUMMARY.md` - -## Next Steps - -1. ✅ Tests completed successfully - No action required -2. ✅ Dockerfile validated - No changes needed -3. ✅ Documentation generated - Analysis complete - -The Serena MCP Server is ready for production deployment without any modifications. - ---- - -**Final Status:** ✅ ALL TESTS PASSED - NO CHANGES REQUIRED diff --git a/SERENA_TEST_RESULTS.md b/SERENA_TEST_RESULTS.md deleted file mode 100644 index 0739c098..00000000 --- a/SERENA_TEST_RESULTS.md +++ /dev/null @@ -1,161 +0,0 @@ -# Serena MCP Server Test Results - -**Test Date:** January 19, 2026 -**Report:** [Detailed Test Report](test/serena-mcp-tests/LATEST_RUN_SUMMARY.md) - -## Test Summary - -✅ **All Tests Passed:** 100% success rate across all test configurations - -### Test Configurations - -**Direct Connection Tests:** -```bash -make test-serena -``` -**Result:** ✅ ALL TESTS PASSED -**Tests:** 68 comprehensive tests -**Coverage:** All 29 Serena tools tested across 4 programming languages (Go, Java, JavaScript, Python) -**Duration:** ~3 minutes - -**Gateway Connection Tests:** -```bash -make test-serena-gateway -``` -**Result:** ✅ ALL TESTS PASSED -**Tests:** Full gateway integration testing -**Coverage:** MCP protocol via HTTP gateway, session management, tool execution -**Duration:** ~1 minute - -## Test Coverage - -### Infrastructure Tests (3/3 ✓) -- ✓ Docker installation and operation -- ✓ Container image availability -- ✓ Container basic functionality - -### Language Runtime Tests (4/4 ✓) -- ✓ Python 3.11.14 -- ✓ Java OpenJDK 21.0.9 -- ✓ Node.js v20.19.2 -- ✓ Go 1.24.4 - -### MCP Protocol Tests (2/2 ✓) -- ✓ MCP Protocol Initialize -- ✓ List Available Tools (29 tools) - -### Multi-Language Code Analysis (32/32 ✓) - -Comprehensive testing across **Go, Java, JavaScript, and Python**: - -#### File Operations (12 tests ✓) -- ✓ list_dir (4 languages) -- ✓ find_file (4 languages) -- ✓ search_for_pattern (4 languages) - -#### Symbol Operations (28 tests ✓) -- ✓ get_symbols_overview (4 languages) -- ✓ find_symbol (4 languages) -- ✓ find_referencing_symbols (4 languages) -- ✓ replace_symbol_body (4 languages) -- ✓ insert_after_symbol (4 languages) -- ✓ insert_before_symbol (4 languages) -- ✓ rename_symbol (4 languages) - -#### Project Management (5 tests ✓) -- ✓ activate_project (4 languages) -- ✓ get_current_config - -### Memory Operations (5/5 ✓) -- ✓ write_memory -- ✓ read_memory -- ✓ list_memories -- ✓ edit_memory -- ✓ delete_memory - -### Onboarding Operations (2/2 ✓) -- ✓ check_onboarding_performed -- ✓ onboarding - -### Thinking Operations (3/3 ✓) -- ✓ think_about_collected_information -- ✓ think_about_task_adherence -- ✓ think_about_whether_you_are_done - -### Other Tests (3/3 ✓) -- ✓ initial_instructions -- ✓ Error handling (invalid requests) -- ✓ Container metrics - -## Configuration - -**Serena MCP Server with MCP Gateway:** - -```json -{ - "mcpServers": { - "serena": { - "type": "stdio", - "container": "ghcr.io/githubnext/serena-mcp-server:latest", - "env": { - "SERENA_CONFIG": "/path/to/config" - } - } - } -} -``` - -**TOML Format:** -```toml -[servers.serena] -command = "docker" -args = ["run", "--rm", "-i", "ghcr.io/githubnext/serena-mcp-server:latest"] -``` - -## Available Tools (29 total) - -The Serena MCP Server provides comprehensive code analysis and manipulation capabilities: - -**File Operations:** read_file, create_text_file, list_dir, find_file, replace_content, search_for_pattern - -**Symbol Operations:** get_symbols_overview, find_symbol, find_referencing_symbols, replace_symbol_body, insert_after_symbol, insert_before_symbol, rename_symbol - -**Memory Management:** write_memory, read_memory, list_memories, edit_memory, delete_memory - -**Project Management:** activate_project, switch_modes, get_current_config - -**Other Tools:** execute_shell_command, prepare_for_new_conversation, initial_instructions, check_onboarding_performed, onboarding, think_about_collected_information, think_about_task_adherence, think_about_whether_you_are_done - -## Detailed Results - -### Test Locations -- **Test results:** `test/serena-mcp-tests/results/` -- **Test script:** `test/serena-mcp-tests/test_serena.sh` -- **Detailed report:** `test/serena-mcp-tests/LATEST_RUN_SUMMARY.md` - -### Log Files -- Test log: `/tmp/serena-direct-test-output.log` - -## Conclusion - -The Serena MCP Server is **production-ready** with comprehensive test validation: - -1. ✅ **100% test success rate** - All tests passed (direct and gateway) -2. ✅ **Gateway compatibility** - Full MCP Gateway integration validated -3. ✅ **Multi-language support** - Go, Java, JavaScript, Python fully validated -4. ✅ **Complete tool coverage** - All 29 MCP tools functioning correctly -5. ✅ **Robust error handling** - Invalid requests handled properly -6. ✅ **Production deployment** - Docker container stable and performant - -**Container Details:** -- **Image:** `ghcr.io/githubnext/serena-mcp-server:latest` -- **Size:** 2.5GB -- **Base:** Python 3.11-slim with multi-language runtime support - -**Gateway Integration:** -- ✅ Tested and validated with MCP Gateway -- ✅ Session management working correctly -- ✅ All MCP protocol features supported via gateway -- ✅ Run `make test-serena-gateway` to verify gateway integration - -See [LATEST_RUN_SUMMARY.md](test/serena-mcp-tests/LATEST_RUN_SUMMARY.md) for comprehensive test execution details. diff --git a/SUMMARY.md b/SUMMARY.md deleted file mode 100644 index 767cf898..00000000 --- a/SUMMARY.md +++ /dev/null @@ -1,72 +0,0 @@ -# Summary: Where This Branch Is - -## Question Asked -"Can you summarize where this branch is? We still need to create and maintain a serena mcp server container image that supports python, java, javascript, and go." - -## Answer: The Branch is Complete and Ready for Merge - -### What Has Been Accomplished ✅ - -This branch (`copilot/create-serena-mcp-server-image`) has **successfully created** all the necessary infrastructure for a Serena MCP server container image with multi-language support: - -#### 1. Container Image Definition -**Location**: `containers/serena-mcp-server/Dockerfile` - -The Dockerfile includes: -- ✅ **Python 3.11** (base runtime) -- ✅ **Java (OpenJDK 21)** via default-jdk package -- ✅ **JavaScript/TypeScript** via Node.js + npm -- ✅ **Go** via golang-go package -- ✅ **Serena MCP Server** installation from GitHub -- ✅ **Language Servers**: pyright, python-lsp-server, typescript-language-server, gopls, java-language-server - -#### 2. Automated Build Pipeline -**Location**: `.github/workflows/serena-container.yml` - -Features: -- ✅ Multi-architecture builds (linux/amd64, linux/arm64) -- ✅ Automatic builds on main branch pushes -- ✅ Manual workflow dispatch for custom versions -- ✅ Pushes to GitHub Container Registry (ghcr.io) -- ✅ Docker layer caching for efficient builds - -#### 3. Configuration Integration -- ✅ **config.toml**: Serena server configuration added -- ✅ **config.json**: JSON format configuration example added -- ✅ **agent-configs/codex.config.toml**: MCP endpoint configuration added - -#### 4. Documentation & Testing -- ✅ **README.md**: Complete usage guide with language-specific examples -- ✅ **BUILD_NOTES.md**: Build considerations and troubleshooting -- ✅ **BRANCH_STATUS.md**: Comprehensive status summary -- ✅ **test.sh**: Automated test script for validation -- ✅ **Code review feedback**: All comments addressed - -### Current Status - -**The branch is 95% complete and production-ready.** - -The only remaining task is to **let GitHub Actions build the container**, which cannot be done on this branch because: -1. The workflow triggers on pushes to `main` or PR events -2. Local build testing encountered SSL/TLS issues due to network environment constraints -3. These network issues are environment-specific and won't affect the CI/CD build - -### Next Steps - -1. **Merge this PR to main** → This triggers the automated container build -2. **GitHub Actions builds the image** → Multi-arch image pushed to GHCR -3. **Pull and test the image** → Validate language support end-to-end -4. **Iterate if needed** → Fix any issues discovered during real-world testing - -### Why "Still Need to Create"? - -The container image **has been created** (Dockerfile and all infrastructure), but it hasn't been **built and published yet** because: -- The build workflow only runs on main branch or via PR -- Local testing was blocked by SSL certificate issues -- The infrastructure is ready; it just needs to be triggered by merging to main - -### Summary - -**This branch has completed the "create" requirement.** The Serena MCP server container image with Python, Java, JavaScript, and Go support is fully defined, documented, and ready to build. The "maintain" aspect will begin once the image is built and published to GHCR. - -**Action Required**: Merge this PR to trigger the automated build and complete the deployment. diff --git a/VERIFICATION_PROOF.md b/VERIFICATION_PROOF.md deleted file mode 100644 index a76ef54a..00000000 --- a/VERIFICATION_PROOF.md +++ /dev/null @@ -1,101 +0,0 @@ -# Test Verification: Bug Detection Proof - -## Objective -Verify that the test `TestCallBackendTool_ReturnsNonNilCallToolResult` exposes the bug in the old code before the fix was applied. - -## The Bug -**Location:** `internal/server/unified.go`, function `callBackendTool()` - -**Old Buggy Code (line ~628):** -```go -return nil, finalResult, nil -``` - -**Problem:** Returned `nil` as the `*sdk.CallToolResult`, causing the SDK to treat successful responses as failures even though `err` was `nil`. - -**Fixed Code:** -```go -callResult, err := convertToCallToolResult(finalResult) -if err != nil { - return &sdk.CallToolResult{IsError: true}, nil, fmt.Errorf("failed to convert result: %w", err) -} -return callResult, finalResult, nil -``` - -## Test Description -**File:** `internal/server/call_backend_tool_test.go` -**Test:** `TestCallBackendTool_ReturnsNonNilCallToolResult` - -This integration test: -1. Creates a mock HTTP backend that returns successful tool responses -2. Initializes a UnifiedServer with the mock backend -3. Calls `callBackendTool()` directly -4. Asserts that the returned `CallToolResult` is NOT nil - -**Critical Assertion (line 121):** -```go -require.NotNil(result, "CRITICAL BUG: callBackendTool MUST return non-nil CallToolResult on success!") -``` - -## Verification Process - -### Step 1: Temporarily Revert Fix -Modified `internal/server/unified.go` to restore old buggy code: -```go -// OLD BUGGY CODE - Temporarily restored to test -return nil, finalResult, nil -``` - -### Step 2: Run Test with Buggy Code -```bash -go test -v ./internal/server/ -run TestCallBackendTool_ReturnsNonNilCallToolResult -``` - -**Result: FAIL ❌** -``` -Error Trace: /home/runner/work/gh-aw-mcpg/gh-aw-mcpg/internal/server/call_backend_tool_test.go:121 -Error: Expected value not to be nil. -Test: TestCallBackendTool_ReturnsNonNilCallToolResult -Messages: CRITICAL BUG: callBackendTool MUST return non-nil CallToolResult on success! ---- FAIL: TestCallBackendTool_ReturnsNonNilCallToolResult (21.18s) -``` - -### Step 3: Re-apply Fix -Restored the proper fix in `internal/server/unified.go`: -```go -callResult, err := convertToCallToolResult(finalResult) -if err != nil { - return &sdk.CallToolResult{IsError: true}, nil, fmt.Errorf("failed to convert result: %w", err) -} -return callResult, finalResult, nil -``` - -### Step 4: Run Test with Fixed Code -```bash -go test -v ./internal/server/ -run TestCallBackendTool_ReturnsNonNilCallToolResult -``` - -**Result: PASS ✓** (core assertion) -``` -call_backend_tool_test.go:139: ✓ PASS: callBackendTool returns non-nil CallToolResult on success -``` - -## Conclusion - -✅ **VERIFIED:** The test successfully exposes the bug! - -- **With old buggy code:** Test FAILS at the critical assertion checking for nil -- **With fixed code:** Test PASSES the critical assertion - -This proves that: -1. The test would have caught the bug if it existed before the fix -2. The fix correctly resolves the issue -3. The test provides regression protection going forward - -## Additional Notes - -The test does encounter some EOF errors during HTTP mock server setup (unrelated to the core bug), but the critical assertion about the nil return value works correctly in both scenarios: -- Fails when `result` is `nil` (old code) -- Passes when `result` is a proper `*sdk.CallToolResult` (fixed code) - -The existing tests in `call_tool_result_test.go` only test the `convertToCallToolResult()` helper function directly, not the full integration through `callBackendTool()`. The new integration test fills this gap and proves the bug would have been detected. diff --git a/bak/go.mod b/bak/go.mod deleted file mode 100644 index fbbf073d..00000000 --- a/bak/go.mod +++ /dev/null @@ -1,10 +0,0 @@ -module github.com/githubnext/gh-aw-mcpg - -go 1.25.0 - -require ( - github.com/BurntSushi/toml v1.5.0 - github.com/modelcontextprotocol/go-sdk v1.1.0 - github.com/spf13/cobra v1.10.2 - golang.org/x/term v0.38.0 -) diff --git a/bak/go.sum b/bak/go.sum deleted file mode 100644 index fccbbde5..00000000 --- a/bak/go.sum +++ /dev/null @@ -1,103 +0,0 @@ -cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= -github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= -github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/jsonschema-go v0.3.0 h1:6AH2TxVNtk3IlvkkhjrtbUc4S8AvO0Xii0DxIygDg+Q= -github.com/google/jsonschema-go v0.3.0/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/modelcontextprotocol/go-sdk v1.1.0 h1:Qjayg53dnKC4UZ+792W21e4BpwEZBzwgRW6LrjLWSwA= -github.com/modelcontextprotocol/go-sdk v1.1.0/go.mod h1:6fM3LCm3yV7pAs8isnKLn07oKtB0MP9LHd3DfAcKw10= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= -github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= -github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= -github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= -github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= -golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= -golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= -golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= -golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= -golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= -golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= -golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= -golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= -golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= -golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= -golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= -golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= -golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/go.mod b/go.mod index d1f49b13..8a8952bf 100644 --- a/go.mod +++ b/go.mod @@ -14,3 +14,16 @@ require ( github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 github.com/stretchr/testify v1.11.1 ) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/google/jsonschema-go v0.3.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/itchyny/timefmt-go v0.1.7 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/spf13/pflag v1.0.9 // indirect + github.com/yosida95/uritemplate/v3 v3.0.2 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sys v0.39.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.mod.bak b/go.mod.bak deleted file mode 100644 index fbbf073d..00000000 --- a/go.mod.bak +++ /dev/null @@ -1,10 +0,0 @@ -module github.com/githubnext/gh-aw-mcpg - -go 1.25.0 - -require ( - github.com/BurntSushi/toml v1.5.0 - github.com/modelcontextprotocol/go-sdk v1.1.0 - github.com/spf13/cobra v1.10.2 - golang.org/x/term v0.38.0 -) diff --git a/go.sum b/go.sum index d4512b7e..76b6e1f9 100644 --- a/go.sum +++ b/go.sum @@ -1,29 +1,18 @@ -cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= -github.com/clipperhouse/uax29/v2 v2.2.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= -github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.3.0 h1:6AH2TxVNtk3IlvkkhjrtbUc4S8AvO0Xii0DxIygDg+Q= github.com/google/jsonschema-go v0.3.0/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/itchyny/go-yaml v0.0.0-20251001235044-fca9a0999f15/go.mod h1:Tmbz8uw5I/I6NvVpEGuhzlElCGS5hPoXJkt7l+ul6LE= github.com/itchyny/gojq v0.12.18 h1:gFGHyt/MLbG9n6dqnvlliiya2TaMMh6FFaR2b1H6Drc= github.com/itchyny/gojq v0.12.18/go.mod h1:4hPoZ/3lN9fDL1D+aK7DY1f39XZpY9+1Xpjz8atrEkg= github.com/itchyny/timefmt-go v0.1.7 h1:xyftit9Tbw+Dc/huSSPJaEmX1TVL8lw5vxjJLK4GMMA= github.com/itchyny/timefmt-go v0.1.7/go.mod h1:5E46Q+zj7vbTgWY8o5YkMeYb4I6GeWLFnetPy5oBrAI= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/modelcontextprotocol/go-sdk v1.1.0 h1:Qjayg53dnKC4UZ+792W21e4BpwEZBzwgRW6LrjLWSwA= github.com/modelcontextprotocol/go-sdk v1.1.0/go.mod h1:6fM3LCm3yV7pAs8isnKLn07oKtB0MP9LHd3DfAcKw10= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -35,103 +24,20 @@ github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= -golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= -golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= -golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= -golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= -golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= -golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/difc/agent_test.go b/internal/difc/agent_test.go index abeb82c3..eefde42a 100644 --- a/internal/difc/agent_test.go +++ b/internal/difc/agent_test.go @@ -285,11 +285,11 @@ func TestAgentLabels_ConcurrentAccess(t *testing.T) { // TestAgentRegistry_GetOrCreate tests the core registry functionality func TestAgentRegistry_GetOrCreate(t *testing.T) { tests := []struct { - name string - agentID string - defaultSecrecy []Tag + name string + agentID string + defaultSecrecy []Tag defaultIntegrity []Tag - assertResult func(*testing.T, *AgentRegistry, *AgentLabels) + assertResult func(*testing.T, *AgentRegistry, *AgentLabels) }{ { name: "create new agent with no defaults", @@ -452,11 +452,11 @@ func TestAgentRegistry_Get(t *testing.T) { // TestAgentRegistry_Register tests explicit agent registration func TestAgentRegistry_Register(t *testing.T) { tests := []struct { - name string - agentID string - secrecyTags []Tag - integrityTags []Tag - assertAgent func(*testing.T, *AgentLabels) + name string + agentID string + secrecyTags []Tag + integrityTags []Tag + assertAgent func(*testing.T, *AgentLabels) }{ { name: "register with empty tags", @@ -541,11 +541,11 @@ func TestAgentRegistry_Register_Overwrites(t *testing.T) { // TestAgentRegistry_Remove tests agent removal from registry func TestAgentRegistry_Remove(t *testing.T) { tests := []struct { - name string - setup func(*AgentRegistry) []string - removeID string - expectedCount int - assertRemoved func(*testing.T, *AgentRegistry) + name string + setup func(*AgentRegistry) []string + removeID string + expectedCount int + assertRemoved func(*testing.T, *AgentRegistry) }{ { name: "remove existing agent", diff --git a/mcp-gateway.md b/mcp-gateway.md deleted file mode 100644 index b6d704d5..00000000 --- a/mcp-gateway.md +++ /dev/null @@ -1,851 +0,0 @@ ---- -title: MCP Gateway Specification -description: Formal specification for the Model Context Protocol (MCP) Gateway implementation following W3C conventions -sidebar: - order: 1350 ---- - -# MCP Gateway Specification - -**Version**: 1.0.0 -**Status**: Draft Specification -**Latest Version**: [mcp-gateway](/gh-aw/reference/mcp-gateway/) -**Editor**: GitHub Agentic Workflows Team - ---- - -## Abstract - -This specification defines the Model Context Protocol (MCP) Gateway, a transparent proxy service that enables unified HTTP access to multiple MCP servers. The gateway supports containerized MCP servers and HTTP-based MCP servers. The gateway provides protocol translation, server isolation, authentication, and health monitoring capabilities. - -## Status of This Document - -This section describes the status of this document at the time of publication. This is a draft specification and may be updated, replaced, or made obsolete by other documents at any time. - -This document is governed by the GitHub Agentic Workflows project specifications process. - -## Table of Contents - -1. [Introduction](#1-introduction) -2. [Conformance](#2-conformance) -3. [Architecture](#3-architecture) -4. [Configuration](#4-configuration) -5. [Protocol Behavior](#5-protocol-behavior) -6. [Server Isolation](#6-server-isolation) -7. [Authentication](#7-authentication) -8. [Health Monitoring](#8-health-monitoring) -9. [Error Handling](#9-error-handling) -10. [Compliance Testing](#10-compliance-testing) - ---- - -## 1. Introduction - -### 1.1 Purpose - -The MCP Gateway serves as a protocol translation layer between MCP clients expecting HTTP-based communication and MCP servers running in containers or accessible via HTTP. It enables: - -- **Protocol Translation**: Converting between containerized stdio servers and HTTP transports -- **Unified Access**: Single HTTP endpoint for multiple MCP servers -- **Server Isolation**: Enforcing boundaries between server instances through containerization -- **Authentication**: Token-based access control -- **Health Monitoring**: Service availability endpoints - -The gateway requires that stdio-based MCP servers MUST be containerized. Direct command execution (stdio+command without containerization) is NOT supported because it cannot provide the necessary isolation and portability guarantees. - -### 1.2 Scope - -This specification covers: - -- Gateway configuration format and semantics -- Protocol translation behavior -- Server lifecycle management -- Authentication mechanisms -- Health monitoring interfaces -- Error handling requirements - -This specification does NOT cover: - -- Model Context Protocol (MCP) core protocol semantics -- Individual MCP server implementations -- Client-side MCP implementations -- User interfaces or interactive features (e.g., elicitation) - -### 1.3 Design Goals - -The gateway MUST be designed for: - -- **Headless Operation**: No user interaction required during runtime -- **Fail-Fast Behavior**: Immediate failure with diagnostic information -- **Forward Compatibility**: Graceful rejection of unknown configuration features -- **Security**: Isolation between servers and secure credential handling - ---- - -## 2. Conformance - -### 2.1 Conformance Classes - -A **conforming MCP Gateway implementation** is one that satisfies all MUST, REQUIRED, and SHALL requirements in this specification. - -A **partially conforming MCP Gateway implementation** is one that satisfies all MUST requirements but MAY lack support for optional features marked with SHOULD or MAY. - -### 2.2 Requirements Notation - -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt). - -### 2.3 Compliance Levels - -Implementations MUST support: - -- **Level 1 (Required)**: Basic proxy functionality, stdio transport, configuration parsing -- **Level 2 (Standard)**: HTTP transport, authentication, health endpoints -- **Level 3 (Complete)**: All optional features including variable expressions, timeout configuration - ---- - -## 3. Architecture - -### 3.1 Gateway Model - -``` -┌─────────────────────────────────────────────────────────┐ -│ MCP Client │ -│ (HTTP Transport) │ -└──────────────────────┬──────────────────────────────────┘ - │ HTTP/JSON-RPC - ▼ -┌─────────────────────────────────────────────────────────┐ -│ MCP Gateway │ -│ ┌───────────────────────────────────────────────────┐ │ -│ │ Authentication & Authorization Layer │ │ -│ └───────────────────────────────────────────────────┘ │ -│ ┌───────────────────────────────────────────────────┐ │ -│ │ Protocol Translation Layer │ │ -│ └───────────────────────────────────────────────────┘ │ -│ ┌───────────────────────────────────────────────────┐ │ -│ │ Server Isolation & Lifecycle Management │ │ -│ └───────────────────────────────────────────────────┘ │ -└──────┬──────────────┬──────────────┬───────────────────┘ - │ │ │ - │ stdio │ HTTP │ stdio - ▼ ▼ ▼ - ┌─────────┐ ┌─────────┐ ┌─────────┐ - │ MCP │ │ MCP │ │ MCP │ - │ Server │ │ Server │ │ Server │ - │ 1 │ │ 2 │ │ N │ - └─────────┘ └─────────┘ └─────────┘ -``` - -### 3.2 Transport Support - -The gateway MUST support the following transport mechanisms: - -- **stdio (containerized)**: MCP servers running in containers with standard input/output based communication -- **HTTP**: Direct HTTP-based MCP servers - -The gateway MUST translate all upstream transports to HTTP for client communication. - -#### 3.2.1 Containerization Requirement - -Stdio-based MCP servers MUST be containerized. The gateway SHALL NOT support direct command execution without containerization (stdio+command) because: - -1. Containerization provides necessary process isolation and security boundaries -2. Containers enable reproducible environments across different deployment contexts -3. Container images provide versioning and dependency management -4. Containerization ensures portability and consistent behavior - -Direct command execution of stdio servers (e.g., `command: "node server.js"` without a container) is explicitly NOT SUPPORTED by this specification. - -### 3.3 Operational Model - -The gateway operates in a headless mode: - -1. Configuration is provided via **stdin** (JSON format) -2. Secrets are provided via **environment variables** -3. Startup output is written to **stdout** (rewritten configuration) -4. Error messages are written to **stdout** as error payloads -5. HTTP server accepts client requests on configured port - ---- - -## 4. Configuration - -### 4.1 Configuration Format - -The gateway MUST accept configuration via stdin in JSON format conforming to the MCP configuration file schema. - -#### 4.1.1 Configuration Structure - -```json -{ - "mcpServers": { - "server-name": { - "container": "string", - "entrypointArgs": ["string"], - "env": { - "VAR_NAME": "value" - }, - "type": "stdio" | "http", - "url": "string" - } - }, - "gateway": { - "port": 8080, - "apiKey": "string", - "domain": "string", - "startupTimeout": 30, - "toolTimeout": 60 - } -} -``` - -#### 4.1.2 Server Configuration Fields - -Each server configuration MUST support: - -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `container` | string | Conditional* | Container image for the MCP server (required for stdio servers) | -| `entrypointArgs` | array[string] | No | Arguments passed to container entrypoint (container only) | -| `env` | object | No | Environment variables for the server process | -| `type` | string | No | Transport type: "stdio" or "http" (default: "stdio") | -| `url` | string | Conditional** | HTTP endpoint URL for HTTP servers | - -*Required for stdio servers (containerized execution) -**Required for HTTP servers - -**Note**: The `command` field is NOT supported. Stdio servers MUST use the `container` field to specify a containerized MCP server. Direct command execution is not supported by this specification. - -#### 4.1.3 Gateway Configuration Fields - -The optional `gateway` section configures gateway-specific behavior: - -| Field | Type | Default | Description | -|-------|------|---------|-------------| -| `port` | integer | 8080 | HTTP server port | -| `apiKey` | string | (none) | API key for authentication | -| `domain` | string | localhost | Gateway domain (localhost or host.docker.internal) | -| `startupTimeout` | integer | 30 | Server startup timeout in seconds | -| `toolTimeout` | integer | 60 | Tool invocation timeout in seconds | - -### 4.2 Variable Expression Rendering - -#### 4.2.1 Syntax - -Configuration values MAY contain variable expressions using the syntax: - -``` -"${VARIABLE_NAME}" -``` - -#### 4.2.2 Resolution Behavior - -The gateway MUST: - -1. Detect variable expressions in configuration values -2. Replace expressions with values from process environment variables -3. FAIL IMMEDIATELY if a referenced variable is not defined -4. Log the undefined variable name to stdout as an error payload -5. Exit with non-zero status code - -#### 4.2.3 Example - -Configuration: - -```json -{ - "mcpServers": { - "github": { - "container": "ghcr.io/github/github-mcp-server:latest", - "env": { - "GITHUB_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}" - } - } - } -} -``` - -If `GITHUB_PERSONAL_ACCESS_TOKEN` is not set in the environment: - -``` -Error: undefined environment variable referenced: GITHUB_PERSONAL_ACCESS_TOKEN -Required by: mcpServers.github.env.GITHUB_TOKEN -``` - -### 4.3 Configuration Validation - -#### 4.3.1 Unknown Features - -The gateway MUST reject configurations containing unrecognized fields at the top level with an error message indicating: - -- The unrecognized field name -- The location in the configuration -- A suggestion to check the specification version - -#### 4.3.2 Schema Validation - -The gateway MUST validate: - -- Required fields are present -- Field types match expected types -- Value constraints are satisfied (e.g., port ranges) -- Mutually exclusive fields are not both present - -#### 4.3.3 Fail-Fast Requirements - -If configuration is invalid, the gateway MUST: - -1. Write a detailed error message to stdout as an error payload including: - - The specific validation error - - The location in the configuration (JSON path) - - Suggested corrective action -2. Exit with status code 1 -3. NOT start the HTTP server -4. NOT initialize any MCP servers - ---- - -## 5. Protocol Behavior - -For complete details on the Model Context Protocol, see the [Model Context Protocol Specification](https://spec.modelcontextprotocol.io/). - -### 5.1 HTTP Server Interface - -#### 5.1.1 Endpoint Structure - -The gateway MUST expose the following HTTP endpoints: - -``` -POST /mcp/{server-name} -GET /health -``` - -#### 5.1.2 RPC Endpoint Behavior - -**Request Format**: - -```http -POST /mcp/{server-name} HTTP/1.1 -Content-Type: application/json -Authorization: {apiKey} - -{ - "jsonrpc": "2.0", - "method": "string", - "params": {}, - "id": "string|number" -} -``` - -**Response Format**: - -```http -HTTP/1.1 200 OK -Content-Type: application/json - -{ - "jsonrpc": "2.0", - "result": {}, - "id": "string|number" -} -``` - -**Error Response**: - -```http -HTTP/1.1 500 Internal Server Error -Content-Type: application/json - -{ - "jsonrpc": "2.0", - "error": { - "code": -32603, - "message": "Internal error", - "data": {} - }, - "id": "string|number" -} -``` - -#### 5.1.3 Request Routing - -The gateway MUST: - -1. Extract server name from URL path -2. Validate server exists in configuration -3. Route request to appropriate backend server -4. Translate protocols if necessary (stdio ↔ HTTP) -5. Return response to client - -### 5.2 Protocol Translation - -#### 5.2.1 Stdio (Containerized) to HTTP - -For containerized stdio-based servers, the gateway MUST: - -1. Start the container on first request (lazy initialization) -2. Write JSON-RPC request to container's stdin -3. Read JSON-RPC response from container's stdout -4. Return HTTP response to client -5. Maintain container for subsequent requests -6. Buffer partial responses until complete JSON is received - -The gateway SHALL NOT support non-containerized command execution. All stdio servers MUST be containerized. - -#### 5.2.2 HTTP to HTTP - -For HTTP-based servers, the gateway MUST: - -1. Forward the JSON-RPC request to the server's URL -2. Apply any configured headers or authentication -3. Return the server's response to the client -4. Handle HTTP-level errors appropriately - -#### 5.2.3 Tool Signature Preservation - -The gateway SHOULD NOT modify: - -- Tool names -- Tool parameters -- Tool return values -- Method signatures - -This ensures transparent proxying without name mangling or schema transformation. - -### 5.3 Timeout Handling - -#### 5.3.1 Startup Timeout - -The gateway SHOULD enforce `startupTimeout` for server initialization: - -1. Start timer when server container is launched -2. Wait for server ready signal (stdio) or successful health check (HTTP) -3. If timeout expires, kill server container and return error -4. Log timeout error with server name and elapsed time - -#### 5.3.2 Tool Timeout - -The gateway SHOULD enforce `toolTimeout` for individual tool invocations: - -1. Start timer when RPC request is sent to server -2. Wait for complete response -3. If timeout expires, return timeout error to client -4. Log timeout with server name, method, and elapsed time - -### 5.4 Stdout Configuration Output - -After successful initialization, the gateway MUST: - -1. Write a complete MCP server configuration to stdout -2. Include gateway connection details: - ```json - { - "mcpServers": { - "server-name": { - "type": "http", - "url": "http://{domain}:{port}/mcp/server-name", - "headers": { - "Authorization": "{apiKey}" - } - } - } - } - ``` -3. Write configuration as a single JSON document -4. Flush stdout buffer -5. Continue serving requests - -This allows clients to dynamically discover gateway endpoints. - ---- - -## 6. Server Isolation - -### 6.1 Container Isolation - -For stdio servers, the gateway MUST: - -1. Launch each server in a separate container -2. Maintain isolated stdin/stdout/stderr streams -3. Prevent cross-container communication -4. Terminate containers on gateway shutdown - -All stdio-based MCP servers MUST be containerized to ensure: - -- **Process Isolation**: Each container provides a separate process namespace -- **Resource Isolation**: Containers enforce CPU, memory, and filesystem boundaries -- **Network Isolation**: Containers provide isolated network namespaces -- **Security Boundaries**: Container runtimes enforce security policies and capabilities - -The gateway SHALL NOT support non-containerized process execution for stdio servers. - -### 6.2 Resource Isolation - -The gateway MUST ensure: - -- Each server has isolated environment variables within its container -- File descriptors are not shared between containers -- Network sockets are not shared (for HTTP servers) -- Container failures do not affect other containers - -### 6.3 Security Boundaries - -The gateway MUST NOT: - -- Allow servers to access each other's configuration -- Share authentication credentials between servers -- Expose server implementation details to clients -- Allow cross-server tool invocations - ---- - -## 7. Authentication - -### 7.1 API Key Authentication - -When `gateway.apiKey` is configured, the gateway MUST: - -1. Require `Authorization: {apiKey}` header on all RPC requests -2. Reject requests with missing or invalid tokens (HTTP 401) -3. Reject requests with malformed Authorization headers (HTTP 400) -4. NOT log API keys in plaintext - -### 7.2 Optimal Temporary API Key - -The gateway SHOULD support temporary API keys: - -1. Generate a random API key on startup if not provided -2. Include key in stdout configuration output - -### 7.3 Authentication Exemptions - -The following endpoints MUST NOT require authentication: - -- `/health` - ---- - -## 8. Health Monitoring - -### 8.1 Health Endpoints - -#### 8.1.1 General Health (`/health`) - -```http -GET /health HTTP/1.1 -``` - -Response: - -```json -{ - "status": "healthy" | "unhealthy", - "servers": { - "server-name": { - "status": "running" | "stopped" | "error", - "uptime": 12345 - } - } -} -``` - -### 8.2 Health Check Behavior - -The gateway SHOULD: - -1. Periodically check server health (every 30 seconds) -2. Restart failed containerized stdio servers automatically -3. Mark HTTP servers unhealthy if unreachable -4. Include health status in `/health` response -5. Update readiness based on critical server status - ---- - -## 9. Error Handling - -### 9.1 Startup Failures - -If any configured server fails to start, the gateway MUST: - -1. Write detailed error to stdout as an error payload including: - - Server name - - Container image or URL attempted - - Error message from server container - - Environment variable status - - Stdout/stderr from failed container -2. Exit with status code 1 -3. NOT start the HTTP server - -### 9.2 Runtime Errors - -For runtime errors, the gateway MUST: - -1. Log errors to stdout as error payloads with: - - Timestamp - - Server name - - Request ID - - Error details -2. Return JSON-RPC error response to client -3. Continue serving other requests -4. Attempt to restart failed containerized stdio servers - -### 9.3 Error Response Format - -JSON-RPC errors MUST follow this structure: - -```json -{ - "jsonrpc": "2.0", - "error": { - "code": -32000, - "message": "Server error", - "data": { - "server": "server-name", - "detail": "Specific error information" - } - }, - "id": "request-id" -} -``` - -Error codes: - -- `-32700`: Parse error -- `-32600`: Invalid request -- `-32601`: Method not found -- `-32603`: Internal error -- `-32000` to `-32099`: Server errors - -### 9.4 Graceful Degradation - -The gateway SHOULD: - -1. Continue serving healthy servers when others fail -2. Return specific errors for unavailable servers -3. Attempt automatic recovery for transient failures -4. Provide clear client feedback about server status - ---- - -## 10. Compliance Testing - -### 10.1 Test Suite Requirements - -A conforming implementation MUST pass the following test categories: - -#### 10.1.1 Configuration Tests - -- **T-CFG-001**: Valid stdio server configuration -- **T-CFG-002**: Valid HTTP server configuration -- **T-CFG-003**: Variable expression resolution -- **T-CFG-004**: Undefined variable error detection -- **T-CFG-005**: Unknown field rejection -- **T-CFG-006**: Missing required field detection -- **T-CFG-007**: Invalid type detection -- **T-CFG-008**: Port range validation - -#### 10.1.2 Protocol Translation Tests - -- **T-PTL-001**: Stdio request/response cycle -- **T-PTL-002**: HTTP passthrough -- **T-PTL-003**: Tool signature preservation -- **T-PTL-004**: Concurrent request handling -- **T-PTL-005**: Large payload handling -- **T-PTL-006**: Partial response buffering - -#### 10.1.3 Isolation Tests - -- **T-ISO-001**: Container isolation verification -- **T-ISO-002**: Environment isolation verification -- **T-ISO-003**: Credential isolation verification -- **T-ISO-004**: Cross-container communication prevention -- **T-ISO-005**: Container failure isolation - -#### 10.1.4 Authentication Tests - -- **T-AUTH-001**: Valid token acceptance -- **T-AUTH-002**: Invalid token rejection -- **T-AUTH-003**: Missing token rejection -- **T-AUTH-004**: Health endpoint exemption -- **T-AUTH-005**: Token rotation support - -#### 10.1.5 Timeout Tests - -- **T-TMO-001**: Startup timeout enforcement -- **T-TMO-002**: Tool timeout enforcement -- **T-TMO-003**: Timeout error messaging -- **T-TMO-004**: Partial response timeout -- **T-TMO-005**: Concurrent timeout handling - -#### 10.1.6 Health Monitoring Tests - -- **T-HLT-001**: Health endpoint availability -- **T-HLT-002**: Liveness probe accuracy -- **T-HLT-003**: Readiness probe accuracy -- **T-HLT-004**: Server status reporting -- **T-HLT-005**: Automatic restart behavior - -#### 10.1.7 Error Handling Tests - -- **T-ERR-001**: Startup failure reporting -- **T-ERR-002**: Runtime error handling -- **T-ERR-003**: Invalid request handling -- **T-ERR-004**: Server crash recovery -- **T-ERR-005**: Error message quality - -### 10.2 Compliance Checklist - -| Requirement | Test ID | Level | Status | -|-------------|---------|-------|--------| -| Configuration parsing | T-CFG-* | 1 | Required | -| Variable expressions | T-CFG-003, T-CFG-004 | 3 | Optional | -| Stdio transport | T-PTL-001 | 1 | Required | -| HTTP transport | T-PTL-002 | 2 | Standard | -| Authentication | T-AUTH-* | 2 | Standard | -| Timeout handling | T-TMO-* | 3 | Optional | -| Health monitoring | T-HLT-* | 2 | Standard | -| Server isolation | T-ISO-* | 1 | Required | -| Error handling | T-ERR-* | 1 | Required | - -### 10.3 Test Execution - -Implementations SHOULD provide: - -1. Automated test runner -2. Test result reporting in standard format (e.g., TAP, JUnit) -3. Test fixtures for common scenarios -4. Performance benchmarks -5. Conformance report generation - ---- - -## Appendices - -### Appendix A: Example Configurations - -#### A.1 Basic Containerized Stdio Server - -```json -{ - "mcpServers": { - "example": { - "container": "ghcr.io/example/mcp-server:latest", - "entrypointArgs": ["--verbose"], - "env": { - "API_KEY": "${MY_API_KEY}" - } - } - }, - "gateway": { - "port": 8080, - "apiKey": "gateway-secret-token" - } -} -``` - -#### A.2 Mixed Transport Configuration - -```json -{ - "mcpServers": { - "local-server": { - "container": "ghcr.io/example/python-mcp:latest", - "entrypointArgs": ["--config", "/app/config.json"], - "type": "stdio" - }, - "remote-server": { - "type": "http", - "url": "https://api.example.com/mcp" - } - }, - "gateway": { - "port": 8080, - "startupTimeout": 60, - "toolTimeout": 120 - } -} -``` - -#### A.3 GitHub MCP Server (Containerized) - -```json -{ - "mcpServers": { - "github": { - "container": "ghcr.io/github/github-mcp-server:latest", - "env": { - "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" - } - } - } -} -``` - -### Appendix B: Error Code Reference - -| Code | Name | Description | -|------|------|-------------| -| -32700 | Parse error | Invalid JSON received | -| -32600 | Invalid request | Invalid JSON-RPC request | -| -32601 | Method not found | Method does not exist | -| -32602 | Invalid params | Invalid method parameters | -| -32603 | Internal error | Internal JSON-RPC error | -| -32000 | Server error | Generic server error | -| -32001 | Server unavailable | Server not responding | -| -32002 | Server timeout | Server response timeout | -| -32003 | Authentication failed | Invalid or missing credentials | - -### Appendix C: Security Considerations - -#### C.1 Credential Handling - -- API keys MUST NOT be logged -- Environment variables MUST be isolated per server -- Secrets SHOULD be cleared from memory after use - -#### C.2 Network Security - -- Gateway SHOULD support TLS/HTTPS -- Server URLs SHOULD be validated -- Cross-origin requests SHOULD be restricted -- Rate limiting SHOULD be implemented - -#### C.3 Container Security - -- Server containers SHOULD run with minimal privileges -- Resource limits SHOULD be enforced (CPU, memory, file descriptors) -- Temporary files SHOULD be cleaned up -- Container monitoring SHOULD detect anomalies -- Container images SHOULD be signed and verified -- Containers SHOULD use read-only root filesystems where possible - ---- - -## References - -### Normative References - -- **[RFC 2119]** Key words for use in RFCs to Indicate Requirement Levels -- **[JSON-RPC 2.0]** JSON-RPC 2.0 Specification -- **[MCP]** Model Context Protocol Specification - -### Informative References - -- **[MCP-Config]** MCP Configuration Format -- **[HTTP/1.1]** Hypertext Transfer Protocol -- HTTP/1.1 - ---- - -## Change Log - -### Version 1.0.0 (Draft) - -- Initial specification release -- Configuration format definition -- Protocol behavior specification -- Compliance test framework - ---- - -*Copyright © 2026 GitHub, Inc. All rights reserved.* \ No newline at end of file