Skip to the content.

Zed + fak Integration Guide

This guide shows how to use fak as a tool-governance layer for Zed, the AI-native editor. Every tool call Zed proposes is evaluated by the kernel before it executes — dangerous calls are dropped, malformed calls are repaired, and policy violations are refused.

Overview

┌──────────────────┐   OpenAI / Anthropic   ┌────────────────────────┐
│      Zed        │ ──────────────────────▶ │  fak serve (gateway)   │
│  (AI-native IDE) │ ◀──── SSE stream ─────  │  adjudicates tools     │
└──────────────────┘                        └────────────────────────┘
          ▲                                                 │
          │ settings.json api_url                          ▼
          │ (points at fak)                                │
          │                                        ┌───────────────┐
          │                                        │  Local Model  │
          │                                        │ or Cloud API  │
          │                                        └───────────────┘

The gateway sits between Zed and the model:

Result: Zed can edit your codebase, but the kernel blocks destructive commands, prevents self-modification, and contains untrusted tool results.


Prerequisites

1. Install fak

# From the repo (the Go module is the repo root)
git clone https://github.com/anthony-chaudhary/fak && cd fak
go build -o fak ./cmd/fak

# Or via the installer
curl -fsSL https://raw.githubusercontent.com/anthony-chaudhary/fak/main/install.sh | sh

Verify installation:

./fak version

2. Install Zed

Download Zed from zed.dev and install following the official setup guide for your platform (macOS, Linux, or Windows).

3. Choose your upstream model

Zed can connect to fak in two modes:

For development, proxy mode is recommended as it gives you full model capabilities while still enforcing tool governance.


Quick Start: One-command setup

The fastest way to put the kernel in front of Zed:

# Terminal 1: Start the fak gateway
./fak serve \
  --addr 127.0.0.1:8080 \
  --provider openai \
  --base-url http://localhost:11434/v1 \
  --model qwen2.5:1.5b \
  --policy examples/customer-support-readonly-policy.json

# Terminal 2: Open Zed
# Zed will read settings.json and use the configured provider
zed

Zed now runs through the capability floor — every file edit, command, and tool call is adjudicated before execution.


Zed’s primary integration path is through OpenAI-compatible APIs. fak provides an OpenAI-compatible /v1/chat/completions endpoint.

Step 1: Start the fak HTTP gateway

./fak serve \
  --addr 127.0.0.1:8080 \
  --provider openai \
  --base-url http://localhost:11434/v1 \
  --model qwen2.5:1.5b \
  --policy examples/customer-support-readonly-policy.json

Verify health:

curl http://127.0.0.1:8080/healthz
# {"ok":true,"model":"qwen2.5:1.5b","engine":"inkernel"}

Step 2: Configure Zed via settings.json

Zed’s configuration lives in ~/.config/zed/settings.json (Linux), ~/Library/Application Support/Zed/settings.json (macOS), or %APPDATA%\Zed\settings.json (Windows).

Add or edit the language_models section:

{
  "language_models": {
    "openai_compatible": {
      "fak": {
        "api_url": "http://127.0.0.1:8080/v1",
        "available_models": [
          {
            "id": "qwen2.5:1.5b",
            "name": "Qwen 2.5 (1.5B)"
          }
        ],
        "low_speed_timeout_in_seconds": 60,
        "high_speed_timeout_in_seconds": 5
      }
    }
  }
}

Set the API key via environment variable (Zed reads <PROVIDER_ID>_API_KEY):

# Set before launching Zed
export FAK_API_KEY="fak-local"

Or set it in your shell profile (.bashrc, .zshrc, etc.) for persistence.

Step 3: Configure Zed to use the fak model

Add to your settings.json:

{
  "language_models": {
    "openai_compatible": {
      "fak": {
        "api_url": "http://127.0.0.1:8080/v1",
        "available_models": [
          {
            "id": "qwen2.5:1.5b",
            "name": "Qwen 2.5 (1.5B)"
          }
        ],
        "low_speed_timeout_in_seconds": 60,
        "high_speed_timeout_in_seconds": 5
      }
    },
    "model": "openai_compatible/fak"
  }
}

Or set the model per-project in .zed/settings.json:

{
  "language_models": {
    "model": "openai_compatible/fak"
  }
}

Step 4: Reload Zed

  1. If Zed is running, reload settings: Cmd+Shift+P → “Reload Settings”
  2. Or restart Zed entirely
  3. Open the AI panel (Cmd+L or Ctrl+L)
  4. Select the model from the dropdown

Zed’s file edits and commands now flow through fak:

Zed → fak /v1/chat/completions → adjudication → upstream model
                                          ↓
                                    capability floor
                                          ↓
                                  allowed/denied/transformed
                                          ↓
                                    Zed (with filtered results)

Method 2: Anthropic provider

Zed also supports Anthropic’s Messages API for Claude models.

Step 1: Start the fak gateway with Anthropic provider

./fak serve \
  --addr 127.0.0.1:8080 \
  --provider anthropic \
  --base-url https://api.anthropic.com/v1 \
  --api-key-env ANTHROPIC_API_KEY \
  --model claude-sonnet-4-20250514 \
  --policy examples/customer-support-readonly-policy.json

Step 2: Configure Zed via settings.json

Add to your settings.json:

{
  "language_models": {
    "anthropic": {
      "api_url": "http://127.0.0.1:8080",
      "available_models": [
        {
          "id": "claude-sonnet-4-20250514",
          "name": "Claude Sonnet 4"
        }
      ],
      "low_speed_timeout_in_seconds": 60,
      "high_speed_timeout_in_seconds": 5
    },
    "model": "anthropic"
  }
}

Set the API key:

export ANTHROPIC_API_KEY="fak-local"

Step 3: Reload Zed

Reload settings or restart Zed, then open the AI panel and verify the Claude model is selected.


Method 3: Multiple providers with different policies

You can run multiple fak serve instances with different policies and switch between them in Zed.

# Terminal 1: Strict policy (development)
./fak serve --addr 127.0.0.1:8080 --policy strict.json ...

# Terminal 2: Permissive policy (review)
./fak serve --addr 127.0.0.1:8090 --policy permissive.json ...

Configure both in settings.json:

{
  "language_models": {
    "openai_compatible": {
      "fak-dev": {
        "api_url": "http://127.0.0.1:8080/v1",
        "available_models": [
          {
            "id": "qwen2.5:1.5b",
            "name": "Qwen (Strict)"
          }
        ]
      },
      "fak-review": {
        "api_url": "http://127.0.0.1:8090/v1",
        "available_models": [
          {
            "id": "qwen2.5:1.5b",
            "name": "Qwen (Permissive)"
          }
        ]
      }
    }
  }
}

Switch between models via the AI panel dropdown or per-project settings.


Creating a Capability Floor for Zed

A capability floor defines which operations Zed may perform. Start from the built-in default:

# Dump the default policy as a starting point
./fak policy --dump > zed-policy.json

Example: Safe coding assistant policy

{
  "version": "fak-policy/v1",
  "posture": "fail_closed",
  "allow": [
    "read_file",
    "write_file",
    "list_directory",
    "search_files",
    "get_definition",
    "git_diff",
    "git_log"
  ],
  "allow_prefix": [
    "read_",
    "get_",
    "search_",
    "list_",
    "git_",
    "lint_",
    "format_"
  ],
  "deny": {
    "run_command": "POLICY_BLOCK",
    "git_push": "POLICY_BLOCK",
    "git_reset": "POLICY_BLOCK",
    "git_clean": "POLICY_BLOCK",
    "delete_file": "POLICY_BLOCK"
  },
  "self_modify_globs": [
    ".git/",
    ".zed/",
    "zed-policy.json",
    ".env",
    "id_rsa"
  ],
  "redact_fields": [
    "password",
    "secret",
    "api_key",
    "token"
  ],
  "arg_rules": [
    {
      "tool": "read_file",
      "arg": "path",
      "deny_regex": ".*\\.env$",
      "reason": "SECRET_EXFIL"
    },
    {
      "tool": "run_command",
      "arg": "command",
      "deny_regex": "rm\\s+-rf|sudo|git\\s+push",
      "reason": "POLICY_BLOCK"
    }
  ]
}

Validate before using:

./fak policy --check zed-policy.json

Use the custom policy:

./fak serve --policy zed-policy.json ...

Common Patterns for Zed Workflows

Pattern 1: Read-only code review

Configure fak to allow reads but block writes and destructive Git operations:

{
  "allow": ["read_file", "list_directory", "search_files", "git_diff", "git_log"],
  "deny": {
    "write_file": "POLICY_BLOCK",
    "run_command": "POLICY_BLOCK",
    "git_push": "POLICY_BLOCK"
  }
}

Pattern 2: Safe refactoring with Git awareness

Allow safe file operations but block destructive Git operations:

{
  "allow_prefix": ["read_", "write_", "search_", "git_diff", "git_log", "git_show", "git_blame"],
  "deny": {
    "git_push": "POLICY_BLOCK",
    "git_reset": "POLICY_BLOCK",
    "git_clean": "POLICY_BLOCK",
    "run_command": "POLICY_BLOCK"
  },
  "self_modify_globs": [".git/", ".zed/"]
}

Pattern 3: Quarantine for external tool results

Protect against poisoned responses from external APIs:

# Enable quarantine on the gateway
./fak serve --addr 127.0.0.1:8080 \
  --base-url https://api.openai.com/v1 \
  --policy policy.json \
  --vdso=true  # Enables content-addressed cache and quarantine

If an external tool returns suspicious content (e.g., injection attempts), fak automatically quarantines it, preventing it from entering Zed’s context.


Monitoring and Debugging

Health checks

curl http://127.0.0.1:8080/healthz

Metrics

curl http://127.0.0.1:8080/metrics

Key metrics:

Debugging a denied operation

When Zed reports a denied operation, reproduce it offline:

./fak preflight \
  --tool write_file \
  --args '{"path":"test.txt","content":"test"}' \
  --policy your-policy.json
# verdict=DENY reason=POLICY_BLOCK

Use --explain to get a detailed breakdown:

./fak preflight --explain \
  --tool run_command \
  --args '{"command":"rm -rf /tmp"}' \
  --policy your-policy.json

Checking Zed’s model connection

  1. Open Zed
  2. Open the AI panel (Cmd+L or Ctrl+L)
  3. Check that the model dropdown shows your configured model
  4. Verify the API URL points to http://127.0.0.1:8080/v1

Troubleshooting

Zed can’t connect to the gateway

  1. Verify fak is running:
    curl http://127.0.0.1:8080/healthz
    
  2. Check Zed’s settings.json:
    cat ~/.config/zed/settings.json | grep api_url
    # Should show: "api_url": "http://127.0.0.1:8080/v1"
    
  3. Check the API key environment variable:
    echo $FAK_API_KEY
    # Should output: fak-local
    
  4. Check Zed’s output logs:
    • Open Zed
    • Press Cmd+Shift+P (macOS) or Ctrl+Shift+P (Linux/Windows)
    • Run “Open Log”
    • Look for connection errors

All operations are being denied

  1. Check the policy’s posture:
    • posture: "fail_closed" (default) denies everything not explicitly allowed
    • Ensure your tools are in allow or match an allow_prefix
  2. Test a specific call:
    ./fak preflight --tool read_file --args '{"path":"test.txt"}' --policy your-policy.json
    
  3. Check the gateway logs:
    # Add --log to fak serve
    ./fak serve --log <tmp>/fak-zed.log ...
    tail -f <tmp>/fak-zed.log
    

Slow first response

Expected on large local models — the Zed prompt is ~25K tokens. Subsequent requests are faster if you enable --vdso=true (content-addressed caching).

Settings.json not being picked up

  1. Verify the settings.json location:
    • Linux: ~/.config/zed/settings.json
    • macOS: ~/Library/Application Support/Zed/settings.json
    • Windows: %APPDATA%\Zed\settings.json
  2. Check file syntax:
    # Validate JSON
    cat ~/.config/zed/settings.json | python -m json.tool
    
  3. Reload settings: Cmd+Shift+P → “Reload Settings”

  4. Check for conflicting project settings: .zed/settings.json overrides global settings

Model not appearing in dropdown

  1. Verify the available_models array includes the model ID
  2. Ensure low_speed_timeout_in_seconds and high_speed_timeout_in_seconds are set
  3. Reload settings or restart Zed
  4. Check Zed logs for model loading errors

Advanced Usage

Authentication

For production use, require an API key:

./fak serve \
  --addr 0.0.0.0:8080 \
  --base-url ... \
  --model ... \
  --require-key-env FAK_TOKEN

Zed sends <PROVIDER_ID>_API_KEY environment variable, which fak honors.

Cloud providers

# OpenAI
./fak serve \
  --provider openai \
  --base-url https://api.openai.com/v1 \
  --api-key-env OPENAI_API_KEY \
  --model gpt-4

# Anthropic
./fak serve \
  --provider anthropic \
  --base-url https://api.anthropic.com/v1 \
  --api-key-env ANTHROPIC_API_KEY \
  --model claude-sonnet-4-20250514

Local models

# Ollama
./fak serve \
  --provider openai \
  --base-url http://localhost:11434/v1 \
  --model qwen2.5-coder:7b

# vLLM
./fak serve \
  --provider openai \
  --base-url http://localhost:8000/v1 \
  --model qwen2.5-coder:7b

Per-project configuration

Use .zed/settings.json in your project root for project-specific model selection:

{
  "language_models": {
    "model": "openai_compatible/fak-review"
  }
}

This overrides the global setting for that project only.


Cross-references


License

Apache-2.0