# Switching from mock-llm to aimock

mock-llm is solid for OpenAI mocking with Kubernetes. aimock gives you 11 more providers, zero dependencies, and full MCP/A2A/AG-UI/Vector support—with the same Helm chart workflow you're used to.

## Config migration

mock-llm uses a YAML config to define responses. aimock uses a JSON config with a richer feature set. Here's how the concepts map:

mock-llm — config.yaml yaml

    port: 8080
    completions:
      - model: "gpt-4"
        response:
          content: "Hello from mock-llm"
          role: "assistant"
        usage:
          prompt_tokens: 10
          completion_tokens: 5
          total_tokens: 15

aimock — aimock.json json

    {
      "llm": {
        "fixtures": "./fixtures",
        "metrics": true,
        "strict": false
      },
      "services": {
        "/mcp": { "type": "mcp", "tools": "./mcp-tools.json" },
        "/a2a": { "type": "a2a", "agents": "./a2a-agents.json" }
      }
    }

Inline responses from mock-llm's YAML become fixture files. Each fixture is a JSON file that defines the response content, and aimock handles SSE framing, chunking, and token counting automatically:

mock-llm — inline YAML response yaml

    completions:
      - model: "gpt-4"
        response:
          content: "Hello world"
          role: "assistant"

aimock — fixtures/hello.json json

    {
      "match": { "userMessage": "*" },
      "response": {
        "content": "Hello world"
      }
    }

## What you gain

🌐

### Multi-provider (12 vs 1)

OpenAI (Chat, Responses, Realtime), Claude, Gemini (REST, Live, and Interactions), Bedrock, Azure, Vertex AI, Ollama, Cohere, and OpenAI-compatible providers.

0

### Zero dependencies

Pure Node.js with no runtime dependencies. No YAML parsers, no Express, no framework lock-in.

📦

### Vector DB mocking

Mock Pinecone, Qdrant, and ChromaDB endpoints for RAG pipeline testing.

⏺

### Record & replay

Proxy real APIs, capture responses as fixtures, replay deterministically forever.

🔍

### Drift detection

Three-way comparison of SDK types, real API responses, and mock output catches shape mismatches.

🧩

### Chaos testing

Inject latency, drop chunks, corrupt payloads, and disconnect mid-stream to harden your app.

🔌

### WebSocket APIs

OpenAI Realtime, Responses WS, Gemini Live. Full bidirectional protocol mocking.

{ }

### Programmatic API

Use `new LLMock()` in Vitest/Jest for in-process mocking alongside CLI and Docker modes.

## Comparison table

Capability | mock-llm | aimock
--- | --- | ---
OpenAI Chat Completions | ✓ | ✓
OpenAI Responses API | ✗ | ✓
Anthropic Claude | ✗ | ✓
Google Gemini | ✗ | ✓
AWS Bedrock | ✗ | ✓
Azure OpenAI / Vertex AI / Ollama / Cohere | ✗ | ✓
Streaming SSE | Basic | Full (TTFT, TPS, jitter)
WebSocket protocols | ✗ | 3 protocols
MCP protocol mocking | ✗ | ✓
A2A protocol mocking | ✗ | ✓
Vector DB mocking | ✗ | ✓
Record & replay | ✗ | ✓
Drift detection | ✗ | ✓
Chaos testing | ✗ | ✓
Prometheus metrics | ✗ | ✓
Programmatic API | ✗ | ✓
Zero dependencies | ✗ | ✓
Kubernetes / Helm | ✓ | ✓
Docker image | ✓ | ✓

## Kubernetes migration

If you're running mock-llm in Kubernetes via Helm, switching to aimock is a values.yaml change. The deployment pattern is identical—only the image and config format differ.

mock-llm — values.yaml yaml

    replicaCount: 1

    image:
      repository: dwmkerr/mock-llm
      tag: "latest"
      pullPolicy: IfNotPresent

    service:
      type: ClusterIP
      port: 8080

    env:
      - name: MOCK_LLM_CONFIG
        value: /config/config.yaml

    volumes:
      - name: config
        configMap:
          name: mock-llm-config

    volumeMounts:
      - name: config
        mountPath: /config

aimock — values.yaml yaml

    replicaCount: 1

    image:
      repository: ghcr.io/copilotkit/aimock
      tag: ""   # defaults to Chart appVersion
      pullPolicy: IfNotPresent

    service:
      type: ClusterIP
      port: 4010

    fixtures:
      mountPath: /app/fixtures
      existingClaim: ""  # PVC for fixture files

    livenessProbe:
      httpGet:
        path: /health
        port: 4010
      initialDelaySeconds: 5
      periodSeconds: 10

    readinessProbe:
      httpGet:
        path: /ready
        port: 4010
      initialDelaySeconds: 2
      periodSeconds: 5

    resources: {}
      # limits:
      #   cpu: 200m
      #   memory: 256Mi

Key differences: aimock uses JSON fixtures on a PVC instead of a YAML ConfigMap, the default port is `4010` instead of `8080`, and the image comes from `ghcr.io/copilotkit/aimock`. Health checks work the same way—aimock exposes `/health` (liveness) and `/ready` (readiness).

If you were using mock-llm's ConfigMap for inline responses, convert each response to a fixture JSON file and load them via a PVC. See the Fixtures documentation for the full schema.

## CLI / Docker quick start

Install & run sh

    # Run the mock server (flag-driven llmock bin)
    npx -p @copilotkit/aimock llmock -p 4010 -f ./fixtures

    # With a full config file
    npx @copilotkit/aimock --config aimock.json --port 4010

    # Point your app at the mock
    export OPENAI_BASE_URL=http://localhost:4010/v1

Docker sh

    # Pull and run
    docker run -d -p 4010:4010 \
      -v $(pwd)/fixtures:/fixtures \
      ghcr.io/copilotkit/aimock:latest \
      -p 4010 -f /fixtures -h 0.0.0.0

    # Config-driven mode (runs on your host, not in the image)
    # The published Docker image runs the flag-driven llmock CLI
    # which does not support --config. Use npx locally instead:
    npx @copilotkit/aimock --config aimock.json --port 4010

    # Point your app at the mock
    export OPENAI_BASE_URL=http://localhost:4010/v1