Files
nextcloud-mcp-server/CLAUDE.md
T
2025-10-14 01:23:39 +02:00

7.1 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Development Commands

Testing

# Run all tests
uv run pytest

# Run integration tests only
uv run pytest -m integration

# Run tests with coverage
uv run pytest --cov

# Skip integration tests
uv run pytest -m "not integration"

Code Quality

# Format and lint code
uv run ruff check
uv run ruff format

# Type checking
# No explicit type checker configured - this is a Python project using ruff for linting

Running the Server

# Local development - load environment variables and run
export $(grep -v '^#' .env | xargs)
mcp run --transport sse nextcloud_mcp_server.app:mcp

# Docker development environment with Nextcloud instance
docker-compose up

# After code changes, rebuild and restart only the MCP server container
docker-compose up --build -d mcp

# Build Docker image
docker build -t nextcloud-mcp-server .

Environment Setup

# Install dependencies
uv sync

# Install development dependencies
uv sync --group dev

Architecture Overview

This is a Python MCP (Model Context Protocol) server that provides LLM integration with Nextcloud. The architecture follows a layered pattern:

Core Components

  • nextcloud_mcp_server/app.py - Main MCP server entry point using FastMCP framework
  • nextcloud_mcp_server/client/ - HTTP client implementations for different Nextcloud APIs
  • nextcloud_mcp_server/server/ - MCP tool/resource definitions that expose client functionality
  • nextcloud_mcp_server/controllers/ - Business logic controllers (e.g., notes search)

Client Architecture

  • NextcloudClient - Main orchestrating client that manages all app-specific clients
  • BaseNextcloudClient - Abstract base class providing common HTTP functionality and retry logic
  • App-specific clients: NotesClient, CalendarClient, ContactsClient, TablesClient, WebDAVClient

Server Integration

Each Nextcloud app has a corresponding server module that:

  1. Defines MCP tools using @mcp.tool() decorators
  2. Defines MCP resources using @mcp.resource() decorators
  3. Uses the context pattern to access the NextcloudClient instance

Supported Nextcloud Apps

  • Notes - Full CRUD operations and search
  • Calendar - CalDAV integration with events, recurring events, attendees
  • Contacts - CardDAV integration with address book operations
  • Tables - Row-level operations on Nextcloud Tables
  • WebDAV - Complete file system access

Key Patterns

  1. Environment-based configuration - Uses NextcloudClient.from_env() to load credentials from environment variables
  2. Async/await throughout - All operations are async using httpx
  3. Retry logic - @retry_on_429 decorator handles rate limiting
  4. Context injection - MCP context provides access to the authenticated client instance
  5. Modular design - Each Nextcloud app is isolated in its own client/server pair

Testing Structure

  • Integration tests in tests/integration/ - Test real Nextcloud API interactions
  • Fixtures in tests/conftest.py - Shared test setup and utilities
  • Tests are marked with @pytest.mark.integration for selective running
  • Important: Integration tests run against live Docker containers. After making code changes to the MCP server, rebuild only the MCP container with docker-compose up --build -d mcp before running tests

Testing Best Practices

  • MANDATORY: Always run tests after implementing features or fixing bugs
    • Run tests to completion before considering any task complete
    • If tests require modifications to pass, ask for permission before proceeding
    • Use docker-compose up --build -d mcp to rebuild MCP container after code changes
  • Use existing fixtures from tests/conftest.py to avoid duplicate setup work:
    • nc_mcp_client - MCP client session for tool/resource testing
    • nc_client - Direct NextcloudClient for setup/cleanup operations
    • temporary_note - Creates and cleans up test notes automatically
    • temporary_addressbook - Creates and cleans up test address books
    • temporary_contact - Creates and cleans up test contacts
  • Test specific functionality after changes:
    • For Notes changes: uv run pytest tests/integration/test_mcp.py -k "notes" -v
    • For specific API changes: uv run pytest tests/integration/test_notes_api.py -v
  • Avoid creating standalone test scripts - use pytest with proper fixtures instead

OAuth/OIDC Testing

OAuth integration tests support both automated (Playwright) and interactive authentication flows:

Automated Testing (Default - Recommended for CI/CD):

  • Default fixtures: nc_oauth_client, nc_mcp_oauth_client now use Playwright automation by default
  • Uses Playwright headless browser automation to complete OAuth flow programmatically
  • All Playwright fixtures: playwright_oauth_token, nc_oauth_client, nc_mcp_oauth_client, nc_oauth_client_playwright, nc_mcp_oauth_client_playwright
  • Requires: NEXTCLOUD_HOST, NEXTCLOUD_USERNAME, NEXTCLOUD_PASSWORD environment variables
  • Uses pytest-playwright-asyncio for async Playwright fixtures
  • Playwright configuration: Use pytest CLI args like --browser firefox --headed to customize
  • Install browsers: uv run playwright install firefox (or chromium, webkit)
  • Example:
    # Run all OAuth tests with automated Playwright flow using Firefox
    uv run pytest tests/integration/test_oauth*.py --browser firefox -v
    
    # Run specific Playwright tests with visible browser for debugging
    uv run pytest tests/integration/test_oauth_playwright.py --browser firefox --headed -v
    
    # Run with Chromium (default)
    uv run pytest tests/integration/test_oauth.py -v
    

Interactive Testing (Manual browser login):

  • Opens system browser and waits for manual login/authorization
  • Fixtures: interactive_oauth_token, nc_oauth_client_interactive, nc_mcp_oauth_client_interactive
  • Requires: User to complete browser-based login when prompted
  • Useful for: Debugging OAuth flows, testing with 2FA, local development
  • Automatically skipped in GitHub Actions CI - Interactive fixtures check for GITHUB_ACTIONS environment variable
  • Example:
    # Run OAuth tests with interactive flow (will open browser and wait for manual login)
    uv run pytest tests/integration/test_oauth_interactive.py -v
    

Test Environment Setup:

  • Start OAuth MCP server: docker-compose up --build -d mcp-oauth
  • OAuth server runs on port 8001 (regular MCP on 8000)
  • Both flows register OAuth clients dynamically using Nextcloud's OIDC provider

CI/CD Considerations:

  • Interactive OAuth tests are automatically skipped when GITHUB_ACTIONS environment variable is set
  • Automated Playwright tests will run in CI/CD environments
  • Use Firefox browser in CI: --browser firefox (Chromium may have issues with localhost redirects)

Configuration Files

  • pyproject.toml - Python project configuration using uv for dependency management
  • .env (from env.sample) - Environment variables for Nextcloud connection
  • docker-compose.yml - Complete development environment with Nextcloud + database