Skip to content

Editor Integration (ACP)

Glue can run headless as an Agent Client Protocol (ACP) agent, so editors and notebooks that speak ACP can drive a Glue session in-process. ACP is a JSON-RPC protocol from Zed Industries — the same one Zed uses for Claude Code, Gemini, Codex, and other agents.

The entry point is glue acp. It exposes the full Glue harness (tool calls, runtimes, permission gating, MCP servers, models, sessions) over stdin/stdout or a WebSocket. Editors spawn it; you don't normally invoke it by hand.

Quick start (Zed)

  1. Install Glue and make sure glue is on your PATH.

  2. Open ~/.config/zed/settings.json and add:

    json
    {
      "agent_servers": {
        "Glue": {
          "type": "custom",
          "command": "glue",
          "args": ["acp"],
          "env": {}
        }
      }
    }
  3. Open the agent panel and pick Glue. (Zed hot-reloads settings.json — no restart needed.)

That's it — Zed spawns glue acp over stdio, opens an ACP session, and your prompts run through Glue's harness.

Transports

glue acp supports two transports. Editors use stdio; browser and notebook clients use WebSocket.

TransportUse whenFlag
stdioDefault. Editor spawns Glue as a subprocess and pipes JSON-RPC.--stdio (default)
WebSocketBrowser and notebook clients that can't spawn a local subprocess.--port N (implies --no-stdio)

stdio (editors)

sh
glue acp              # what the editor runs

In stdio mode, stdin and stdout are the JSON-RPC protocol channel — glue acp writes nothing to stdout and nothing to stderr on startup. It's meant to be spawned by an editor, not invoked manually.

If you run it interactively, it will simply wait for JSON-RPC messages on stdin and look idle. Press Ctrl+D (closes stdin) or Ctrl+C to exit.

WebSocket (browser, notebook)

sh
glue acp --port 3000                                  # loopback, no auth
glue acp --port 3000 --host 0.0.0.0 --token secret123 # LAN, token required

On startup, the WebSocket transport prints a multi-line banner to stderr (stdout is reserved for the protocol). Loopback, no token:

● glue acp ACP over WebSocket
  ✓ url  ws://127.0.0.1:3000/acp
  · docs https://getglue.dev/docs/advanced/acp-server
  · stop Ctrl+C

With --token, an additional warning line appears between url and docs:

  ! auth bearer token required

Non-loopback hosts require a token

Binding --host to anything other than 127.0.0.1 requires --token <secret>. The token is sent as Authorization: Bearer … (or ?token=… query string). Glue refuses to start without one — exposing an unauthenticated agent on a LAN means anyone on that LAN can run shell commands as you.

glue acp command reference

glue acp [--stdio] [--port N] [--host H] [--ws-path P]
           [--token T] [--protocol acp] [--debug]
FlagDefaultPurpose
--stdiotrueSpeak ACP over stdin/stdout. This is what editors expect.
--port N, -p NBind a WebSocket server on the given port. 0 picks an ephemeral port. Implies --no-stdio.
--host H127.0.0.1Bind address for --port. Pass 0.0.0.0 to expose on all interfaces (requires --token).
--ws-path P/acpHTTP path that accepts the WebSocket upgrade. * accepts any path.
--token TBearer token required on every WebSocket connection. Required when --host is non-loopback.
--protocolacpProtocol to serve. ACP only today; MCP-client support is on the roadmap.
--debug, -dfalseEnable debug observability sinks for the agent loop.

Editor configuration

Status as of 2026-05-21. Always check the upstream docs for the latest config shape.

Passing provider, model, and credentials

Every editor's env block is forwarded into the spawned glue acp process, so you can pin a provider per agent without touching ~/.glue/config.yaml:

jsonc
"env": {
  "GLUE_PROVIDER": "ollama",
  "GLUE_MODEL": "ollama/gemma3",
  "OLLAMA_HOST": "http://localhost:11434"
}

API keys (ANTHROPIC_API_KEY, OPENAI_API_KEY, …) work the same way. Editors that don't support per-agent env (some Neovim plugins) inherit the launching shell's environment instead.

Zed (official)

~/.config/zed/settings.json:

json
{
  "agent_servers": {
    "Glue": {
      "type": "custom",
      "command": "glue",
      "args": ["acp"],
      "env": {}
    }
  }
}

Open the agent panel and pick Glue. Settings hot-reload — no restart needed. Debug via Command Palette → dev: open acp logs.

If glue isn't on Zed's $PATH (common when installed via ~/.local/bin or a version manager), use an absolute path: "command": "/Users/you/.local/bin/glue".

Zed reference: External agents · Agent server extensions · ACP registry.

Custom-agent icons

Zed doesn't currently expose an icon field for custom agents in settings.json — only TOML-packaged agent extensions and entries in the public ACP registry get icons. Follow zed#51149 for status.

JetBrains AI Assistant (official, 2025.3+)

JetBrains AI Assistant ships native ACP support starting with 2025.3 (AI plugin v253.30387.147+). The easiest path is AI Chat → Add Custom Agent, which writes ~/.jetbrains/acp.json. To register Glue by hand, edit that file directly:

json
{
  "agent_servers": {
    "Glue": {
      "command": "/Users/you/.local/bin/glue",
      "args": ["acp"],
      "env": {
        "GLUE_PROVIDER": "ollama",
        "GLUE_MODEL": "ollama/gemma3",
        "OLLAMA_HOST": "http://localhost:11434"
      }
    }
  }
}

The agent-level keys are command, args, and env — there's no "type" field (unlike Zed). After editing acp.json, refresh the Agents panel or restart the IDE.

Absolute paths required

JetBrains IDEs do not inherit the user shell's $PATH reliably. Always use absolute paths in commandwhich glue from a terminal gives you the right value.

Multiple agents live side-by-side under agent_servers. A realistic config that mixes Glue with other ACP agents:

json
{
  "agent_servers": {
    "Glue": {
      "command": "/Users/you/.local/bin/glue",
      "args": ["acp"],
      "env": { "GLUE_PROVIDER": "anthropic" }
    },
    "opencode": {
      "command": "/opt/homebrew/bin/opencode",
      "args": ["acp"]
    },
    "goose": {
      "command": "/opt/homebrew/bin/goose",
      "args": ["acp"]
    }
  }
}

Exposing the IDE's MCP server to Glue

JetBrains can expose its built-in IntelliJ MCP server (file navigation, refactor primitives, run configurations) to ACP agents. Add a top-level default_mcp_settings block:

json
{
  "default_mcp_settings": {
    "use_idea_mcp": true,
    "use_custom_mcp": true
  },
  "agent_servers": {
    "Glue": {
      "command": "/Users/you/.local/bin/glue",
      "args": ["acp"]
    }
  }
}
  • use_idea_mcp — expose the IDE's built-in MCP server.
  • use_custom_mcp — also expose any MCP servers you've configured in AI Assistant settings.
  • idea_mcp_allowed_tools — optional array narrowing which IDE MCP tools are exposed.

These settings apply to every agent. Per-agent overrides are documented as possible by JetBrains but the exact key shape isn't public yet — stick with top-level defaults.

JetBrains reference: AI Assistant — ACP · ACP Agent Registry.

VS Code

No first-party ACP support — Microsoft has not adopted the protocol (see microsoft/vscode#265496). The only community extension that reached a usable state, gayanper/vscode-acp-provider, was archived in April 2026 and never shipped on the Marketplace. If you use VS Code, drive Glue through the terminal (glue interactively, or glue acp --port 3000 with a WebSocket client) until first-party or maintained third-party support exists.

Neovim (community)

Three actively-maintained plugins implement ACP. Pick one — they're mutually exclusive.

carlos-algms/agentic.nvim — simplest

lua
{
  "carlos-algms/agentic.nvim",
  opts = {
    acp_providers = {
      glue = {
        name = "Glue",
        command = "glue",
        args = { "acp" },
        env = {
          GLUE_PROVIDER = "anthropic",
        },
      },
    },
  },
}

Only command is strictly required; name shows up in the provider picker. Sessions are interchangeable with terminal glue sessions (same session storage).

lua
require("codecompanion").setup({
  adapters = {
    acp = {
      glue = function()
        local helpers = require("codecompanion.adapters.acp.helpers")
        return {
          name = "glue",
          formatted_name = "Glue",
          type = "acp",
          roles = { llm = "assistant", user = "user" },
          commands = {
            default = { "glue", "acp" },
          },
          defaults = {
            mcpServers = "inherit_from_config",
            timeout = 20000,
          },
          parameters = {
            protocolVersion = 1,
            clientCapabilities = {
              fs = { readTextFile = true, writeTextFile = true },
            },
            clientInfo = { name = "CodeCompanion.nvim", version = "1.0.0" },
          },
          handlers = {
            setup = function(self) return true end,
            auth = function(self) return true end,
            form_messages = function(self, messages, capabilities)
              return helpers.form_messages(self, messages, capabilities)
            end,
            on_exit = function(self, code) end,
          },
        }
      end,
    },
  },
})

ACP adapters in CodeCompanion only work in the chat buffer, not inline assist. See adapters-acp.

yetone/avante.nvim — terse but buggy

lua
{
  "yetone/avante.nvim",
  opts = {
    provider = "glue",
    acp_providers = {
      glue = {
        command = "glue",
        args = { "acp" },
      },
    },
  },
}

Known issues: ACP providers don't appear in :AvanteSwitchProvider (#2958) — you must set provider in config. Switching from a non-ACP provider mid-session can error; workaround is rm -rf ~/.local/state/nvim/avante/projects.

Emacs (community)

Use xenodium/acp.el directly, or the xenodium/agent-shell interactive UI on top of it.

elisp
(require 'acp)

(setq glue-client
  (acp-make-client
    :command "glue"
    :command-params '("acp")
    :environment-variables '("GLUE_PROVIDER=anthropic")))

Keyword names matter: :command-params (not :args) and :environment-variables is a list of "KEY=value" strings. The *acp traffic* buffer tees the JSON-RPC wire log — handy for debugging.

Early-stage

acp.el is explicitly marked as not API-stable. Keyword names may change; install from GitHub via use-package :vc (not on MELPA).

Web and notebook clients (WebSocket)

These clients use the WebSocket transport — start Glue with glue acp --port 3000 (see WebSocket transport above).

  • jupyter-ai-acp-client — official Jupyter AI v3.0 ACP client. pip install jupyter_ai_acp_client. Defines agents via a persona with an executable field.
  • agent-client-kernel — alternative Jupyter kernel; configures the agent via the ACP_AGENT_COMMAND env var.
  • marimoagent panel ships Claude Code, Gemini, Codex, and OpenCode preconfigured. Custom-agent support is documented as "coming soon" — there's no public hook for pointing it at glue acp yet.

A canonical, community-maintained list of ACP clients lives at https://agentclientprotocol.com/get-started/clients.

Security

glue acp exposes the full Glue harness, including the shell tool. Treat it like SSH access.

  • stdio is implicitly trusted — only the parent process can talk to it.
  • WebSocket on loopback (127.0.0.1) is reachable only from the host. Still consider a token if other users share the machine.
  • WebSocket on non-loopback hosts requires --token. Glue refuses to start without one.
  • Permission gating still applies. Every tool call goes through the same approval gate as the interactive TUI. The mode (confirm or auto) is set in ~/.glue/config.yaml. In confirm mode, read-only and trusted tools run automatically; mutating tools are routed to the editor as an ACP session/request_permission so the user clicks Approve/Deny in their IDE. In auto mode, every tool runs without prompting.

See also

Released under the MIT License.