Skip to content

Conversation

@T-rav
Copy link
Collaborator

@T-rav T-rav commented Oct 10, 2025

Summary

This PR adds two major features to WebCat:

1. max_results Parameter for Search Tool

  • Added configurable max_results parameter (default: 5) to control search result count
  • Updated Serper client to use "num" parameter for result limiting
  • Updated DuckDuckGo client to respect max_results
  • Removed broken tool-level authentication (moved to reverse proxy)

2. Nginx Reverse Proxy with Bearer Token Authentication

  • Created Dockerfile.nginx-simple for single-image deployment with built-in auth
  • Added nginx config with dynamic auth via entrypoint script
  • Nginx validates bearer token before proxying requests to WebCat
  • WebCat runs without auth on internal port 4000
  • Nginx exposes authenticated endpoint on port 8000
  • Supports optional auth: works with or without WEBCAT_API_KEY

Architecture Changes

  • Before: WebCat tried to validate auth at tool level (broken due to FastMCP HTTP transport limitations)
  • After: Nginx handles auth at proxy layer, WebCat focuses on MCP functionality
  • Separation of Concerns: Security handled by nginx, application logic in WebCat

Testing

All tests use real APIs (no mocks):

  • test_mcp_no_auth.py - Tests MCP protocol with real Serper API calls
  • test_nginx_auth.py - Tests nginx auth (blocks without token, allows with valid token)
  • test_real_mcp_server.py - Full MCP handshake with max_results verification

Test Results:

Test 1: Without Authorization header → 401 Unauthorized ✅
Test 2: With valid token → 200 OK + Session established ✅
Test 3: Real search with max_results=1 → Returns exactly 1 result ✅

Breaking Changes

⚠️ Potential Breaking Changes:

  • search_tool() signature changed: added max_results parameter (has default, backward compatible)
  • Removed ctx parameter from search_tool (auth moved to nginx)
  • WEBCAT_API_KEY no longer validated at tool level

Deployment Options

Option 1: Without Auth (existing Dockerfile)

docker run -p 8000:8000 -e SERPER_API_KEY=your_key tmfrisinger/webcat:latest

Option 2: With Nginx Auth (new Dockerfile.nginx-simple)

docker build -f docker/Dockerfile.nginx-simple -t webcat-nginx .
docker run -p 8000:8000 --env-file .env webcat-nginx

Test Plan

  • Build succeeds for both Dockerfiles
  • MCP protocol handshake works correctly
  • max_results parameter limits search results
  • Nginx blocks requests without bearer token
  • Nginx allows requests with valid bearer token
  • Real Serper API integration works
  • All pre-commit hooks pass

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Single-container image bundling the app with an nginx auth proxy; exposes port 8000, supports health checks, and simple Bearer token auth via environment variable.
    • Docker Compose example for an nginx reverse proxy that validates tokens and forwards to the internal service.
  • Refactor
    • Authentication is now handled by the nginx proxy; the app runs without in-app auth. Server supports configurable port/path.
  • Tests
    • Added scripts to validate proxy authentication and end-to-end streaming search responses.

This commit adds two major features:

1. **max_results parameter for search tool**
   - Added configurable max_results parameter (default: 5) to search_tool
   - Updated Serper client to use "num" parameter for result limiting
   - Updated DuckDuckGo client to respect max_results
   - Removed broken tool-level authentication (moved to proxy)

2. **Nginx reverse proxy with bearer token authentication**
   - Created Dockerfile.nginx-simple for single-image deployment
   - Added nginx config with dynamic auth via entrypoint script
   - Nginx validates bearer token before proxying to WebCat
   - WebCat runs without auth on internal port 4000
   - Nginx exposes authenticated endpoint on port 8000
   - Supports optional auth: works with or without WEBCAT_API_KEY

**Testing:**
- test_mcp_no_auth.py: Tests MCP protocol with real API calls
- test_nginx_auth.py: Tests nginx auth (blocks without token, allows with token)
- All tests use real Serper API, no mocks

**Breaking Changes:**
- search_tool() now requires max_results parameter (default=5)
- Removed ctx parameter from search_tool (auth moved to nginx)
- WEBCAT_API_KEY no longer validated at tool level

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Oct 10, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Adds an nginx-authenticated deployment path for WebCat, including a single-image Dockerfile with nginx+supervisord, nginx configs, an entrypoint for runtime auth templating, Docker Compose for proxying, updated MCP server ports/paths, removal of in-app auth from search_tool, expanded tests (proxy/no-auth), and enhanced auth debug logging.

Changes

Cohort / File(s) Summary
Single-image build and runtime
docker/Dockerfile.nginx-simple, docker/supervisord.conf, docker/entrypoint-nginx.sh
New Dockerfile bundling WebCat+nginx+supervisord; supervisord runs webcat and nginx; entrypoint templates nginx auth with WEBCAT_API_KEY and starts supervisord.
Nginx configs
docker/nginx-single-image.conf, docker/nginx-auth.conf
Adds nginx configs: single-image HTTP proxy on :8000 with placeholder-based auth and health; standalone TLS proxy with Bearer check and long SSE timeouts.
Compose setup
docker/docker-compose-nginx.yml
New compose defining internal network, backend webcat service, and external nginx proxy with header-based auth and port exposure.
MCP server updates
docker/mcp_server.py
Adds run-time port/path support and explicit tool registration; clarifies auth is handled by reverse proxy; updates startup logs.
Search tool refactor
docker/tools/search_tool.py
Removes in-app auth/context, updates signature to search_tool(query, max_results=5), routes calls via fetch_with_fallback, preserves empty-result error handling.
Auth utilities logging
docker/utils/auth.py
Adds DEBUG-level logging throughout validate_bearer_token for context and header inspection; no functional changes.
Proxy/auth tests
docker/test_nginx_auth.py, docker/test_mcp_no_auth.py
New scripts to validate nginx auth behavior and no-auth MCP flow, including initialize, notifications/initialized, and tools/call with SSE parsing.
Unit tests for search
docker/tests/unit/tools/test_search_tool.py
Removes auth-related mocks/tests; updates to assert max_results propagation and behavior across search paths.
Real/port-specific tests
test_real_mcp_server.py, test_port_4001.py
Adds end-to-end scripts targeting real MCP endpoints, using Bearer headers, session setup, tools/call, and SSE result parsing.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant C as Client
  participant N as nginx proxy
  participant W as WebCat MCP Server

  rect rgb(240,248,255)
    note right of N: Startup
    N->>N: EntryPoint templates nginx.conf (WEBCAT_API_KEY)
    N->>N: Launch via supervisord (nginx + webcat)
  end

  C->>N: HTTP POST /mcp initialize (optional Authorization)
  alt Authorization provided and valid
    N->>W: Proxy request (headers, no buffering)
    W-->>N: 200 + headers (mcp-session-id)
    N-->>C: 200 + headers
  else Missing/invalid Authorization
    N-->>C: 401 { "error": "Unauthorized" }
  end

  C->>N: notifications/initialized (with session id)
  N->>W: Proxy
  W-->>N: 200
  N-->>C: 200

  C->>N: tools/call search (stream/SSE)
  N->>W: Proxy (keep-alive, long timeouts)
  W-->>N: SSE stream
  N-->>C: SSE stream
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Refactor #27 — Also changes docker/tools/search_tool.py, overlapping the signature refactor and behavior around the search tool.

Poem

I built a gate of nginx light,
Where tokens gleam in moonlit night.
WebCat purrs on port four-oh-oh-oh,
Streams of SSE softly flow.
I hop, I test, with keys in paw—
Proxy true, no ctx flaw.
Ship it fast—thump-thump—hurrah! 🐇✨

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/nginx-auth-max-results

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between adaa15d and c79aaa2.

📒 Files selected for processing (14)
  • docker/Dockerfile.nginx-simple (1 hunks)
  • docker/docker-compose-nginx.yml (1 hunks)
  • docker/entrypoint-nginx.sh (1 hunks)
  • docker/mcp_server.py (2 hunks)
  • docker/nginx-auth.conf (1 hunks)
  • docker/nginx-single-image.conf (1 hunks)
  • docker/supervisord.conf (1 hunks)
  • docker/test_mcp_no_auth.py (1 hunks)
  • docker/test_nginx_auth.py (1 hunks)
  • docker/tests/unit/tools/test_search_tool.py (4 hunks)
  • docker/tools/search_tool.py (1 hunks)
  • docker/utils/auth.py (3 hunks)
  • test_port_4001.py (1 hunks)
  • test_real_mcp_server.py (1 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

- Removed auth-related tests (auth moved to nginx)
- Added tests for max_results parameter (default and custom values)
- Updated existing tests to pass max_results parameter
- All 57 unit tests now passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@T-rav T-rav merged commit ccc585e into main Oct 10, 2025
11 checks passed
@T-rav T-rav deleted the feat/nginx-auth-max-results branch October 10, 2025 02:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants