Integration coverage
“Works with” means the specific path listed below can send a request through Keel. It does not mean Keel observes every call or tool available to the named SDK, model, or agent. Keep the Keel project key on your server, configure the provider credential in Keel, and verify that your project allows the selected model and proxy route.
| Stack item | Usable Keel path | Scope of the claim |
|---|---|---|
| OpenAI SDK | Chat Completions through /v1/proxy/openai/chat/completions | Model calls on this route. A request that carries tool definitions is refused before dispatch (platform_safety_floor.unknown_action). The SDK’s Responses API and application-executed tools are separate paths. |
| Anthropic SDK | Text Messages through /v1/proxy/anthropic/v1/messages | Native Messages request and response for text calls. Token counting and tool-schema calls are not covered by this recipe. |
| Vercel AI SDK | ai@6 with @ai-sdk/openai-compatible@2 through the OpenAI Chat Completions proxy | Model calls without tool definitions. A full tool-calling agent that sends tool schemas to this proxy is refused before dispatch (platform_safety_floor.unknown_action). Application tools need their own Keel-governed execution path, such as an enrolled MCP :call. |
| Gemini | Google model proxy or Keel SDK provider wrapper | Supported model operations only; see Provider Support. This is not a Gemini CLI integration. |
| Grok | xAI model proxy or Keel SDK provider wrapper | Supported model operations only; see Provider Support. This is not a Grok CLI integration. |
| Azure OpenAI | Azure OpenAI connector mode for supported OpenAI model operations | Azure OpenAI Service only; this does not describe the full Azure AI or Foundry catalog. |
| ElevenLabs | None today | Keel dispatches only operations it can price authoritatively; generate.audio and transcribe.audio are refused before any provider call. Hosted ElevenLabs Agents and realtime calls are not covered. |
| MCP tools | POST /v1/mcp/servers/{server_ref}/tools/{tool_name}:call for an MCP server registered in your project | Keel governs that tool call. Only connector identities Keel has enrolled (an operator step; ask Keel) can reach a policy allow. A server you register yourself is held for review on every call: a human-approved action mapping can classify its tools, but their calls stay review-only, and unmapped tools are refused. Starter cannot allow non-payment MCP tool calls. /v1/mcp/* is not a client-facing MCP server that an agent can add directly, and no compatibility with arbitrary MCP servers or MCP SDK versions is claimed. |
| Custom agents | /v1/execute, /v1/executions, or a documented proxy route | Only calls and actions the application actually routes through Keel. |
Of these, only the OpenAI paths have a current live certification; the Anthropic, Gemini, Grok and Azure OpenAI paths are covered by API tests.
For managed MCP execution-key scope and live identity requirements, see Authentication.
Current managed-MCP customer lifecycle certification is pending. Historical proof does not certify a later candidate; transport conformance alone does not prove the full approval, replay, revocation, dispatch and evidence lifecycle.
Provider support varies by operation and maturity tier. The capability matrix, provider support table, and surface maturity page are the detailed references.
OpenAI and Anthropic SDK setup
Hosted Keel requires a current X-Keel-Timestamp and a new X-Keel-Nonce on every HTTP attempt to a proxy route, including the SDK’s own retries. A stock provider SDK pointed at a Keel base URL does not send them, so hosted Keel rejects its requests with 401 request_not_fresh. The recipes below pass the SDK a fetch function that adds a new timestamp and nonce to every request it sends. It also checks the destination before sending a Keel key. Use Node 22 or later, or a compatible server runtime with fetch, Request, Headers, and crypto.randomUUID(); do not put a project key in browser code.
A tool that can only be pointed at Keel through a base-URL setting, such as an OPENAI_BASE_URL environment variable, cannot add these headers and is not supported on hosted Keel. This includes agent tools such as Goose, Aider, and Open Interpreter when they are configured only by base URL. Use a Keel SDK, or a client that lets you add the headers to every request as shown here.
function keelFetchFor(endpoint: string): typeof fetch {
const allowed = new URL(endpoint);
return (input, init) => {
const actual = new URL(input instanceof Request ? input.url : String(input));
if (actual.origin !== allowed.origin || actual.pathname !== allowed.pathname) {
throw new TypeError("SDK request is outside the configured Keel model endpoint");
}
const headers = new Headers(input instanceof Request ? input.headers : undefined);
new Headers(init?.headers).forEach((value, name) => headers.set(name, value));
headers.set("X-Keel-Timestamp", String(Math.floor(Date.now() / 1000)));
headers.set("X-Keel-Nonce", "nonce-" + crypto.randomUUID().replaceAll("-", ""));
return fetch(input, { ...init, headers, redirect: "manual" });
};
}The examples below are server-side TypeScript. Run them in your TypeScript application, with the shared keelFetchFor helper above the SDK example.
Keep a separate Idempotency-Key for each logical model invocation. Create it once before the call and pass it in the request options, as below; the SDK retains it across its HTTP retries while the fetch hook refreshes the timestamp and nonce. For an unchanged manual retry, retain the same request and key. Do not switch to a new idempotency key after an unknown outcome; reconcile the original request first. A new prompt or a changed request is a new invocation, with a new key. Do not put one global idempotency key on a shared client.
OpenAI SDK: Chat Completions
import OpenAI from "openai";
const openai = new OpenAI({
baseURL: "https://api.keelapi.com/v1/proxy/openai",
apiKey: process.env.KEEL_API_KEY!,
fetch: keelFetchFor("https://api.keelapi.com/v1/proxy/openai/chat/completions"),
});
const idempotencyKey = crypto.randomUUID(); // Save with this logical request for an unchanged retry.
const response = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "Hello" }],
}, { headers: { "Idempotency-Key": idempotencyKey } });
console.log(response.choices[0]?.message.content);Use chat.completions.create on this endpoint. responses.create has a different wire contract and is not covered by this recipe.
Anthropic SDK: text Messages
import Anthropic from "@anthropic-ai/sdk";
const anthropic = new Anthropic({
baseURL: "https://api.keelapi.com/v1/proxy/anthropic",
apiKey: process.env.KEEL_API_KEY!,
fetch: keelFetchFor("https://api.keelapi.com/v1/proxy/anthropic/v1/messages"),
});
const idempotencyKey = crypto.randomUUID(); // Save with this logical request for an unchanged retry.
const message = await anthropic.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 128,
messages: [{ role: "user", content: "Hello" }],
}, { headers: { "Idempotency-Key": idempotencyKey } });
console.log(message.content);This path accepts the SDK’s X-API-Key header and returns an Anthropic-shaped Message. The request and response shape is covered by Keel’s API tests; a live Anthropic call has not been certified on the current release. A native Anthropic client configured only with a Keel base URL sends no freshness headers, so on hosted Keel use the TypeScript recipe above or a Keel SDK. The native SDK path has not been certified for every Anthropic operation. Under the tested safety policy, a tool-schema request receives a denial before provider dispatch; route application tools through a separately governed path. The original /v1/proxy/anthropic endpoint retains its existing response shape for existing callers.
Vercel AI SDK
Use ai@6 with @ai-sdk/openai-compatible@2 and the Chat Completions path. The Vercel AI SDK integration guide contains the complete server-side example; its fetch option adds both freshness headers to every request, as above. Without that option the provider sends no freshness headers and hosted Keel refuses the call. @ai-sdk/openai defaults may call the Responses API, which this model-proxy recipe does not cover.
LangChain model calls
A LangChain ChatOpenAI configured only with a Keel base URL sends no freshness headers, so hosted Keel refuses its requests (401 request_not_fresh); that configuration is not supported on hosted Keel. The Keel SDK’s LangChain adapter requests a Permit before each model call instead; see Support Surfaces for what it covers. Neither path governs a LangChain agent’s tools: each application-executed action needs its own Keel permit or managed MCP call. A model request containing a tool schema was denied under the tested safety policy, so a complete LangChain tool-calling agent is not listed as a native integration.
CLI and hosted agents
Claude Code, Codex CLI, and GitHub-hosted agents are not listed as current native integrations. Keel’s existing CLI setup flow provisions an identity and model-proxy connection; it does not automatically govern Bash, file edits, built-in tools, other connectors, or provider calls made with separate credentials. A native action-governance claim needs a version-tested path for each runtime action; a client-facing MCP gateway is one possible implementation. For a custom agent today, route each intended call through a documented Keel API and verify the result at the downstream service when the effect matters.