Skip to content
mattv8Public

About

Self-hosted, OpenAI-compatible RAG API + MCP server that plugs local knowledge into existing LLM clients.

Resources

Contributing

Stars

34 stars

Watchers

0 watching

Forks

Repository files navigation

Ragtime

All your tools.
All your context.

In one place.

Self-hosted, OpenAI-compatible RAG API + MCP server that plugs local knowledge into existing LLM clients.

Build Container Signed SBOM License: MIT

Contributing Guide

ragtime-promo-v2-16x9.mp4

Table of Contents

Overview

What Ragtime provides and how the main pieces fit together.

Features

  • Chat UI built in, with tool visualization, interactive charts, DataTables, and sandboxed HTML components: no external client required
  • Model providers: hosted APIs, subscription auth (OpenAI Codex, Claude Code), and local runtimes, all configurable in Settings
  • Workspaces with live previews run in isolated runtime sessions; shared links use clean public URLs (/{owner}/{slug}), with optional password-protected full-page access
  • MCP server (HTTP Streamable + stdio transports) exposing tools to Claude Desktop, VS Code Copilot, Cursor, and JetBrains IDEs with auth
  • OpenAI-compatible API /v1/chat/completions endpoint with streaming: works with OpenWebUI, Continue, and any OpenAI client
  • Dual vector store: Choose FAISS or pgvector for Upload/Git indexes; pgvector for schema/PDM and optional filesystem indexing (details)
  • Tool security: SQL injection prevention via allowlist patterns, LIMIT enforcement, Odoo code validation, optional write-ops flag

Model Providers

Configure LLM and embedding providers in the Settings UI. Chat (LLM) and embedding models can use different providers. Models are discovered live from each provider, and overlapping families (for example Anthropic API key vs Claude Code subscription) stay labeled by the provider serving them so token spend is clear.

Provider Auth Chat (LLM) Embeddings
OpenAI API key Yes Yes
OpenAI Codex ChatGPT subscription (OAuth device flow) Yes Yes
Anthropic API key Yes -
Claude Code Claude Pro/Max subscription (CLI/OAuth) Yes -
OpenRouter API key Yes Yes
OpenAI-compatible API key, if required by the endpoint Yes Yes, when supported by the endpoint
GitHub Copilot OAuth device flow or PAT Yes -
Ollama Local (self-hosted) Yes Yes
llama.cpp Local (self-hosted) Yes Yes
LM Studio Local (self-hosted) Yes Yes
oMLX Local (self-hosted) Yes Yes

Subscription-backed providers (OpenAI Codex, Claude Code) authenticate from the Settings UI without an API key. Claude Code uses the Claude Code CLI subscription and discovers the full Claude model family your plan serves.

Claude Code chat requires CLI 2.1.290 or newer. It uses your saved CLI login or CLAUDE_CODE_OAUTH_TOKEN, with Ragtime handling tool execution. Responses arrive as complete chunks rather than token-by-token. This transport supports text, not image attachments, and rejects tool schemas larger than 120,000 bytes. The legacy-CPU image retains an older CLI and does not support Claude Code chat; its other providers remain available.

Connect an OpenAI-compatible service

Security: Public generic OpenAI API model endpoints receive prompts and tool results and can influence tool calls; use only providers you trust. Ragtime shows this notice to administrators when an OpenAI-compatible provider is configured, or when an Ollama, llama.cpp, LM Studio, or oMLX chat endpoint uses a public host.

In the model-provider settings, select OpenAI-compatible, enter the service's full API base URL and API key, then fetch its models. Include the API path in the URL (for example, https://api.example.com/v1); Ragtime preserves that path and does not add /v1. Chat discovery requires a compatible /models endpoint. This connection uses the Chat Completions API for chat, streaming, and tool calls. Model and endpoint support for tools can vary. Images use Ragtime's OCR path; this provider does not enable native image input or the Responses API.

For embeddings, select OpenAI-compatible under Embedding Configuration. Chat and embeddings share the generic connection's URL, key, and provider name, but use separate model selections. Fetch embedding models or enter an exact embedding model ID to probe it through /embeddings. Only models that return valid vectors are listed. A manually entered embedding model can be checked even when the service does not expose /models.

Use the optional Provider Name to label the connection in model pickers; leaving it blank uses OpenAI-compatible. This label does not change model IDs or request routing.

Save LLM Configuration enables the selected generic chat model in an existing Chat Models allowlist while preserving the other allowed models. Use Chat Models to manage the remaining selections.

Model lists do not always include token limits. Ragtime resolves each model's context and output limits from administrator overrides, then endpoint metadata, then an exact model match in an explicitly selected models.dev catalog reference. Choose a catalog reference only when it describes your service's limits; the same model can have different limits on different services. Missing values remain unknown. Before using a model with an unknown context limit, enter its documented context limit in the per-model settings. An unknown output limit does not become an invented provider maximum; Ragtime uses the configured response budget and the known context window.

If a successful model listing omits a deployment's model ID, enter that exact ID and its documented context limit to configure it manually. Ragtime keeps these entries separate from models the endpoint explicitly identifies as non-chat models.

The generic connection has its own API key and provider-scoped model IDs (openai_compatible::model-id). Changing its base URL clears the loaded key in the form so you can enter credentials for the new endpoint. Settings API updates also clear the previous key when the URL changes unless the update supplies a replacement. API keys use the same encrypted storage and administrator-only settings access as the other providers.

Architecture

flowchart LR
  Tools["Tools<br/>(SQL, SSH, Odoo)"] -->|tool runs + results| Ragtime
  Context["Knowledge Sources<br/>(FAISS, pgvector)"] -->|retrieved context| Ragtime
  LLM["LLM Provider<br/>(OpenAI, Anthropic, Ollama, llama.cpp, LM Studio)"] -->|LLM API| Ragtime

  subgraph Ragtime["Ragtime"]
    direction TB
    API["/v1/chat/completions"]
    MCP["/mcp"]
    UI["Web UI"]
  end

  Ragtime -->|chat responses| Clients["Clients<br/>(OpenWebUI, Claude, VS Code)"]
  Clients -->|chat queries| Ragtime

  style Ragtime fill:#1a365d,stroke:#3182ce,stroke-width:3px,color:#fff
Loading

Quick Start

Prerequisites

  • Docker and Docker Compose
  • A .env file with your configuration

Setup

  1. Create .env:

    Copy .env.example to .env. The expanded block below is CI-checked against .env.example, so future edits should go there instead of the README snippet:

    Click to expand .env template
    # =============================================================================
    # Ragtime RAG API - Environment Configuration
    # =============================================================================
    # Copy this file to .env and fill in your values
    
    # -----------------------------------------------------------------------------
    # Database Configuration
    # -----------------------------------------------------------------------------
    # PostgreSQL password (used by both database container and ragtime)
    POSTGRES_PASSWORD=changeme
    
    # -----------------------------------------------------------------------------
    # Authentication Configuration
    # -----------------------------------------------------------------------------
    # Local admin account credentials
    LOCAL_ADMIN_USER=admin
    LOCAL_ADMIN_PASSWORD=changeme_admin
    
    # Optional comma-separated OAuth callback URLs to trust in addition to built-in
    # loopback/IDE callback handling.
    # OAUTH_TRUSTED_REDIRECT_URIS=https://example-1/oauth/callback,https://example-2/oauth/callback
    
    # -----------------------------------------------------------------------------
    # Server Configuration
    # -----------------------------------------------------------------------------
    # API port (default: 8000)
    PORT=8000
    
    # CORS allowed origins (comma-separated)
    # Leave empty to allow loopback-only origins.
    # Example: https://ragtime.example.com,https://chat.example.com
    ALLOWED_ORIGINS=
    
    # Canonical public Ragtime origin (scheme + host, no trailing slash), for example:
    # https://ragtime.example.com
    # Set it only when Ragtime sees a different origin than users do
    # (for example behind TLS termination) or public URLs must stay fixed.
    # EXTERNAL_BASE_URL=https://ragtime.example.com
    
    # Optional preview base-domain override for userspace subdomain previews.
    # Leave unset to derive preview hosts from the current Ragtime origin
    # (for example https://ragtime.example.com -> https://<workspace>.ragtime.example.com).
    # Set this when previews should use a separate wildcard host family such as
    # example-userspaces.com. Wildcard DNS/TLS must route *.example-userspaces.com
    # back to Ragtime.
    # USERSPACE_PREVIEW_BASE_DOMAIN=example-userspaces.com
    
    # -----------------------------------------------------------------------------
    # Security Configuration
    # -----------------------------------------------------------------------------
    # API Key for OpenAI-compatible endpoint authentication (strongly recommended
    # for non-local deployments)
    # Generate with: openssl rand -base64 32
    API_KEY=
    
    # Ragtime manages its own encryption key at /data/.encryption_key.
    # Keep that managed file recoverable through your data backups if you need to
    # restore encrypted API keys and connection passwords later.
    
    # Optional GitHub OAuth App client ID for GitHub Copilot device auth flow.
    # If not set, Ragtime falls back to the built-in default client id.
    # Create your own OAuth app to control consent screen branding (e.g., app name "Ragtime").
    # Note: this is the Client ID only (not the Client Secret).
    # GITHUB_COPILOT_CLIENT_ID=Ovxxxxxxxxxxxxxxxxxx
    
    # Optional OAuth apps for SharePoint/OneDrive and Google Drive userspace mounts.
    # Microsoft client ID/secret: https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade
    # Microsoft tenant ID: use the Azure Directory (tenant) ID or primary tenant domain for single-tenant app registrations.
    # Microsoft Graph delegated permissions for read/write mounts: offline_access, User.Read, Files.ReadWrite.All, Sites.ReadWrite.All. Admin consent may be required.
    # Google client ID/secret: https://console.cloud.google.com/apis/credentials
    # Google API library: enable Google Drive API (drive.googleapis.com) for the same project as the OAuth client.
    # Google OAuth consent screen scopes for read/write mounts: https://www.googleapis.com/auth/drive and https://www.googleapis.com/auth/userinfo.email
    # CLOUD_MOUNT_MICROSOFT_CLIENT_ID=
    # CLOUD_MOUNT_MICROSOFT_CLIENT_SECRET=
    # CLOUD_MOUNT_MICROSOFT_TENANT_ID=
    # CLOUD_MOUNT_GOOGLE_CLIENT_ID=
    # CLOUD_MOUNT_GOOGLE_CLIENT_SECRET=
    
    # HTTPS: Enable built-in TLS with self-signed certificate (auto-generated on first run)
    # To use your own certs, place them at ./data/ssl/server.crt and ./data/ssl/server.key
    # ENABLE_HTTPS=true
    
    # Set to true if behind an HTTPS reverse proxy (nginx, Caddy, Traefik)
    # This marks cookies as Secure. Auto-enabled when ENABLE_HTTPS=true.
    SESSION_COOKIE_SECURE=false
    
    # -----------------------------------------------------------------------------
    # Runtime Configuration
    # -----------------------------------------------------------------------------
    
    # Base URL Ragtime uses for outbound calls to the runtime-manager API that
    # creates and controls userspace runtime sessions. In the default Docker setup,
    # this should stay pointed at the internal runtime service.
    # Set to blank/non-http to force local placeholder runtime mode.
    # RUNTIME_MANAGER_URL=http://runtime:8090
    
    # Internal Ragtime URL for User Space runtime workers.
    # Set only for remote/custom runtime networks where automatic discovery cannot reach Ragtime.
    # RUNTIME_BRIDGE_BASE_URL=http://ragtime:8000
    
    # Shared bearer token for Ragtime <-> runtime service calls. If unset, User
    # Space runtime features stay disabled and admins see a security warning in
    # the UI. Generate with: openssl rand -base64 32
    RUNTIME_AUTH_TOKEN=
    
    # Maximum concurrent runtime sessions in running/starting state (default: 12)
    # RUNTIME_MAX_SESSIONS=12
    
    # Optional override for concurrent workspace startup/bootstrap operations per
    # runtime worker. By default, the worker sizes this automatically from runtime
    # namespace isolation, CPU, memory, and session capacity.
    # RUNTIME_STARTUP_CONCURRENCY=
    
    # Chat web search uses the bundled internal SearXNG service by default.
    # Set TAVILY_API_KEY to use Tavily instead (get a key at https://app.tavily.com/home).
    # TAVILY_API_KEY=
    
    ############################################################
    # Developer Only - Typically do not modify below this line #
    ############################################################
    
    # Debug mode (enables verbose logging and hot-reload)
    DEBUG_MODE=false
    
    # Database URL (auto-configured by docker-compose, override for external DB)
    # DATABASE_URL=postgresql://ragtime:password@hostname:5432/ragtime
  2. Edit .env with your actual values.

  3. Create docker-compose.yml if you want the standalone self-hosted compose setup shown below:

    Click to expand docker-compose.yml
    # =============================================================================
    # Ragtime - Self-Hosted Docker Compose
    # =============================================================================
    # For self-hosted deployment. See README.md for setup instructions.
    #
    # Usage:
    #   1. Create .env file with your configuration
    #   2. docker compose up -d
    #   3. Access at http://localhost:${PORT:-8000}
    
    services:
      # PostgreSQL database for Prisma persistence
      ragtime-db:
        image: pgvector/pgvector:pg18
        container_name: ragtime-db
        restart: unless-stopped
        environment:
          POSTGRES_USER: ragtime
          POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
          POSTGRES_DB: ragtime
        volumes:
          - ragtime-db-data:/var/lib/postgresql
        networks:
          - ragtime-network
        healthcheck:
          test: ["CMD-SHELL", "pg_isready -U ragtime -d ragtime"]
          interval: 10s
          timeout: 5s
          retries: 5
    
      searxng:
        image: ghcr.io/searxng/searxng:latest
        container_name: searxng
        restart: unless-stopped
        environment:
          SEARXNG_BASE_URL: http://searxng:8080/
          SEARXNG_SECRET: ${SEARXNG_SECRET:-ragtime-internal-searxng}
        configs:
          - source: searxng-settings
            target: /etc/searxng/settings.yml
        volumes:
          - searxng-cache:/var/cache/searxng
        networks:
          - ragtime-network
        healthcheck:
          test:
            [
              "CMD",
              "python",
              "-c",
              "import urllib.request; urllib.request.urlopen('http://localhost:8080/healthz', timeout=5).read()",
            ]
          interval: 30s
          timeout: 10s
          retries: 5
          start_period: 10s
    
      # Ragtime RAG API
      ragtime:
        # For older CPUs without X86_V2 support, use the legacy tag:
        # image: hub.docker.visnovsky.us/library/ragtime:legacy
        image: hub.docker.visnovsky.us/library/ragtime:main
        container_name: ragtime
        restart: unless-stopped
        ports:
          - "${PORT:-8000}:8000"
        env_file:
          - .env
        environment:
          # Database connection (uses container network)
          DATABASE_URL: postgresql://ragtime:${POSTGRES_PASSWORD}@ragtime-db:5432/ragtime
          # Recommended defaults
          DEBUG_MODE: "false"
          RUNTIME_MANAGER_URL: ${RUNTIME_MANAGER_URL:-http://runtime:8090}
          RUNTIME_BRIDGE_BASE_URL: ${RUNTIME_BRIDGE_BASE_URL:-}
          # Shared Ragtime <-> runtime token. If unset, User Space runtime features
          # stay disabled and admins see a security warning in the UI.
          RUNTIME_AUTH_TOKEN: ${RUNTIME_AUTH_TOKEN:-}
          OBJECT_STORAGE_ENDPOINT: ${OBJECT_STORAGE_ENDPOINT:-http://runtime-s3:9000}
          OBJECT_STORAGE_CONTROL_URL: ${OBJECT_STORAGE_CONTROL_URL:-http://runtime-s3:9001}
        volumes:
          # Data persistence (indexes, SSL certs, etc.)
          - ./data:/data
          - keystore:/run/ragtime-keystore
          # Optional: mount docker.sock only if you need Docker tool execution.
          # The Docker API can control the host even when the socket is mounted read-only.
          # - /var/run/docker.sock:/var/run/docker.sock:ro
          # Optional: host SMB/NFS shares. Bind the parent directory with rslave,
          # never the share mountpoint itself; a share that is down at boot then
          # cannot stop the container from starting. See README "Docker & Mounts".
          # - /mnt/shares:/mnt/shares:rslave
        security_opt:
          - no-new-privileges:true
        # Uncomment below if using SMB/NFS mounting inside container (consider mounting via docker volume instead)
        # privileged: true
        # cap_add:
        #   - SYS_ADMIN
        networks:
          - ragtime-network
        depends_on:
          ragtime-db:
            condition: service_healthy
          runtime:
            condition: service_healthy
          searxng:
            condition: service_healthy
        healthcheck:
          # Verify the API and both required runtime-s3 listeners after startup.
          test: ["CMD-SHELL", "if [ \"$${ENABLE_HTTPS:-false}\" = \"true\" ]; then curl -fsk --max-time 2 -o /dev/null https://localhost:8000/health; else curl -fs --max-time 2 -o /dev/null http://localhost:8000/health; fi && curl -fsS --max-time 2 -o /dev/null \"$${OBJECT_STORAGE_CONTROL_URL:-http://runtime-s3:9001}/health\" && curl -sS --max-time 2 -o /dev/null \"$${OBJECT_STORAGE_ENDPOINT:-http://runtime-s3:9000}\""]
          interval: 30s
          timeout: 10s
          retries: 3
          # Initial settings creation publishes the storage encryption key.
          start_period: 5m
    
      # Internal, persistent workspace S3 gateway. It waits for Ragtime's managed
      # encryption key and intentionally has no host-published ports.
      runtime-s3:
        image: hub.docker.visnovsky.us/library/ragtime-storage:main
        container_name: runtime-s3
        restart: unless-stopped
        volumes:
          - ./data/_userspace/_object_storage:/data/_userspace/_object_storage
          - keystore:/run/ragtime-keystore:ro
        networks:
          - ragtime-network
        depends_on:
          ragtime:
            # Start after Ragtime begins so it can publish the key; Ragtime health
            # checks this gateway's readiness, so waiting for healthy would cycle.
            condition: service_started
        healthcheck:
          # Make the image's control/S3 listener check explicit for Compose users.
          # A 403 from the unauthenticated S3 listener is a valid reachability result.
          test: ["CMD-SHELL", "curl -fsS --max-time 2 -o /dev/null \"http://localhost:$${STORAGE_CONTROL_PORT}/health\" && curl -sS --max-time 2 -o /dev/null \"http://localhost:$${S3_PORT}\""]
          interval: 30s
          timeout: 10s
          retries: 3
          # Allow Ragtime's key bootstrap and the gateway's startup wait.
          start_period: 5m
    
      runtime:
        image: hub.docker.visnovsky.us/library/runtime:main
        container_name: runtime
        restart: unless-stopped
        environment:
          PORT: "8090"
          RUNTIME_SERVICE_MODE: manager
          # Shared Ragtime <-> runtime token. If unset, User Space runtime features
          # stay disabled and admins see a security warning in the UI.
          RUNTIME_AUTH_TOKEN: ${RUNTIME_AUTH_TOKEN:-}
          RUNTIME_WORKER_BASE_URL: ${RUNTIME_WORKER_BASE_URL:-http://runtime:8090}
          RUNTIME_WORKSPACE_ROOT: ${RUNTIME_WORKSPACE_ROOT:-/data/_userspace}
          RUNTIME_MAX_SESSIONS: ${RUNTIME_MAX_SESSIONS:-12}
          RUNTIME_STARTUP_CONCURRENCY: ${RUNTIME_STARTUP_CONCURRENCY:-}
          RUNTIME_LEASE_TTL_SECONDS: ${RUNTIME_LEASE_TTL_SECONDS:-3600}
          RUNTIME_RECONCILE_INTERVAL_SECONDS: ${RUNTIME_RECONCILE_INTERVAL_SECONDS:-15}
        volumes:
          - ./data:/data
          # Optional: host SMB/NFS shares for User Space; same parent-bind pattern as ragtime.
          # - /mnt/shares:/mnt/shares:rslave
        security_opt:
          - no-new-privileges:true
        # Uncomment below to enable full runtime sandbox isolation when the host
        # permits mount and PID namespaces (otherwise runtime falls back to chroot).
        # privileged: true
        # cap_add:
        #   - SYS_ADMIN
        networks:
          - ragtime-network
        healthcheck:
          test: ["CMD", "curl", "-fs", "http://localhost:8090/health"]
          interval: 30s
          timeout: 10s
          retries: 3
          start_period: 5s
    
    networks:
      ragtime-network:
        driver: bridge
    
    configs:
      searxng-settings:
        content: |
          use_default_settings: true
    
          search:
            formats:
              - html
              - json
    
    volumes:
      ragtime-db-data:
      searxng-cache:
      keystore:

    Note: Ragtime configuration variables are loaded from the .env file via env_file. The ragtime.environment section only overrides values that should use the internal container network.

    Runtime mode compatibility: pivot_root with CAP_SYS_ADMIN is the preferred steady-state runtime mode. If the runtime starts without mount authority, Ragtime falls back to a chroot compatibility mode that mirrors workspace files into the sandbox. Switching an existing workspace fleet from chroot fallback to full isolation is supported, but should be treated as a one-time migration event. Transitioning between chroot and pivot_root can cause loss of snapshot history! It is recommended to take a full backup before transitioning.

    Upgrading an existing deployment to the file-only bridge credential and keystore layout? Follow the safe cutover guide.

    SQLite history host requirement: Workspace SQLite history capture requires Landlock ABI 3 or newer, enabled and accessible inside the Ragtime container. ABI 3 is available in upstream Linux 6.2 and newer; Linux 6.1 provides ABI 2. An unsupported host cannot capture SQLite history safely. Updating only the container image does not update the host kernel.

  4. Start the application:

    docker compose up -d

    The database, searxng, and runtime start in parallel. Ragtime waits until all three are healthy, then publishes the encryption key needed by runtime-s3. Storage starts after Ragtime's container starts; Ragtime's healthcheck requires its API and both storage endpoints to respond. The detached up -d command starts this sequence in the background. Use docker compose ps to see each service's health as startup progresses.

  5. Access the application:

    Default credentials: admin / (set via LOCAL_ADMIN_PASSWORD in .env)

Post-Install Setup

After the stack is running, configure the capabilities Ragtime will expose.

Tool Configuration

Screenshot 2

Configure tools in the Ragtime web UI before connecting MCP clients. Enabled tools are available to chat; MCP exposure additionally applies heartbeat health filtering.

  1. Open the web UI at http://localhost:8000 and log in with your admin account.
  2. Navigate to the Tools tab.
  3. Click Add Tool and select the tool type (PostgreSQL, Odoo, SSH, filesystem indexer, etc.).
  4. Fill in connection details (hostnames, credentials, database names, paths) for each tool.
  5. Use the built-in test button to verify each tool connection.

Once the required tools are healthy, continue with MCP Integration.

Creating Indexes

The Indexer UI (http://localhost:8000, Indexes tab) supports multiple index types (see Vector Store Abstraction for backend details):

Method Vector Store Storage Use Case
Upload (zip/tar) FAISS or pgvector FAISS: data/indexes/<name>/
pgvector: filesystem_embeddings table
Static codebases, documentation snapshots
Git Clone FAISS or pgvector FAISS: data/indexes/<name>/
pgvector: filesystem_embeddings table
Repositories with optional private token auth
Filesystem FAISS or pgvector FAISS: data/indexes/<name>/
pgvector: filesystem_embeddings table
Live SMB/NFS shares, Docker volumes, local paths: incremental re-index
Schema pgvector schema_embeddings table Auto-generated from PostgreSQL/MSSQL/MySQL tools (enable in Tool Configuration)
PDM pgvector pdm_embeddings table Configuration-aware checked-in SolidWorks PDM metadata via SQL Server, including per-value origin versions.

Jobs run async with progress streaming to the UI.

Preview DNS Setup (Reverse Proxy Deployments)

This step configures the wildcard DNS and proxy routing required for workspace live previews (see Workspaces for conceptual details).

  1. Choose a preview base domain: Ragtime defaults to prepending the workspace name to its public origin (e.g., https://ragtime.example.com -> https://<workspace>.ragtime.example.com). To use a separate wildcard domain, set USERSPACE_PREVIEW_BASE_DOMAIN=example-userspaces.com.
  2. Add a wildcard DNS record for the chosen domain pointing to your Ragtime entrypoint.
  3. Configure your reverse proxy to route these wildcard requests to Ragtime and ensure TLS certificates cover them.
  4. Update .env (only if needed):
EXTERNAL_BASE_URL=https://ragtime.example.com
USERSPACE_PREVIEW_BASE_DOMAIN=example-userspaces.com

Notes:

  • Set EXTERNAL_BASE_URL only if Ragtime sees a different origin than users do (e.g., behind TLS termination), or to pin public URLs to a canonical host.
  • Keep SESSION_COOKIE_SECURE=true when traffic is HTTPS at the edge.
  • Forward Host and X-Forwarded-Proto headers through the proxy.
  • In local development (DEBUG_MODE=true), previews automatically use userspace-preview.lvh.me.

Concepts

Core concepts that affect how Ragtime is deployed and used.

Workspaces

Workspaces combine files, conversations, selected infrastructure tools, and an isolated runtime preview session in one agentic sandbox. They are Replit-like, but wired into Ragtime's tools and indexed context so agents can work against live systems.

  • Public sharing uses direct routes (/{owner}/{slug} and /shared/{token}) which launch shared previews.
  • Password-protected shares are handled server-side with a full-page prompt.
  • When the runtime lacks CAP_SYS_ADMIN, previews run in a chroot compatibility mode instead of full pivot_root isolation. Transitioning between chroot and pivot_root can cause loss of snapshot history! It is recommended to take a full backup before transitioning.

Agent Collaboration

Workspace owners and admins can open Share Workspace > Agent Collaboration, enable agent access, and copy the generated instructions into Claude Cowork, Codex, ChatGPT, or another compatible agent to collaborate on the workspace.

Use Your Own Coding Agent

Ragtime can provide the workspace control plane while an external agent harness (Claude Desktop, Codex, OpenCode, etc.) supplies reasoning.

Chat and User Space AI generation are independently controlled:

  • Settings > Chat > Enable chat: Default for Chat UI generation (titles, responses, background inference). Default: on. Administrators can set each user's Chat policy in Users > User policies to use the default, enable it, or disable it. An enabled user override works even when the global default is off.
  • Settings > User Space > Enable User Space AI generation: Default for workspace generation and build tasks. Default: on. Administrators can set each user's User Space policy in Users > User policies to use the default, enable it, or disable it. An enabled user override works even when the global default is off.
  • Administrator self-management: Administrators can manage their own Chat and User Space generation overrides through Users > User policies. Existing enabled overrides become active immediately after this behavior is deployed, including when the corresponding global default is off.
  • External API (/v1/chat/completions): Always available independently of both switches. All existing auth, content-protection policies, and credential restrictions remain in place.
  • External harness scope: When User Space AI generation is off, Ragtime does not generate workspace content or handle build tasks; however, file access, runtime execution, index retrieval, and provider-backed embeddings for indexing remain available to the harness and external tools.
Connect a coding agent
  1. Enable MCP in Settings when using the MCP connection.
  2. As a workspace owner or admin, open Share Workspace > Coding Agent Setup, name and create a development credential, then click Copy Instructions. Rotate an existing credential if its original token is no longer available.
  3. Paste the instructions into your trusted external agent. It authenticates to the bootstrap API, selects its client profile, downloads and verifies the required files, and merges the local configuration while preserving user rules and provider settings.
  4. Start a new client session if requested. The agent verifies its MCP connection and retrieves the workspace context before working.

Profiles are provided for OpenCode, Claude Code, and Codex. The manifest supplies exact destinations, checksums, merge instructions, and the workspace-specific credential environment variable. Credentials belong in a private launch environment or secret store, outside project files and version control.

A short rules file stays in the client's instruction context. Native skills carry the detailed platform guidance, while MCP provides fresh workspace facts and authorized tool contracts. Clients without native skill support can retrieve that guidance through bounded MCP readers.

Refresh live context as workspace state changes. Reinstall downloaded assets when their manifest revision changes. Paged readers use each target document's SHA-256 and returned byte offset; the overall context_revision is a change indicator, not a document hash.

Development API

The copied setup instructions point to GET /indexes/userspace/development/workspaces/{workspace_id}/bootstrap. Its authenticated manifest advertises the asset download URLs and client profiles. Tokens are supplied through an Authorization: Bearer header and are never embedded in downloaded configuration files.

The /mcp connection exposes compact context, resource discovery, paged instructions/contracts, and development operations. The existing full HTTP /context and /operations endpoints under the same workspace prefix remain available for downloads and programmatic clients. Credential creation, rotation, and revocation require an owner/admin session; development credentials authorize only their scoped workspace-development HTTP and MCP access.

File writes and patches require the current content hash. Exec jobs have bounded concurrency and output retention. Selected SSH connections are available only through the workspace_development wrapper: ssh_execute requires both exec and write credential scopes, while an exec-only credential can download a permitted SSH file with ssh_transfer but cannot mutate remote or workspace destinations. Transfer contracts bind workspace:/ paths to the enclosing workspace; workspace destinations use expected_content_hash for create-only or compare-and-swap replacement and never take an inner workspace_id. Inline SSH results are capped at 24 KiB serialized UTF-8 JSON without silent truncation; use workspace files for larger text and SSH-to-SSH for larger binary transfers. The hidden workspace code index is available by default; other indexes require an owner grant and retain backing-tool access checks. Development credentials are rejected from Chat generation, User Space generation, built-in API key management, and other credential-surface operations; they are exclusively scoped to workspace development access.

Vector Store Abstraction

Ragtime uses two vector backends: FAISS (in-memory, loaded at startup) and pgvector (PostgreSQL, persistent). Upload, Git, and Filesystem indexes can use either backend.

See Creating Indexes for a detailed breakdown of index types and their storage backends.

FAISS indexes are loaded into memory at startup; pgvector indexes stay in PostgreSQL and use cosine similarity search. Embedding provider (OpenAI, Ollama, llama.cpp, or LM Studio) is configured once in Settings and applies to all index types. Swapping embedding model or dimensions after initial indexing requires a full re-index.

Integrations

How to connect external clients and coding assistants to Ragtime.

Model Context Protocol (MCP) Integration

Ragtime exposes its tools via the Model Context Protocol, allowing AI coding assistants to interact with your databases, execute shell commands, and search your indexed codebases.

By default, MCP is disabled until you enable it in Settings. If disabled, /mcp responds with HTTP 503. For security and authentication rules, see Network & Access.

Available MCP Tools

Tools are dynamically exposed based on what you configure in the UI. The schemas below list the primary fields; several tools also accept optional fields such as timeout.

Tool Type Input Schema
postgres {query, reason}
mssql {query, reason}
mysql {query, reason}
influxdb {query, reason}
odoo_shell {code, reason}
ssh_shell {command, reason}
ssh_transfer {source, destination, content?, encoding?, overwrite?, recursive?, reason?, timeout?, workspace_id?}; copies between authorized SSH connections, inline content, and workspace text files.
filesystem_indexer {query, max_results}
solidworks_pdm search_{tool}: {query, document_type}; Chat also provides lookup_{tool} for exact indexed-snapshot lookup.
knowledge_search {query, index_name}
schema_search {prompt, limit}
git_history {action, ...}

MCP Server Setup

HTTP Transport (Recommended)

Ragtime exposes an MCP endpoint at /mcp that supports the Streamable HTTP transport. Add this to your MCP client configuration:

{
	"servers": {
		"ragtime": {
			"url": "http://localhost:8000/mcp",
			"type": "http",
      // If you've enabled MCP authentication in the Ragtime Settings UI (Settings > MCP Configuration), add headers for your configured auth method.
      // Password mode supports either `MCP-Password` or `Authorization: Bearer <password>`:
			// "headers": {
      //   "MCP-Password": "your-mcp-password-here"
      //   // or: "Authorization": "Bearer your-mcp-password-here"
			// }
		}
	},
	"inputs": []
}

NOTE: For remote access, replace localhost:8000 with your server URL.

Stdio Transport (Alternative)

For local development or environments where HTTP isn't preferred, use stdio transport via Docker:

{
  "mcpServers": {
    "ragtime": {
      "command": "docker",
      "args": ["exec", "-i", "ragtime", "python", "-m", "ragtime.mcp"]
    }
  }
}

Replace ragtime with your container name if different (find it with docker ps).

Configuration file locations:

  • Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows)
  • VS Code / Copilot: User or workspace MCP settings
  • Cursor: .cursor/mcp.json
  • Windsurf: ~/.codeium/windsurf/mcp_config.json

Connecting to OpenWebUI

  1. In OpenWebUI, go to Settings > Connections > OpenAI API
  2. Add a new connection:
    • API Base URL: http://ragtime:8000/v1 (or http://localhost:8000/v1 if running locally)
    • API Key: Your configured API_KEY (see Network & Access) (or any value if not set)
  3. Select your server's model name (default: "ragtime", configurable in Settings > Server Branding)

Operations

Security, maintenance, and troubleshooting guidance for self-hosted deployments.

Security

Ragtime is designed for self-hosted deployment on trusted networks. Review these recommendations before exposing it beyond localhost:

Pushes to the beta and main branches trigger packaging workflows that build, sign, and publish images. The main-branch images are Cosign-signed and ship with an SPDX SBOM artifact (linked from the badges above and workflow runs) so you can verify what you pull from the registry. Pull requests run validation only and do not publish images.

Network & Access

  • Run behind a reverse proxy or firewall. Avoid exposing port 8000 directly to the public internet.
  • Set API_KEY to protect the /v1/chat/completions endpoint. When unset (the default), anyone with network access can call the chat API and invoke your configured tools.
  • Restrict ALLOWED_ORIGINS to trusted domains. The application default is loopback-only when unset; avoid using * in network-accessible deployments because it is permissive with allow_credentials=True.
  • Enable MCP route authentication via Settings UI if /mcp is network-accessible. MCP is disabled by default; when MCP is enabled, the default route is open unless you turn on route authentication.
  • MCP authentication supports password-based headers (including MCP-Password and bearer form) and OAuth2/client_credentials route modes.
  • Protect workspace external-agent URLs. These URLs contain revocable bearer tokens. Use them only in private sessions with trusted agents, keep them out of generated files and public issue trackers, and rotate or disable a URL when access is no longer needed.
  • Set a strong LOCAL_ADMIN_PASSWORD when deploying.
  • Review trusted external redirects carefully. OAuth callbacks and other external redirect allowlists should only include destinations you control. Redirecting users to third-party domains can expose authorization codes, tokens, or sensitive workflow context if those destinations are compromised or misconfigured.

Authentication Security

  • Encryption key is managed automatically on first startup and stored in the data volume as .encryption_key so sessions and encrypted settings survive restarts. Plain backups do not carry that file. If you need a backup that can restore encrypted API keys and connection passwords, create an encrypted backup with --include-secret so the managed key stays inside ciphertext, or otherwise preserve the .encryption_key file separately.
  • Rate limiting protects the login endpoint (5 attempts/minute per IP) to prevent brute-force attacks. In DEBUG_MODE=true, rate limiting is disabled for local testing.

Debug Mode Warning

Do not use DEBUG_MODE=true outside local development. When enabled, the /auth/status endpoint exposes your admin username and password in plaintext (including unauthenticated callers). This is intentional for self-hosted debugging but dangerous if the server is accessible to untrusted users.

SSH Connections

The SSH tool uses Paramiko with AutoAddPolicy, which accepts any host key without verification. This makes SSH connections vulnerable to man-in-the-middle attacks on first connect. Only use the SSH tool on trusted networks or with hosts you have verified out-of-band.

Tool Read-Only Mode

Tool read-only mode is a guardrail, not complete isolation. Validators reduce common write paths, but they cannot make broad database, SSH, shell, or Odoo credentials safe against every bypass or misconfiguration. Use least-privileged credentials, read-only database roles and transactions, OS/container sandboxing, restricted SSH users, timeouts, audit logs, and network/firewall boundaries for any tool reachable by agents.

Docker & Mounts

  • The default compose files include mounts for docker.sock and optional privileged flags to support advanced tool features (container exec, SSH tunnels, NFS/SMB mounts).
  • If you do not need these features, remove or comment out the corresponding lines in your compose file.
  • For NFS/SMB filesystem indexing, the container may require elevated privileges. Consider the security implications before enabling privileged: true or SYS_ADMIN capabilities.
  • Filesystem sources attached to User Space workspaces only need to be mounted into the runtime container (the ragtime container does not need to see the source). The runtime container also needs mount authority (privileged: true or cap_add: [SYS_ADMIN]) so it can bind-mount the source into the workspace sandbox without copying or changing source permissions. Filesystem sources used purely for indexing only need to be mounted into the ragtime container; mount them in both services if the same source is used for both indexing and User Space workspaces.
  • If a source is a host-mounted SMB/NFS share, bind its parent directory with rslave propagation instead of the share mountpoint itself, for example /mnt/shares:/mnt/shares:rslave with the share mounted on the host at /mnt/shares/Accounting. Docker refuses to create a container whose bind source is a failed mount (error mounting ... no such device) and does not retry, so binding the share directly can keep Ragtime or Runtime down after a reboot. With a parent bind, the containers start even when a share is down, and the share appears inside them as soon as the host mounts it again.
    • Mount shares on the host with x-systemd.automount (plus _netdev,nofail) in /etc/fstab. Ragtime checks host shares every minute; accessing an idle or failed automount retriggers the host mount, so many outages recover automatically. Because of these checks, automount idle timeouts no longer unmount shares that Ragtime can see.
    • When a share stays unavailable or stops responding, admins see a Host Mount Unavailable banner (with a Check again action) and other users see a generic storage notice. Restore the share on the Docker host (for example sudo systemctl start mnt-shares-Accounting.mount), then select Check again. Restart any User Space workspace that still cannot see the share.
    • The parent bind exposes everything under that directory, so use a dedicated parent for shares rather than /mnt when other mounts live there. Propagation requires a Linux Docker host with shared mount propagation on / (the systemd default); Docker Desktop does not support it.

Third-Party Data Relay

Queries and tool calls may forward your data to external services you configure (OpenAI, Anthropic, Ollama, llama.cpp, LM Studio, PostgreSQL, MSSQL, SSH hosts). Only connect to services you trust with your data.

Updating

To update to the latest version:

docker compose pull
docker compose up -d

Release channels

The default Compose images follow the stable main channel. Stable aliases main and latest remain moving tags; development aliases are beta and latest-beta. For a repeatable deployment, pin the Ragtime, runtime, and storage images to the same release tag, vX.Y.Z. The older-CPU Ragtime image uses the matching vX.Y.Z-legacy tag. Image digests identify the exact bytes when a deployment requires stronger pinning than a tag.

Stable release PRs are prepared automatically each Tuesday at 09:17 UTC and are merged manually. See the release promotion procedure in CONTRIBUTING.md for maintainer operations, including retries and version selection.

Troubleshooting

SSH Tools Fail from Colima on macOS but Hosts Are Reachable

SSH checks run from inside the Colima VM, so macOS-reachable hosts may still fail if Colima's user-mode networking is stale. To confirm, test TCP connectivity from each layer:

nc -vz -w 3 <HOST_IP> 22                                                                      # macOS
colima ssh -- bash -lc 'timeout 4 bash -lc "</dev/tcp/<HOST_IP>/22" && echo open || echo failed'  # Colima VM
docker exec ragtime-dev bash -lc 'timeout 4 bash -lc "</dev/tcp/<HOST_IP>/22" && echo open || echo failed'  # container

If only macOS can connect, restart Colima and the stack:

colima stop && colima start
docker compose -f docker/docker-compose.dev.yml up --build

If the problem persists, kill stale Lima usernet helpers: ps ax | grep 'limactl usernet' and keep only the PID in ~/.colima/_lima/_networks/user-v2/usernet_user-v2.pid.

NumPy CPU Compatibility Error

If you see an error like:

RuntimeError: NumPy was built with baseline optimizations (X86_V2) but your machine doesn't support (X86_V2)

Your CPU lacks the X86_V2 instruction set required by modern NumPy binaries. Use the legacy image instead:

image: hub.docker.visnovsky.us/library/ragtime:legacy

This image pins CPU-sensitive native dependencies, including NumPy and FAISS, to versions compatible with older virtual CPU profiles.

Contributing

See CONTRIBUTING.md for development setup, making changes, and CI/CD details.

License

MIT: see LICENSE.

About

Self-hosted, OpenAI-compatible RAG API + MCP server that plugs local knowledge into existing LLM clients.

Resources

Contributing

Stars

34 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages