LLM Configuration Definition
The LLM Configuration enables the use of external LLM services for an organization. There is a single LLM configuration per org, maintained by org admins on the Connect / LLM page of the Web Console, and it can be managed as configuration-as-code:
cs llm config export # print the current LLM config to stdout
cs llm config import FILE # import the LLM config from a file, or from stdin when FILE is -
This page describes every field of that document. For a task-oriented walkthrough, see Manage LLM Configurations.
Structure Overview
providers: # LLM service providers, keyed by name
anthropic-main:
anthropic:
api_key: secret:anthropic-key
models: # The models exposed to clients and agents
- provider: anthropic-main
name: claude-sonnet-4-6
purposes: [GENERIC, CODING]
aliases: [default]
session_config: # Retention and auto archiving of conversations
retention: 2592000s
auto_archive: 604800s
sandbox_config: # Auto configuration of LLM clients in workspaces
clients:
anthropic:
provider: anthropic-main
discovery: # Org-level agent and MCP server authorization
named_mcp_servers:
github:
external:
url: https://api.githubcopilot.com/mcp/
global_mcp_servers:
- ref: github
Top-Level Fields
| Field | Type | Description |
|---|---|---|
providers |
map[string]Provider | The configured providers, keyed by provider name. |
models |
Model[] | The configured models. At least one GENERIC model must be defined to enable the AI features. |
session_config |
SessionConfig | Settings related to LLM sessions. |
sandbox_config |
SandboxConfig | Automatic configuration of LLM clients inside sandboxes. |
discovery |
Discovery | The authorized agent and MCP resources shared at org level, and the policy for MCP servers that are not authorized here. |
Every defined provider also contributes to the LLM passthrough API, so that clients never need a provider-specific authentication token of their own:
- outside a sandbox:
https://SYSTEM-DNS/ext/llm/api/orgs/ORG/passthrough/PROVIDER/... - inside a workspace:
http://PROVIDER.proxy.llm.g.sandbox/
Provider
The definition of an LLM service provider. Exactly one provider type must be specified per entry.
| Field | Type | Description |
|---|---|---|
openai |
Provider.OpenAI | An OpenAI, or OpenAI API compatible, service. |
anthropic |
Provider.Anthropic | An Anthropic, or Anthropic API compatible, service. |
gemini |
Provider.Gemini | The Google Gemini API. |
ollama |
Provider.Ollama | The Ollama service, hosted by Ollama or by the user. |
vertex_ai |
Provider.VertexAI | Google Cloud Vertex AI. |
bedrock |
Provider.Bedrock | AWS Bedrock. |
An API key should normally be stored as a Secret — an Admin Only secret is recommended — and referenced from the configuration as secret:NAME rather than written in plain text.
Provider.OpenAI
| Field | Type | Description |
|---|---|---|
api_key |
string | The API key, usually in the form secret:NAME. |
base_url |
string | Overrides the default base URL https://api.openai.com/v1. When specified, the provider is effectively an OpenAI API compatible service. |
api |
enum | Which API flavor to use: DEFAULT (the responses API) or CHAT_COMPLETIONS. Select CHAT_COMPLETIONS for a compatible service that only implements the chat/completions API. |
http_headers |
string[] | Additional HTTP headers to insert. Each item is HeaderName: Value.... |
http_queries |
string[] | Additional query parameters for the HTTP request. Each item is key=value or key, without escaping. |
Example — an OpenAI API compatible service:
providers:
openrouter:
openai:
api_key: secret:openrouter-key
base_url: https://openrouter.ai/api/v1
api: CHAT_COMPLETIONS
Provider.Anthropic
| Field | Type | Description |
|---|---|---|
api_key |
string | The API key, usually in the form secret:NAME. |
base_url |
string | Overrides the default base URL https://api.anthropic.com/. When specified, the provider is effectively an Anthropic API compatible service. |
http_headers |
string[] | Additional HTTP headers to insert. Each item is HeaderName: Value.... |
http_queries |
string[] | Additional query parameters for the HTTP request. Each item is key=value or key, without escaping. |
Provider.Gemini
| Field | Type | Description |
|---|---|---|
api_key |
string | The API key, usually in the form secret:NAME. |
Provider.Ollama
| Field | Type | Description |
|---|---|---|
base_url |
string | Overrides the default base URL https://ollama.com. When specified, the provider is user hosted. |
api_key |
string | The API key, usually in the form secret:NAME. |
http_headers |
string[] | Additional HTTP headers to insert. Each item is HeaderName: Value.... |
http_queries |
string[] | Additional query parameters for the HTTP request. Each item is key=value or key, without escaping. |
Provider.VertexAI
On GCP, all fields are optional, as they can be fetched from the metadata service. Specify them only to access Vertex AI in a project or region different from where the system is deployed.
| Field | Type | Description |
|---|---|---|
project |
string | The GCP project hosting Vertex AI. |
location |
string | The Vertex AI location, such as us-central1. |
identity_federation |
VertexAI.IdentityFederation | Per-user identity federation settings. |
VertexAI.IdentityFederation
Configures Workload Identity Federation, so that the per-user JWTs issued by Crafting are exchanged for GCP access tokens. When enabled, each request uses the calling user's JWT as the subject token, which makes usage attributable to individual users.
| Field | Type | Description |
|---|---|---|
enabled |
boolean | Enable identity federation for this provider. |
audience |
string | Required if enabled. The full STS audience resource name, e.g. //iam.googleapis.com/projects/{number}/locations/global/workloadIdentityPools/{pool}/providers/{provider}. |
service_account_impersonation_url |
string | Required if enabled. The service account impersonation URL, e.g. https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/{email}:generateAccessToken. |
token_url |
string | The STS token exchange URL. Defaults to https://sts.googleapis.com/v1/token when empty. |
See Setup Identity Federation for how the trust is established on the cloud side.
Provider.Bedrock
| Field | Type | Description |
|---|---|---|
region |
string | The AWS region serving Bedrock. Optional. |
identity_federation |
Bedrock.IdentityFederation | Per-user identity federation settings. |
Bedrock.IdentityFederation
Configures AWS Web Identity Federation, so that the per-user JWTs issued by Crafting are exchanged for temporary AWS credentials through AssumeRoleWithWebIdentity. When enabled, each request is signed with per-user STS credentials.
| Field | Type | Description |
|---|---|---|
enabled |
boolean | Enable identity federation for this provider. |
role_arn |
string | Required if enabled. The ARN of the IAM role to assume, e.g. arn:aws:iam::123456789012:role/my-bedrock-role. |
Model
A model exposed by one of the configured providers.
| Field | Type | Description |
|---|---|---|
provider |
string | Required. The name of the provider, as used as the key in providers. |
name |
string | Required. The name of the model, specific to the provider. |
purposes |
enum[] | The use cases this model serves: GENERIC, FAST, CODING, CODING_FIM, CODING_NES. |
aliases |
string[] | Alternative names for selecting the model, in addition to a purpose and provider:name. |
dialect |
Model.Dialect | The general categorization of the model. Clients may rely on this to craft optimized prompts. |
properties |
Model.Properties | Common properties used as information and hints for clients to optimize usage. |
How a Model Is Selected
A client selects a model with a selector, resolved against the models list in one of three ways:
- By purpose, case insensitive. The first model that contains the purpose matches. If none matches:
CODING_FIMandCODING_NEShave no fallback — the corresponding features are disabled;- every other purpose falls back to
GENERIC. - By
provider:name, case sensitive, matching one specific model, with no fallback. - By alias, case insensitive. The first model that contains the alias matches, with no fallback.
An empty selector is treated as the GENERIC purpose. Because ordering decides the winner, put the preferred model for a purpose first in the list.
Model.Dialect
The general model category, used as a hint for optimizing prompts.
| Field | Type | Description |
|---|---|---|
source |
string | The name of the source providing the model, e.g. openai, anthropic, google. May be empty. |
model_class |
string | The general model class, e.g. gpt for source=openai, claude or claude-sonnet for source=anthropic, qwen for source=ollama or an empty source. |
sub_class |
string | Detailed category information, specific to the model. |
Model.Properties
| Field | Type | Description |
|---|---|---|
context_window_limit |
integer | The maximum number of tokens allowed in the context window. Most providers do not report this value through their API, so Crafting applies a reasonable default. Set an explicit value to make auto-summarization trigger more accurately, or a value of zero or below to disable it. |
Example:
models:
- provider: anthropic-main
name: claude-sonnet-4-6
purposes: [GENERIC, CODING]
aliases: [default, smart]
dialect:
source: anthropic
model_class: claude-sonnet
properties:
context_window_limit: 200000
- provider: anthropic-main
name: claude-haiku-4-5
purposes: [FAST]
Model Mapping
A Model Mapping overlays the model selection defined by models, which is the base mapping from a selector — a purpose, an alias, or provider:name — to an actual model. It changes which model answers a selector, without changing how selectors are resolved.
| Field | Type | Description |
|---|---|---|
mappings |
map[string]string | The remapping configuration. The key is the selector requested by the sampler, and the value is the selector to use instead. Both sides accept the same forms as models selectors: an empty string (treated as GENERIC), a purpose, an alias, or provider:name. The value is resolved against models as usual. |
Model mappings are used by an AI Agent to pin or downgrade the models used in its conversations.
Example — run everything generic on the fast model, and coding on a named model:
model_mapping:
mappings:
generic: fast
coding: anthropic-main:claude-sonnet-4-6
SessionConfig
Settings related to LLM sessions.
| Field | Type | Description |
|---|---|---|
retention |
duration | How long an interactive or archived session may persist since its last update, before it is deleted automatically. |
auto_archive |
duration | If non-zero, auto archiving is enabled. A session that has been finished for longer than this period is archived, releasing all linked resources. An archived session no longer accepts further conversations. |
Durations are expressed in seconds with an s suffix, e.g. 604800s for seven days.
Archiving is what releases the sandboxes created as an agent's execution environment, so auto_archive is the main control on the cost left behind by idle conversations. See Agentic Sessions for what archiving does to a conversation.
Example:
session_config:
retention: 2592000s # 30 days
auto_archive: 604800s # 7 days
SandboxConfig
Automatically sets up sandboxes to use LLM clients without further configuration.
| Field | Type | Description |
|---|---|---|
clients |
SandboxConfig.Clients | Auto configuration for LLM clients, such as coding CLIs, by injecting the related environment variables. |
SandboxConfig.Clients
Selects one provider for each supported client type. The client is configured against that provider's passthrough API inside the workspaces, so no API key is exposed to the workspace.
| Field | Type | Description |
|---|---|---|
anthropic |
Clients.Anthropic | The provider used by Anthropic API clients. |
openai |
Clients.OpenAI | The provider used by OpenAI API clients. |
gemini |
Clients.Gemini | The provider used by Gemini API clients. |
ollama |
Clients.Ollama | The provider used by Ollama API clients. |
Clients.Anthropic
| Field | Type | Description |
|---|---|---|
provider |
string | Required. The name of an anthropic provider defined in providers. |
Clients.OpenAI
| Field | Type | Description |
|---|---|---|
provider |
string | Required. The name of an openai provider defined in providers. |
Clients.Gemini
| Field | Type | Description |
|---|---|---|
provider |
string | Required. The name of a gemini provider defined in providers. |
Clients.Ollama
| Field | Type | Description |
|---|---|---|
provider |
string | Required. The name of an ollama provider defined in providers. |
Example:
sandbox_config:
clients:
anthropic:
provider: anthropic-main
openai:
provider: openrouter
Discovery
Discovery of agent and MCP information from existing sandboxes, shared within the org. An org admin must explicitly authorize the agents and MCP servers exposed by templates and sandboxes before they are shared with other agents at org level.
| Field | Type | Description |
|---|---|---|
named_mcp_servers |
map[string]Discovery.MCPServer | The authorized, named MCP server definitions — the Authorized MCP Servers list. They can be referenced elsewhere by name, and are not effective until referenced. |
global_mcp_servers |
Discovery.MCPServer[] | The MCP servers that can be used globally in the org — the Globally Activated MCP Servers list. These are published in the mcp.json file of the sandbox metadata folder. |
sandbox_agents |
Discovery.SandboxAgents | The authorized agents defined in templates, which can be discovered and used globally in the org. |
mcp_server_policy |
Discovery.MCPServerPolicy | The policy for using custom MCP servers that are not predefined in named_mcp_servers. If unspecified, no custom MCP server is allowed, as if an empty policy had been specified. |
Every server in named_mcp_servers also gets a dedicated in-workspace endpoint at http://NAME.mcp.llm.g.sandbox. See MCP Servers.
Discovery.MCPServer
An MCP server entry. Exactly one of sandbox, external, or ref must be specified.
| Field | Type | Description |
|---|---|---|
sandbox |
string | The name of the sandbox exposing MCP servers, including the folder path when the sandbox is in a folder. The endpoints remain available to all clients querying discovery regardless of the sandbox running state — starting, running, or suspended — although they may be unreachable until the sandbox is running. They disappear once the sandbox is deleted, or the endpoints are no longer eligible to be used for MCP. |
external |
MCPServer.External | Use an external service. |
ref |
string | Reference an MCP server by its name in named_mcp_servers. |
tool_call_policy |
ToolCallPolicy | Restricts the tools that can be called on this MCP server. If unspecified, all tools can be called. The policy is single tier: it can only be defined together with the actual MCP server definition (sandbox or external). When ref is used, this field must be empty, and the policy of the referenced server applies as is. |
MCPServer.External
Defines an external service as an MCP server.
| Field | Type | Description |
|---|---|---|
url |
string | Required. The full URL of the server. |
protocol |
enum | The transport protocol: AUTO (default), SSE (Server-Sent Events), or STREAM. |
auth |
MCPServer.Auth | The authentication setting — a token taken from a Secret or from a user's Login Provider token. |
Example:
discovery:
named_mcp_servers:
github:
external:
url: https://api.githubcopilot.com/mcp/
auth:
token:
login:
name: github
tool_call_policy:
filters:
- name:
pattern: '*_read_*'
- name:
pattern: '*'
action: BLOCK
global_mcp_servers:
- ref: github
Discovery.MCPServerPolicy
The policy for using MCP servers that are not defined in named_mcp_servers.
The servers in named_mcp_servers are predefined and approved by the org admin, and referencing them with ref is always allowed, regardless of this policy. A developer may, however, need a custom MCP server that is not predefined — for example in the explicit list of an AI agent. This policy decides whether such a server can be used.
A custom MCP server is any MCP server defined inline rather than referenced with ref, wherever it appears, including in global_mcp_servers. Only the definitions in named_mcp_servers are exempt, since that field is the approved registry the policy is defined against.
| Field | Type | Description |
|---|---|---|
allow_custom_mcp_servers |
boolean | By default (false), only the MCP servers defined in named_mcp_servers can be used or referenced in custom agents and in global_mcp_servers. If true, custom MCP servers beyond named_mcp_servers can be used, and the blocking rules become effective. |
blocked_mcp_servers |
MCPServerPolicy.Matcher[] | Only effective when allow_custom_mcp_servers is true. The rules are applied to the MCP server URL; a matched server is blocked and will not be used. |
MCPServerPolicy.Matcher
Matches a custom MCP server definition.
| Field | Type | Description |
|---|---|---|
url |
SimpleNameMatcher | Required. Matches the URL of the MCP server. |
Example:
discovery:
mcp_server_policy:
allow_custom_mcp_servers: true
blocked_mcp_servers:
- url:
pattern: 'https://*.example.com/*'
Discovery.SandboxAgents
The authorized agents defined in templates.
| Field | Type | Description |
|---|---|---|
templates |
SandboxAgents.TemplateFilter[] | The rules matching the templates that can be used as agents. The first matching rule with an action other than NONE wins, and the rest are ignored. |
SandboxAgents.TemplateFilter
| Field | Type | Description |
|---|---|---|
name |
SimpleNameMatcher | Required. Matches the template name. |
action |
enum | NONE (default) — the rule does not decide, and evaluation continues with the next rule; ALLOW — the matched templates can be used as agents; DENY — the matched templates cannot be used as agents. |
Example — allow the agent templates of one folder and deny everything else:
discovery:
sandbox_agents:
templates:
- name:
pattern: 'agents/*'
action: ALLOW
- name:
pattern: '*'
action: DENY
Tool Call Policy
Defines the access control of tool calls, based on name matching. It is a firewall-like ruleset: the filters are evaluated in order, and the first matching filter decides the outcome. A tool call that matches no filter is allowed.
| Field | Type | Description |
|---|---|---|
filters |
ToolCallPolicy.Filter[] | The ordered list of filters. |
ToolCallPolicy.Filter
| Field | Type | Description |
|---|---|---|
name |
SimpleNameMatcher | Required. Matches the name of the tool call. |
action |
enum | DEFAULT (default) — allow the matched tool calls; BLOCK — reject the matched tool calls. |
Example — allow read-style tools only:
tool_call_policy:
filters:
- name:
pattern: '*_read_*'
- name:
pattern: '*'
action: BLOCK
Because unmatched calls are allowed, a policy that should deny by default must end with a catch-all BLOCK filter, as above. See Tool Call Policy for more examples.
SimpleNameMatcher
A simplified matcher for resource names. Exactly one of the fields must be specified. Resource names are lower-cased, so there is no option for case sensitivity.
| Field | Type | Description |
|---|---|---|
pattern |
string | Matched by filename pattern, where ? and * apply. |
regexp |
string | Matched by regular expression. |
See Also
- LLM Config — the feature overview of central LLM configuration
- Manage LLM Configurations — the org admin walkthrough
- AI Agent Definition — the agent specification that consumes these models and MCP servers
- MCP Servers — authorizing and using MCP servers in sandboxes
- Setup Identity Federation — per-user credentials for Vertex AI and Bedrock
- Secret — where provider API keys should be stored