Skip to content

Configuring HTTP Adapters ​

An adapter connects CodeCompanion to an LLM provider or an agent. HTTP adapters, set under adapters.http, call an LLM's API directly, with CodeCompanion supplying the system prompt, tools and agent loop. ACP adapters, set under adapters.acp, connect to an agent that brings its own. Both are configured in the same way, so read the two pages together.

TIP

For a provider that isn't built in, try a community adapter or create your own

Built-in Adapters ​

AdapterAPI keyDefault model
anthropicANTHROPIC_API_KEYclaude-sonnet-5
azure_openaiAZURE_OPENAI_API_KEY and AZURE_OPENAI_ENDPOINTNone, set your deployment name
copilotYour Copilot sign-inauto
deepseekDEEPSEEK_API_KEYdeepseek-v4-flash
geminiGEMINI_API_KEYgemini-3.1-pro-preview
gemini_legacyGEMINI_API_KEYgemini-3.1-pro-preview
huggingfaceHUGGINGFACE_API_KEYQwen/Qwen2.5-32B-Instruct
kimiMOONSHOT_API_KEYkimi-k2.7-code
mistralMISTRAL_API_KEYmistral-small-latest
novitaNOVITA_API_KEYmeta-llama/llama-3.1-8b-instruct
ollamaNone, set OLLAMA_HOST for a remote serverA model from your Ollama server
openaiOPENAI_API_KEYgpt-5.6-luna
openai_legacyOPENAI_API_KEYgpt-4.1
openrouterOPENROUTER_API_KEYopenai/gpt-5.4-mini
xaiXAI_API_KEYgrok-beta

gemini uses Google's Interactions API and gemini_legacy uses generateContent. openai uses the Responses API and openai_legacy uses Chat Completions. For llama.cpp, LM Studio and other servers that speak the OpenAI API, extend openai_compatible, as covered in Connecting an OpenAI-Compatible Provider.

The duckduckgo, jina, markitdown, serply and tavily adapters power the web search and fetch tools rather than chat.

Changing the Default Adapter ​

To set the adapter for each interaction:

lua
require("codecompanion").setup({
  interactions = {
    chat = {
      adapter = "anthropic",
    },
    inline = {
      adapter = "copilot",
    },
    cmd = {
      adapter = "deepseek",
    },
  },
})

Changing the Default Model ​

Set the model on the interaction, or on the adapter so it applies everywhere:

lua
require("codecompanion").setup({
  interactions = {
    chat = {
      adapter = {
        name = "openai",
        model = "gpt-4.1",
      },
    },
  },
})
lua
require("codecompanion").setup({
  adapters = {
    http = {
      openai = function()
        return require("codecompanion.adapters").extend("openai", {
          schema = {
            model = {
              default = "gpt-4.1",
            },
          },
        })
      end,
    },
  },
})

Customising an Adapter ​

There are two ways to customise a built-in adapter, and this page uses both:

  • Function - For full or computed setups, such as a custom url, headers or schema, or values resolved when the adapter loads
  • extend table - For static overrides, such as credentials or a default value
lua
require("codecompanion").setup({
  adapters = {
    http = {
      anthropic = function()
        return require("codecompanion.adapters").extend("anthropic", {
          env = { api_key = "cmd:op read op://personal/Anthropic/credential --no-newline" },
        })
      end,
    },
  },
})
lua
require("codecompanion").setup({
  adapters = {
    http = {
      extend = {
        anthropic = { env = { api_key = "cmd:op read op://personal/Anthropic/credential --no-newline" } },
      },
    },
  },
})

IMPORTANT

Each key in extend is the adapter's key under adapters.http, not the adapter's name

Changing Adapter Parameters (Schema) ​

An adapter's parameters, such as model, temperature and max_output_tokens, sit in its schema table. To change a default:

lua
require("codecompanion").setup({
  adapters = {
    http = {
      openai = function()
        return require("codecompanion.adapters").extend("openai", {
          schema = {
            temperature = {
              default = 0.2,
            },
          },
        })
      end,
    },
  },
})

A parameter's enabled function takes the adapter and decides whether the parameter is sent. To leave temperature out for Codex models:

lua
require("codecompanion").setup({
  adapters = {
    http = {
      openai = function()
        return require("codecompanion.adapters").extend("openai", {
          schema = {
            temperature = {
              enabled = function(self)
                local model = require("codecompanion.adapters.utils").model(self)
                return not (model and model:find("codex"))
              end,
            },
          },
        })
      end,
    },
  },
})

Adding a Custom Adapter ​

Add your own adapter alongside the built-in ones:

lua
require("codecompanion").setup({
  adapters = {
    http = {
      my_custom_adapter = function()
        return {} -- Your adapter
      end,
    },
  },
})

See Creating Adapters for what goes in the table.

Background Interaction Adapters ​

Background interactions send requests to an LLM without any input from you, such as to generate a chat title. They use interactions.background.adapter, which you can override for a single action:

lua
require("codecompanion").setup({
  interactions = {
    background = {
      chat = {
        callbacks = {
          ["on_ready"] = {
            actions = {
              {
                path = "interactions.background.builtin.chat_make_title",
                adapter = { name = "copilot", model = "claude-haiku-4.5" },
              },
            },
          },
        },
      },
    },
  },
})

Controlling Model Choices ​

Changing adapter with ga asks you to pick a model when the adapter has more than one. To use the adapter's default model without asking:

lua
require("codecompanion").setup({
  adapters = {
    http = {
      opts = {
        show_model_choices = false,
      },
    },
  },
})

Model lists fetched from a provider are cached for 1800 seconds, set with adapters.http.opts.cache_models_for.

Environment Variables ​

An adapter's env table holds values, such as an API key, that are resolved on every request and substituted into its URL, headers and parameters:

lua
require("codecompanion").setup({
  adapters = {
    http = {
      anthropic = function()
        return require("codecompanion.adapters").extend("anthropic", {
          env = {
            api_key = "MY_OTHER_ANTHROPIC_KEY",
          },
        })
      end,
    },
  },
})
lua
require("codecompanion").setup({
  adapters = {
    http = {
      anthropic = function()
        return require("codecompanion.adapters").extend("anthropic", {
          env = {
            api_key = "cmd:op read op://personal/Anthropic/credential --no-newline",
          },
        })
      end,
    },
  },
})
lua
require("codecompanion").setup({
  adapters = {
    http = {
      anthropic = function()
        return require("codecompanion.adapters").extend("anthropic", {
          env = {
            api_key = function()
              return my_custom_api_key_fetcher()
            end,
          },
        })
      end,
    },
  },
})
lua
require("codecompanion").setup({
  adapters = {
    http = {
      anthropic = function()
        return require("codecompanion.adapters").extend("anthropic", {
          env = {
            model_for_url = "schema.model.default",
          },
        })
      end,
    },
  },
})
lua
require("codecompanion").setup({
  adapters = {
    http = {
      anthropic = function()
        return require("codecompanion.adapters").extend("anthropic", {
          env = {
            api_key = "file:~/.dotfiles/.anthropic_api_key",
          },
        })
      end,
    },
  },
})
ValueResolves to
"cmd:op read ..."The output of the shell command, such as the 1Password CLI or gpg
"file:~/.anthropic_api_key"The file's contents, with a relative path read from the current working directory
"ANTHROPIC_API_KEY"The environment variable of that name
A functionIts return value, called with the adapter
"schema.model.default"The value at that path in the adapter
Anything elseThe value as written

Commands time out after 20 seconds. To change this:

lua
require("codecompanion").setup({
  adapters = {
    opts = {
      cmd_timeout = 30000, -- milliseconds
    },
  },
})

Disabling Compaction ​

The anthropic and openai adapters use the provider's server-side compaction to manage context. To turn it off:

lua
require("codecompanion").setup({
  adapters = {
    http = {
      anthropic = function()
        return require("codecompanion.adapters").extend("anthropic", {
          opts = {
            compaction = false,
          },
        })
      end,
    },
  },
})

Hiding Adapters ​

Adapters in the hidden table are left out of the adapter picker. Set one to false to show it again:

lua
require("codecompanion").setup({
  adapters = {
    http = {
      opts = {
        hidden = { my_custom_adapter = true, tavily = false },
      },
    },
  },
})

By default, duckduckgo, jina, markitdown and tavily are hidden. Hidden adapters can still be used by name, such as by the web_search tool.

To list only the adapters in your own config, leaving out the built-in ones:

lua
require("codecompanion").setup({
  adapters = {
    http = {
      opts = {
        show_presets = false,
      },
    },
  },
})

Setting a Proxy ​

To send requests through a proxy:

lua
require("codecompanion").setup({
  adapters = {
    http = {
      opts = {
        allow_insecure = true,
        proxy = "socks5://127.0.0.1:9999",
      },
    },
  },
})

Setup Examples ​

Some of these are illustrations rather than setups the plugin actively supports.

Azure OpenAI ​

The azure_openai adapter has no default model, so set your deployment name:

lua
require("codecompanion").setup({
  adapters = {
    http = {
      azure_openai = function()
        return require("codecompanion.adapters").extend("azure_openai", {
          env = {
            api_key = "YOUR_AZURE_OPENAI_API_KEY",
            endpoint = "YOUR_AZURE_OPENAI_ENDPOINT",
          },
          schema = {
            model = {
              default = "YOUR_DEPLOYMENT_NAME",
            },
          },
        })
      end,
    },
  },
  interactions = {
    chat = {
      adapter = "azure_openai",
    },
    inline = {
      adapter = "azure_openai",
    },
  },
})

Copilot Free and Student ​

Copilot Free and Student plans only get models through auto model selection. The copilot adapter defaults to the auto model, so it works without any extra config.

llama.cpp with --reasoning-format deepseek ​

To show llama.cpp's reasoning output in the chat buffer:

lua
require("codecompanion").setup({
  adapters = {
    http = {
      ["llama.cpp"] = function()
        return require("codecompanion.adapters").extend("openai_compatible", {
          env = {
            url = "http://127.0.0.1:8080", -- replace with your llama.cpp instance
            api_key = "TERM",
            chat_url = "/v1/chat/completions",
          },
          handlers = {
            parse_message_meta = function(self, data)
              local extra = data.extra
              if extra and extra.reasoning_content then
                data.output.reasoning = { content = extra.reasoning_content }
                if data.output.content == "" then
                  data.output.content = nil
                end
              end
              return data
            end,
          },
        })
      end,
    },
  },
  interactions = {
    chat = {
      adapter = "llama.cpp",
    },
    inline = {
      adapter = "llama.cpp",
    },
  },
})

Ollama (remotely) ​

To connect to a remote Ollama server, set OLLAMA_HOST, the same variable the Ollama CLI uses:

bash
export OLLAMA_HOST="http://192.168.1.100:11434"

Or set the URL on the adapter, with an API key sent in an Authorization header if the server needs one:

lua
require("codecompanion").setup({
  adapters = {
    http = {
      ollama = function()
        return require("codecompanion.adapters").extend("ollama", {
          env = {
            url = "https://my_ollama_url",
            api_key = "OLLAMA_API_KEY",
          },
          headers = {
            ["Content-Type"] = "application/json",
            ["Authorization"] = "Bearer ${api_key}",
          },
        })
      end,
    },
  },
})

OpenAI Responses API ​

The openai adapter uses OpenAI's Responses API. To use the Chat Completions API instead:

lua
require("codecompanion").setup({
  interactions = {
    chat = {
      adapter = "openai_legacy",
    },
    inline = {
      adapter = "openai_legacy",
    },
  },
})

The openai adapter sends store = false, so OpenAI doesn't store your responses.

OpenRouter ​

The openrouter adapter supports:

Tool use, vision and the available parameters depend on the model you select. Set them in your config, or for a single chat in the debug window:

lua
require("codecompanion").setup({
  adapters = {
    http = {
      openrouter = function()
        return require("codecompanion.adapters").extend("openrouter", {
          schema = {
            preset = { default = "email-copywriter" },
          },
        })
      end,
    },
  },
})
lua
require("codecompanion").setup({
  adapters = {
    http = {
      openrouter = function()
        return require("codecompanion.adapters").extend("openrouter", {
          schema = {
            provider = {
              default = {
                allow_fallbacks = true,
                order = { "anthropic", "openai" },
                require_parameters = false,
              },
            },
          },
        })
      end,
    },
  },
})

Each chat buffer sends its own session_id for sticky sessions, which you can rename in the debug window. To fix it on the adapter instead:

lua
require("codecompanion").setup({
  adapters = {
    http = {
      openrouter_title_generation = function()
        return require("codecompanion.adapters").extend("openrouter", {
          opts = { session_id = "title_generation" },
        })
      end,
    },
  },
})

Community Adapters ​

Adapters built by the community:

Raise issues and questions about them in their threads in the adapter discussions.

Released under the Apache-2.0 License.