Ctrl K
ComunidadGuías…

compose.yml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
services:
  serverfs-mcp:
    build:
      context: .
    # `image` doubles as the tag `docker compose build` writes to, so a bare
    # build under a pinned production .env (SERVERFS_IMAGE=...:<release>) would
    # point that release tag at locally built code. Build under a scratch tag
    # instead: `SERVERFS_IMAGE=serverfs-mcp:dev docker compose build`.
    image: ${SERVERFS_IMAGE:-ghcr.io/ntlx/serverfs_mcp:latest}

    restart: unless-stopped

    user: "${SERVERFS_UID:-10001}:${SERVERFS_GID:-10001}"

    environment:
      TZ: ${TZ:-Asia/Shanghai}

      SERVERFS_LOG_LEVEL: ${SERVERFS_LOG_LEVEL:-INFO}

      SERVERFS_HTTP_HOST: ${SERVERFS_HTTP_HOST:-0.0.0.0}
      SERVERFS_HTTP_PORT: ${SERVERFS_HTTP_PORT:-8000}
      SERVERFS_HTTP_PATH: ${SERVERFS_HTTP_PATH:-/mcp}
      SERVERFS_HTTP_ALLOWED_HOSTS: ${SERVERFS_HTTP_ALLOWED_HOSTS:-}
      SERVERFS_HTTP_ALLOWED_ORIGINS: ${SERVERFS_HTTP_ALLOWED_ORIGINS:-}
      SERVERFS_HTTP_API_KEY: ${SERVERFS_HTTP_API_KEY:-}

      SERVERFS_MAX_READ_BYTES: ${SERVERFS_MAX_READ_BYTES:-524288}
      SERVERFS_MAX_READ_LINES: ${SERVERFS_MAX_READ_LINES:-500}

      SERVERFS_DEFAULT_LIST_LIMIT: ${SERVERFS_DEFAULT_LIST_LIMIT:-100}
      SERVERFS_MAX_LIST_ENTRIES: ${SERVERFS_MAX_LIST_ENTRIES:-500}

      SERVERFS_DEFAULT_SEARCH_RESULTS: ${SERVERFS_DEFAULT_SEARCH_RESULTS:-50}
      SERVERFS_MAX_SEARCH_RESULTS: ${SERVERFS_MAX_SEARCH_RESULTS:-100}

      SERVERFS_MAX_WALK_ENTRIES: ${SERVERFS_MAX_WALK_ENTRIES:-200000}
      SERVERFS_SEARCH_TIMEOUT_SECONDS: ${SERVERFS_SEARCH_TIMEOUT_SECONDS:-15}
      SERVERFS_SEARCH_MAX_FILE_BYTES: ${SERVERFS_SEARCH_MAX_FILE_BYTES:-52428800}

      SERVERFS_ALLOW_HIDDEN: ${SERVERFS_ALLOW_HIDDEN:-false}

      SERVERFS_EXTRA_DENY_GLOBS: ${SERVERFS_EXTRA_DENY_GLOBS:-}
      SERVERFS_DISABLE_DEFAULT_DENY: ${SERVERFS_DISABLE_DEFAULT_DENY:-false}

      SERVERFS_MAX_WRITE_BYTES: ${SERVERFS_MAX_WRITE_BYTES:-1048576}
      SERVERFS_MAX_EDITS_PER_CALL: ${SERVERFS_MAX_EDITS_PER_CALL:-50}

      SERVERFS_BINARY_TRANSFER_ENABLED: ${SERVERFS_BINARY_TRANSFER_ENABLED:-false}
      SERVERFS_MAX_BINARY_TRANSFER_BYTES: ${SERVERFS_MAX_BINARY_TRANSFER_BYTES:-8388608}
      SERVERFS_FILE_INGRESS_ENABLED: ${SERVERFS_FILE_INGRESS_ENABLED:-false}
      SERVERFS_FILE_INGRESS_TIMEOUT_SECONDS: ${SERVERFS_FILE_INGRESS_TIMEOUT_SECONDS:-30}

      WORKDIR_01_ALIAS: ${WORKDIR_01_ALIAS:-}
      WORKDIR_01_DESCRIPTION: ${WORKDIR_01_DESCRIPTION:-}
      WORKDIR_01_READ_ONLY: ${WORKDIR_01_READ_ONLY:-true}
      WORKDIR_01_ALLOW_HIDDEN: ${WORKDIR_01_ALLOW_HIDDEN:-}
      WORKDIR_01_DISABLE_DEFAULT_DENY: ${WORKDIR_01_DISABLE_DEFAULT_DENY:-}
      WORKDIR_01_EXTRA_DENY_GLOBS: ${WORKDIR_01_EXTRA_DENY_GLOBS:-}
      WORKDIR_01_MAX_READ_BYTES: ${WORKDIR_01_MAX_READ_BYTES:-}
      WORKDIR_01_MAX_READ_LINES: ${WORKDIR_01_MAX_READ_LINES:-}
      WORKDIR_01_MAX_WRITE_BYTES: ${WORKDIR_01_MAX_WRITE_BYTES:-}
      WORKDIR_01_BINARY_TRANSFER_ENABLED: ${WORKDIR_01_BINARY_TRANSFER_ENABLED:-}
      WORKDIR_01_MAX_BINARY_TRANSFER_BYTES: ${WORKDIR_01_MAX_BINARY_TRANSFER_BYTES:-}
      WORKDIR_02_ALIAS: ${WORKDIR_02_ALIAS:-}
      WORKDIR_02_DESCRIPTION: ${WORKDIR_02_DESCRIPTION:-}
      WORKDIR_02_READ_ONLY: ${WORKDIR_02_READ_ONLY:-true}
      WORKDIR_02_ALLOW_HIDDEN: ${WORKDIR_02_ALLOW_HIDDEN:-}
      WORKDIR_02_DISABLE_DEFAULT_DENY: ${WORKDIR_02_DISABLE_DEFAULT_DENY:-}
      WORKDIR_02_EXTRA_DENY_GLOBS: ${WORKDIR_02_EXTRA_DENY_GLOBS:-}
      WORKDIR_02_MAX_READ_BYTES: ${WORKDIR_02_MAX_READ_BYTES:-}
      WORKDIR_02_MAX_READ_LINES: ${WORKDIR_02_MAX_READ_LINES:-}
      WORKDIR_02_MAX_WRITE_BYTES: ${WORKDIR_02_MAX_WRITE_BYTES:-}
      WORKDIR_02_BINARY_TRANSFER_ENABLED: ${WORKDIR_02_BINARY_TRANSFER_ENABLED:-}
      WORKDIR_02_MAX_BINARY_TRANSFER_BYTES: ${WORKDIR_02_MAX_BINARY_TRANSFER_BYTES:-}
      WORKDIR_03_ALIAS: ${WORKDIR_03_ALIAS:-}
      WORKDIR_03_DESCRIPTION: ${WORKDIR_03_DESCRIPTION:-}
      WORKDIR_03_READ_ONLY: ${WORKDIR_03_READ_ONLY:-true}
      WORKDIR_03_ALLOW_HIDDEN: ${WORKDIR_03_ALLOW_HIDDEN:-}
      WORKDIR_03_DISABLE_DEFAULT_DENY: ${WORKDIR_03_DISABLE_DEFAULT_DENY:-}
      WORKDIR_03_EXTRA_DENY_GLOBS: ${WORKDIR_03_EXTRA_DENY_GLOBS:-}
      WORKDIR_03_MAX_READ_BYTES: ${WORKDIR_03_MAX_READ_BYTES:-}
      WORKDIR_03_MAX_READ_LINES: ${WORKDIR_03_MAX_READ_LINES:-}
      WORKDIR_03_MAX_WRITE_BYTES: ${WORKDIR_03_MAX_WRITE_BYTES:-}
      WORKDIR_03_BINARY_TRANSFER_ENABLED: ${WORKDIR_03_BINARY_TRANSFER_ENABLED:-}
      WORKDIR_03_MAX_BINARY_TRANSFER_BYTES: ${WORKDIR_03_MAX_BINARY_TRANSFER_BYTES:-}
      WORKDIR_04_ALIAS: ${WORKDIR_04_ALIAS:-}
      WORKDIR_04_DESCRIPTION: ${WORKDIR_04_DESCRIPTION:-}
      WORKDIR_04_READ_ONLY: ${WORKDIR_04_READ_ONLY:-true}
      WORKDIR_04_ALLOW_HIDDEN: ${WORKDIR_04_ALLOW_HIDDEN:-}
      WORKDIR_04_DISABLE_DEFAULT_DENY: ${WORKDIR_04_DISABLE_DEFAULT_DENY:-}
      WORKDIR_04_EXTRA_DENY_GLOBS: ${WORKDIR_04_EXTRA_DENY_GLOBS:-}
      WORKDIR_04_MAX_READ_BYTES: ${WORKDIR_04_MAX_READ_BYTES:-}
      WORKDIR_04_MAX_READ_LINES: ${WORKDIR_04_MAX_READ_LINES:-}
      WORKDIR_04_MAX_WRITE_BYTES: ${WORKDIR_04_MAX_WRITE_BYTES:-}
      WORKDIR_04_BINARY_TRANSFER_ENABLED: ${WORKDIR_04_BINARY_TRANSFER_ENABLED:-}
      WORKDIR_04_MAX_BINARY_TRANSFER_BYTES: ${WORKDIR_04_MAX_BINARY_TRANSFER_BYTES:-}
      WORKDIR_05_ALIAS: ${WORKDIR_05_ALIAS:-}
      WORKDIR_05_DESCRIPTION: ${WORKDIR_05_DESCRIPTION:-}
      WORKDIR_05_READ_ONLY: ${WORKDIR_05_READ_ONLY:-true}
      WORKDIR_05_ALLOW_HIDDEN: ${WORKDIR_05_ALLOW_HIDDEN:-}
      WORKDIR_05_DISABLE_DEFAULT_DENY: ${WORKDIR_05_DISABLE_DEFAULT_DENY:-}
      WORKDIR_05_EXTRA_DENY_GLOBS: ${WORKDIR_05_EXTRA_DENY_GLOBS:-}
      WORKDIR_05_MAX_READ_BYTES: ${WORKDIR_05_MAX_READ_BYTES:-}
      WORKDIR_05_MAX_READ_LINES: ${WORKDIR_05_MAX_READ_LINES:-}
      WORKDIR_05_MAX_WRITE_BYTES: ${WORKDIR_05_MAX_WRITE_BYTES:-}
      WORKDIR_05_BINARY_TRANSFER_ENABLED: ${WORKDIR_05_BINARY_TRANSFER_ENABLED:-}
      WORKDIR_05_MAX_BINARY_TRANSFER_BYTES: ${WORKDIR_05_MAX_BINARY_TRANSFER_BYTES:-}
      WORKDIR_06_ALIAS: ${WORKDIR_06_ALIAS:-}
      WORKDIR_06_DESCRIPTION: ${WORKDIR_06_DESCRIPTION:-}
      WORKDIR_06_READ_ONLY: ${WORKDIR_06_READ_ONLY:-true}
      WORKDIR_06_ALLOW_HIDDEN: ${WORKDIR_06_ALLOW_HIDDEN:-}
      WORKDIR_06_DISABLE_DEFAULT_DENY: ${WORKDIR_06_DISABLE_DEFAULT_DENY:-}
      WORKDIR_06_EXTRA_DENY_GLOBS: ${WORKDIR_06_EXTRA_DENY_GLOBS:-}
      WORKDIR_06_MAX_READ_BYTES: ${WORKDIR_06_MAX_READ_BYTES:-}
      WORKDIR_06_MAX_READ_LINES: ${WORKDIR_06_MAX_READ_LINES:-}
      WORKDIR_06_MAX_WRITE_BYTES: ${WORKDIR_06_MAX_WRITE_BYTES:-}
      WORKDIR_06_BINARY_TRANSFER_ENABLED: ${WORKDIR_06_BINARY_TRANSFER_ENABLED:-}
      WORKDIR_06_MAX_BINARY_TRANSFER_BYTES: ${WORKDIR_06_MAX_BINARY_TRANSFER_BYTES:-}
      WORKDIR_07_ALIAS: ${WORKDIR_07_ALIAS:-}
      WORKDIR_07_DESCRIPTION: ${WORKDIR_07_DESCRIPTION:-}
      WORKDIR_07_READ_ONLY: ${WORKDIR_07_READ_ONLY:-true}
      WORKDIR_07_ALLOW_HIDDEN: ${WORKDIR_07_ALLOW_HIDDEN:-}
      WORKDIR_07_DISABLE_DEFAULT_DENY: ${WORKDIR_07_DISABLE_DEFAULT_DENY:-}
      WORKDIR_07_EXTRA_DENY_GLOBS: ${WORKDIR_07_EXTRA_DENY_GLOBS:-}
      WORKDIR_07_MAX_READ_BYTES: ${WORKDIR_07_MAX_READ_BYTES:-}
      WORKDIR_07_MAX_READ_LINES: ${WORKDIR_07_MAX_READ_LINES:-}
      WORKDIR_07_MAX_WRITE_BYTES: ${WORKDIR_07_MAX_WRITE_BYTES:-}
      WORKDIR_07_BINARY_TRANSFER_ENABLED: ${WORKDIR_07_BINARY_TRANSFER_ENABLED:-}
      WORKDIR_07_MAX_BINARY_TRANSFER_BYTES: ${WORKDIR_07_MAX_BINARY_TRANSFER_BYTES:-}
      WORKDIR_08_ALIAS: ${WORKDIR_08_ALIAS:-}
      WORKDIR_08_DESCRIPTION: ${WORKDIR_08_DESCRIPTION:-}
      WORKDIR_08_READ_ONLY: ${WORKDIR_08_READ_ONLY:-true}
      WORKDIR_08_ALLOW_HIDDEN: ${WORKDIR_08_ALLOW_HIDDEN:-}
      WORKDIR_08_DISABLE_DEFAULT_DENY: ${WORKDIR_08_DISABLE_DEFAULT_DENY:-}
      WORKDIR_08_EXTRA_DENY_GLOBS: ${WORKDIR_08_EXTRA_DENY_GLOBS:-}
      WORKDIR_08_MAX_READ_BYTES: ${WORKDIR_08_MAX_READ_BYTES:-}
      WORKDIR_08_MAX_READ_LINES: ${WORKDIR_08_MAX_READ_LINES:-}
      WORKDIR_08_MAX_WRITE_BYTES: ${WORKDIR_08_MAX_WRITE_BYTES:-}
      WORKDIR_08_BINARY_TRANSFER_ENABLED: ${WORKDIR_08_BINARY_TRANSFER_ENABLED:-}
      WORKDIR_08_MAX_BINARY_TRANSFER_BYTES: ${WORKDIR_08_MAX_BINARY_TRANSFER_BYTES:-}
      WORKDIR_09_ALIAS: ${WORKDIR_09_ALIAS:-}
      WORKDIR_09_DESCRIPTION: ${WORKDIR_09_DESCRIPTION:-}
      WORKDIR_09_READ_ONLY: ${WORKDIR_09_READ_ONLY:-true}
      WORKDIR_09_ALLOW_HIDDEN: ${WORKDIR_09_ALLOW_HIDDEN:-}
      WORKDIR_09_DISABLE_DEFAULT_DENY: ${WORKDIR_09_DISABLE_DEFAULT_DENY:-}
      WORKDIR_09_EXTRA_DENY_GLOBS: ${WORKDIR_09_EXTRA_DENY_GLOBS:-}
      WORKDIR_09_MAX_READ_BYTES: ${WORKDIR_09_MAX_READ_BYTES:-}
      WORKDIR_09_MAX_READ_LINES: ${WORKDIR_09_MAX_READ_LINES:-}
      WORKDIR_09_MAX_WRITE_BYTES: ${WORKDIR_09_MAX_WRITE_BYTES:-}
      WORKDIR_09_BINARY_TRANSFER_ENABLED: ${WORKDIR_09_BINARY_TRANSFER_ENABLED:-}
      WORKDIR_09_MAX_BINARY_TRANSFER_BYTES: ${WORKDIR_09_MAX_BINARY_TRANSFER_BYTES:-}
      WORKDIR_10_ALIAS: ${WORKDIR_10_ALIAS:-}
      WORKDIR_10_DESCRIPTION: ${WORKDIR_10_DESCRIPTION:-}
      WORKDIR_10_READ_ONLY: ${WORKDIR_10_READ_ONLY:-true}
      WORKDIR_10_ALLOW_HIDDEN: ${WORKDIR_10_ALLOW_HIDDEN:-}
      WORKDIR_10_DISABLE_DEFAULT_DENY: ${WORKDIR_10_DISABLE_DEFAULT_DENY:-}
      WORKDIR_10_EXTRA_DENY_GLOBS: ${WORKDIR_10_EXTRA_DENY_GLOBS:-}
      WORKDIR_10_MAX_READ_BYTES: ${WORKDIR_10_MAX_READ_BYTES:-}
      WORKDIR_10_MAX_READ_LINES: ${WORKDIR_10_MAX_READ_LINES:-}
      WORKDIR_10_MAX_WRITE_BYTES: ${WORKDIR_10_MAX_WRITE_BYTES:-}
      WORKDIR_10_BINARY_TRANSFER_ENABLED: ${WORKDIR_10_BINARY_TRANSFER_ENABLED:-}
      WORKDIR_10_MAX_BINARY_TRANSFER_BYTES: ${WORKDIR_10_MAX_BINARY_TRANSFER_BYTES:-}
      WORKDIR_11_ALIAS: ${WORKDIR_11_ALIAS:-}
      WORKDIR_11_DESCRIPTION: ${WORKDIR_11_DESCRIPTION:-}
      WORKDIR_11_READ_ONLY: ${WORKDIR_11_READ_ONLY:-true}
      WORKDIR_11_ALLOW_HIDDEN: ${WORKDIR_11_ALLOW_HIDDEN:-}
      WORKDIR_11_DISABLE_DEFAULT_DENY: ${WORKDIR_11_DISABLE_DEFAULT_DENY:-}
      WORKDIR_11_EXTRA_DENY_GLOBS: ${WORKDIR_11_EXTRA_DENY_GLOBS:-}
      WORKDIR_11_MAX_READ_BYTES: ${WORKDIR_11_MAX_READ_BYTES:-}
      WORKDIR_11_MAX_READ_LINES: ${WORKDIR_11_MAX_READ_LINES:-}
      WORKDIR_11_MAX_WRITE_BYTES: ${WORKDIR_11_MAX_WRITE_BYTES:-}
      WORKDIR_11_BINARY_TRANSFER_ENABLED: ${WORKDIR_11_BINARY_TRANSFER_ENABLED:-}
      WORKDIR_11_MAX_BINARY_TRANSFER_BYTES: ${WORKDIR_11_MAX_BINARY_TRANSFER_BYTES:-}
      WORKDIR_12_ALIAS: ${WORKDIR_12_ALIAS:-}
      WORKDIR_12_DESCRIPTION: ${WORKDIR_12_DESCRIPTION:-}
      WORKDIR_12_READ_ONLY: ${WORKDIR_12_READ_ONLY:-true}
      WORKDIR_12_ALLOW_HIDDEN: ${WORKDIR_12_ALLOW_HIDDEN:-}
      WORKDIR_12_DISABLE_DEFAULT_DENY: ${WORKDIR_12_DISABLE_DEFAULT_DENY:-}
      WORKDIR_12_EXTRA_DENY_GLOBS: ${WORKDIR_12_EXTRA_DENY_GLOBS:-}
      WORKDIR_12_MAX_READ_BYTES: ${WORKDIR_12_MAX_READ_BYTES:-}
      WORKDIR_12_MAX_READ_LINES: ${WORKDIR_12_MAX_READ_LINES:-}
      WORKDIR_12_MAX_WRITE_BYTES: ${WORKDIR_12_MAX_WRITE_BYTES:-}
      WORKDIR_12_BINARY_TRANSFER_ENABLED: ${WORKDIR_12_BINARY_TRANSFER_ENABLED:-}
      WORKDIR_12_MAX_BINARY_TRANSFER_BYTES: ${WORKDIR_12_MAX_BINARY_TRANSFER_BYTES:-}
      WORKDIR_13_ALIAS: ${WORKDIR_13_ALIAS:-}
      WORKDIR_13_DESCRIPTION: ${WORKDIR_13_DESCRIPTION:-}
      WORKDIR_13_READ_ONLY: ${WORKDIR_13_READ_ONLY:-true}
      WORKDIR_13_ALLOW_HIDDEN: ${WORKDIR_13_ALLOW_HIDDEN:-}
      WORKDIR_13_DISABLE_DEFAULT_DENY: ${WORKDIR_13_DISABLE_DEFAULT_DENY:-}
      WORKDIR_13_EXTRA_DENY_GLOBS: ${WORKDIR_13_EXTRA_DENY_GLOBS:-}
      WORKDIR_13_MAX_READ_BYTES: ${WORKDIR_13_MAX_READ_BYTES:-}
      WORKDIR_13_MAX_READ_LINES: ${WORKDIR_13_MAX_READ_LINES:-}
      WORKDIR_13_MAX_WRITE_BYTES: ${WORKDIR_13_MAX_WRITE_BYTES:-}
      WORKDIR_13_BINARY_TRANSFER_ENABLED: ${WORKDIR_13_BINARY_TRANSFER_ENABLED:-}
      WORKDIR_13_MAX_BINARY_TRANSFER_BYTES: ${WORKDIR_13_MAX_BINARY_TRANSFER_BYTES:-}
      WORKDIR_14_ALIAS: ${WORKDIR_14_ALIAS:-}
      WORKDIR_14_DESCRIPTION: ${WORKDIR_14_DESCRIPTION:-}
      WORKDIR_14_READ_ONLY: ${WORKDIR_14_READ_ONLY:-true}
      WORKDIR_14_ALLOW_HIDDEN: ${WORKDIR_14_ALLOW_HIDDEN:-}
      WORKDIR_14_DISABLE_DEFAULT_DENY: ${WORKDIR_14_DISABLE_DEFAULT_DENY:-}
      WORKDIR_14_EXTRA_DENY_GLOBS: ${WORKDIR_14_EXTRA_DENY_GLOBS:-}
      WORKDIR_14_MAX_READ_BYTES: ${WORKDIR_14_MAX_READ_BYTES:-}
      WORKDIR_14_MAX_READ_LINES: ${WORKDIR_14_MAX_READ_LINES:-}
      WORKDIR_14_MAX_WRITE_BYTES: ${WORKDIR_14_MAX_WRITE_BYTES:-}
      WORKDIR_14_BINARY_TRANSFER_ENABLED: ${WORKDIR_14_BINARY_TRANSFER_ENABLED:-}
      WORKDIR_14_MAX_BINARY_TRANSFER_BYTES: ${WORKDIR_14_MAX_BINARY_TRANSFER_BYTES:-}
      WORKDIR_15_ALIAS: ${WORKDIR_15_ALIAS:-}
      WORKDIR_15_DESCRIPTION: ${WORKDIR_15_DESCRIPTION:-}
      WORKDIR_15_READ_ONLY: ${WORKDIR_15_READ_ONLY:-true}
      WORKDIR_15_ALLOW_HIDDEN: ${WORKDIR_15_ALLOW_HIDDEN:-}
      WORKDIR_15_DISABLE_DEFAULT_DENY: ${WORKDIR_15_DISABLE_DEFAULT_DENY:-}
      WORKDIR_15_EXTRA_DENY_GLOBS: ${WORKDIR_15_EXTRA_DENY_GLOBS:-}
      WORKDIR_15_MAX_READ_BYTES: ${WORKDIR_15_MAX_READ_BYTES:-}
      WORKDIR_15_MAX_READ_LINES: ${WORKDIR_15_MAX_READ_LINES:-}
      WORKDIR_15_MAX_WRITE_BYTES: ${WORKDIR_15_MAX_WRITE_BYTES:-}
      WORKDIR_15_BINARY_TRANSFER_ENABLED: ${WORKDIR_15_BINARY_TRANSFER_ENABLED:-}
      WORKDIR_15_MAX_BINARY_TRANSFER_BYTES: ${WORKDIR_15_MAX_BINARY_TRANSFER_BYTES:-}
      WORKDIR_16_ALIAS: ${WORKDIR_16_ALIAS:-}
      WORKDIR_16_DESCRIPTION: ${WORKDIR_16_DESCRIPTION:-}
      WORKDIR_16_READ_ONLY: ${WORKDIR_16_READ_ONLY:-true}
      WORKDIR_16_ALLOW_HIDDEN: ${WORKDIR_16_ALLOW_HIDDEN:-}
      WORKDIR_16_DISABLE_DEFAULT_DENY: ${WORKDIR_16_DISABLE_DEFAULT_DENY:-}
      WORKDIR_16_EXTRA_DENY_GLOBS: ${WORKDIR_16_EXTRA_DENY_GLOBS:-}
      WORKDIR_16_MAX_READ_BYTES: ${WORKDIR_16_MAX_READ_BYTES:-}
      WORKDIR_16_MAX_READ_LINES: ${WORKDIR_16_MAX_READ_LINES:-}
      WORKDIR_16_MAX_WRITE_BYTES: ${WORKDIR_16_MAX_WRITE_BYTES:-}
      WORKDIR_16_BINARY_TRANSFER_ENABLED: ${WORKDIR_16_BINARY_TRANSFER_ENABLED:-}
      WORKDIR_16_MAX_BINARY_TRANSFER_BYTES: ${WORKDIR_16_MAX_BINARY_TRANSFER_BYTES:-}

    volumes:
      - type: bind
        source: ${WORKDIR_01_PATH:-./.empty}
        target: /workdirs/01
        read_only: ${WORKDIR_01_READ_ONLY:-true}
        bind:
          create_host_path: false
      - type: bind
        source: ${WORKDIR_02_PATH:-./.empty}
        target: /workdirs/02
        read_only: ${WORKDIR_02_READ_ONLY:-true}
        bind:
          create_host_path: false
      - type: bind
        source: ${WORKDIR_03_PATH:-./.empty}
        target: /workdirs/03
        read_only: ${WORKDIR_03_READ_ONLY:-true}
        bind:
          create_host_path: false
      - type: bind
        source: ${WORKDIR_04_PATH:-./.empty}
        target: /workdirs/04
        read_only: ${WORKDIR_04_READ_ONLY:-true}
        bind:
          create_host_path: false
      - type: bind
        source: ${WORKDIR_05_PATH:-./.empty}
        target: /workdirs/05
        read_only: ${WORKDIR_05_READ_ONLY:-true}
        bind:
          create_host_path: false
      - type: bind
        source: ${WORKDIR_06_PATH:-./.empty}
        target: /workdirs/06
        read_only: ${WORKDIR_06_READ_ONLY:-true}
        bind:
          create_host_path: false
      - type: bind
        source: ${WORKDIR_07_PATH:-./.empty}
        target: /workdirs/07
        read_only: ${WORKDIR_07_READ_ONLY:-true}
        bind:
          create_host_path: false
      - type: bind
        source: ${WORKDIR_08_PATH:-./.empty}
        target: /workdirs/08
        read_only: ${WORKDIR_08_READ_ONLY:-true}
        bind:
          create_host_path: false
      - type: bind
        source: ${WORKDIR_09_PATH:-./.empty}
        target: /workdirs/09
        read_only: ${WORKDIR_09_READ_ONLY:-true}
        bind:
          create_host_path: false
      - type: bind
        source: ${WORKDIR_10_PATH:-./.empty}
        target: /workdirs/10
        read_only: ${WORKDIR_10_READ_ONLY:-true}
        bind:
          create_host_path: false
      - type: bind
        source: ${WORKDIR_11_PATH:-./.empty}
        target: /workdirs/11
        read_only: ${WORKDIR_11_READ_ONLY:-true}
        bind:
          create_host_path: false
      - type: bind
        source: ${WORKDIR_12_PATH:-./.empty}
        target: /workdirs/12
        read_only: ${WORKDIR_12_READ_ONLY:-true}
        bind:
          create_host_path: false
      - type: bind
        source: ${WORKDIR_13_PATH:-./.empty}
        target: /workdirs/13
        read_only: ${WORKDIR_13_READ_ONLY:-true}
        bind:
          create_host_path: false
      - type: bind
        source: ${WORKDIR_14_PATH:-./.empty}
        target: /workdirs/14
        read_only: ${WORKDIR_14_READ_ONLY:-true}
        bind:
          create_host_path: false
      - type: bind
        source: ${WORKDIR_15_PATH:-./.empty}
        target: /workdirs/15
        read_only: ${WORKDIR_15_READ_ONLY:-true}
        bind:
          create_host_path: false
      - type: bind
        source: ${WORKDIR_16_PATH:-./.empty}
        target: /workdirs/16
        read_only: ${WORKDIR_16_READ_ONLY:-true}
        bind:
          create_host_path: false

    expose:
      - "${SERVERFS_HTTP_PORT:-8000}"

    networks:
      - serverfs_internal
      - serverfs_file_ingress

    read_only: true

    tmpfs:
      - /tmp

    cap_drop:
      - ALL

    security_opt:
      - no-new-privileges:true

    healthcheck:
      test:
        [
          "CMD",
          ".venv/bin/python",
          "-c",
          "import os,socket; socket.create_connection(('127.0.0.1', int(os.environ.get('SERVERFS_HTTP_PORT', '8000'))), timeout=2).close()",
        ]
      interval: 10s
      timeout: 3s
      retries: 5
      start_period: 5s

  serverfs-file-ingress:
    profiles: ["file-ingress"]
    image: ${SERVERFS_IMAGE:-ghcr.io/ntlx/serverfs_mcp:latest}
    command: ["python", "-m", "serverfs_mcp.file_ingress"]

    restart: unless-stopped

    user: "${SERVERFS_UID:-10001}:${SERVERFS_GID:-10001}"

    environment:
      TZ: ${TZ:-Asia/Shanghai}
      SERVERFS_FILE_INGRESS_ALLOWED_HOSTS: ${SERVERFS_FILE_INGRESS_ALLOWED_HOSTS:-}
      SERVERFS_FILE_INGRESS_ALLOW_OPENAI_BLOB_HOSTS: ${SERVERFS_FILE_INGRESS_ALLOW_OPENAI_BLOB_HOSTS:-false}
      SERVERFS_MAX_BINARY_TRANSFER_BYTES: ${SERVERFS_MAX_BINARY_TRANSFER_BYTES:-}
      SERVERFS_FILE_INGRESS_MAX_BYTES: ${SERVERFS_FILE_INGRESS_MAX_BYTES:-}
      SERVERFS_FILE_INGRESS_FETCH_TIMEOUT_SECONDS: ${SERVERFS_FILE_INGRESS_FETCH_TIMEOUT_SECONDS:-30}
      SERVERFS_FILE_INGRESS_MAX_REDIRECTS: ${SERVERFS_FILE_INGRESS_MAX_REDIRECTS:-3}
      SERVERFS_FILE_INGRESS_PORT: 8081

    expose:
      - "8081"

    networks:
      - serverfs_file_ingress
      - file_ingress_egress

    read_only: true

    tmpfs:
      - /tmp

    cap_drop:
      - ALL

    security_opt:
      - no-new-privileges:true

    healthcheck:
      test:
        [
          "CMD",
          ".venv/bin/python",
          "-c",
          "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8081/healthz', timeout=2).read()",
        ]
      interval: 10s
      timeout: 3s
      retries: 5
      start_period: 5s

  openai-tunnel:
    image: ${OPENAI_TUNNEL_IMAGE:-ghcr.io/openai/tunnel-client:v0.0.17}

    restart: unless-stopped

    depends_on:
      serverfs-mcp:
        condition: service_healthy

    environment:
      CONTROL_PLANE_API_KEY: ${CONTROL_PLANE_API_KEY}
      CONTROL_PLANE_TUNNEL_ID: ${CONTROL_PLANE_TUNNEL_ID}
      CONTROL_PLANE_BASE_URL: ${CONTROL_PLANE_BASE_URL:-https://api.openai.com}
      SERVERFS_OPENAI_TUNNEL_USE_PROXY: ${SERVERFS_OPENAI_TUNNEL_USE_PROXY-__serverfs_unset__}
      SERVERFS_PROXY_HOST: ${SERVERFS_PROXY_HOST:-}
      SERVERFS_PROXY_PORT: ${SERVERFS_PROXY_PORT:-}
      SERVERFS_PROXY_USERNAME: ${SERVERFS_PROXY_USERNAME:-}
      SERVERFS_PROXY_PASSWORD: ${SERVERFS_PROXY_PASSWORD:-}

      MCP_SERVER_URL: http://serverfs-mcp:${SERVERFS_HTTP_PORT:-8000}${SERVERFS_HTTP_PATH:-/mcp}

      MCP_STARTUP_WAIT_TIMEOUT: ${MCP_STARTUP_WAIT_TIMEOUT:-60s}

      LOG_LEVEL: ${TUNNEL_LOG_LEVEL:-info}
      LOG_FORMAT: ${TUNNEL_LOG_FORMAT:-json}

      HEALTH_LISTEN_ADDR: ${HEALTH_LISTEN_ADDR:-:8080}

    entrypoint: ["/bin/sh", "/opt/serverfs/tunnel-launcher.sh"]

    volumes:
      - ./deployment/tunnel/tunnel-launcher.sh:/opt/serverfs/tunnel-launcher.sh:ro

    expose:
      - "8080"

    healthcheck:
      test:
        [
          "CMD-SHELL",
          "port=$${HEALTH_LISTEN_ADDR##*:}; /usr/bin/tunnel-client health --port \"$${port}\" --require-control-plane-poll",
        ]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 10s

    networks:
      - serverfs_internal
      - tunnel_egress

    cap_drop:
      - ALL

    security_opt:
      - no-new-privileges:true


networks:

  serverfs_internal:
    internal: true

  serverfs_file_ingress:
    internal: true

  tunnel_egress:

  file_ingress_egress: