Resource Reference#
Configuration is made up of typed resources, and each kind has its own set of fields. This page is the field-by-field reference for every kind: which fields are required, their types, their allowed values and defaults, and a minimal working example for each. For the conceptual model behind resources and preferences, see the Overview page. For the authoring workflow and worked examples, see the Authoring Agents page.
Common Structure#
Every authored file begins with the same envelope:
kind
The resource kind, for example
ModelorAgent. Case-sensitive, and it must match the exact spelling used in this reference.schema
The schema version of the kind. The current version is
v1.metadata.id
The identifier for the resource, such as
claude-sonnet. Two resources of the same kind cannot share one, and twoMCPidentifiers cannot differ only by case, sojiraandJiraare rejected together. Whether you write it depends on the kind. A project can hold any number ofModel,Agent,MCP,KnowledgeGraph, andTraitDimensionresources, so each one needs an identifier to tell it apart from the rest. The remaining three kinds occur once at most, so they carry no identifier: every project has exactly oneProject, andDocumentSourceSettingsandCodeInterpreterare each written once or left out.
An identifier consists of letters, digits, underscores, and hyphens, and it starts with a letter. Letters can be upper or lower case. For example, claude-sonnet, deep_research, kg2, and Assistant are valid, while 2nd-model starts with a digit, deep research contains a space, company.kg contains a dot, and research! contains a symbol, so all four are rejected at deploy.
The resource kinds that surface in the Chat interface also accept two optional display fields, title and summary. Both are cosmetic labels shown in pickers and detail views, and neither affects how a request resolves. When title is omitted, the Chat interface falls back to the resource identifier.
The fields of each kind are a fixed set, and every resource forbids unknown fields. A misspelled field name, or a custom field of your own such as internalref: EDFGGA654, causes the deploy to fail rather than being silently ignored. To attach your own reference to a resource, add a YAML comment, which the parser ignores and which stays in your version-controlled files. To attach metadata to a whole deploy instead, use a deploy label, described on the CLI Reference page. For example, a comment records the internal reference without adding a field:
---
kind: Agent
schema: v1
metadata:
id: research
# internalref: EDFGGA654
entrypoint: true
---
You are a research analyst...
Writing a Description#
Several kinds also accept a description, and on two of them it is not a display field. Where title and summary are written for people, these descriptions are written for the agents. A KnowledgeGraph description is advertised to an agent alongside the graph identifier and title, so it is what the agent goes on when deciding whether to query that graph rather than another. An Agent description is what a calling agent reads when choosing among the delegates available to it. In both cases a vague description does not merely read poorly, it leads the agent to the wrong choice or to no choice at all.
Write it as a selection rule rather than a label. Say what the resource covers and when to reach for it. This description gives an agent enough to act on:
description: Company product and organizational graph. Query it for team ownership, reporting lines, and product hierarchy.
Whereas this one names the resource without saying when it applies:
description: Company knowledge graph.
Three habits keep descriptions useful:
Name the boundary, not just the subject. What the resource does not cover is as informative as what it does, because it tells the agent when to look elsewhere.
Keep them distinct from each other. Two delegates with near-identical descriptions give a calling agent no basis to choose between them, and it will pick one more or less at random.
Describe, do not insist. Wording such as always use this first pushes an agent to reach for a resource in situations it does not fit. State the fit and let the agent judge.
A description is optional on most kinds, but it is required on any agent with delegate: true. A deploy fails without one, because a calling agent would have nothing to go on when choosing among delegates.
Predicate Syntax for Constraints#
Both the Project and an Agent accept a constrains block, which restricts the values a preference path allows. The block is keyed by preference path, and each entry is a predicate written in the small language below. Each key must be a path your configuration declares, so a misspelled path, or a trait.<dimension> for a dimension you have not published, fails the deploy rather than restricting nothing.
Predicate |
Meaning |
|---|---|
|
The value must be one of a list, for example |
|
The value must not be one of a list. |
|
Numeric comparisons: greater than, greater than or equal, less than, less than or equal. |
|
The value must match an anchored regular expression, for example |
Three paths constrained at once:
constrains:
inference.model:
in: [claude-sonnet, claude-opus]
source.documents.limit:
le: 50
trait.style:
not_in: [verbose]
A predicate can carry several clauses, and a value has to satisfy all of them. This one admits a limit from 10 to 50:
constrains:
source.documents.limit:
ge: 10
le: 50
Clauses that contradict each other admit no value at all, so genai lint rejects them rather than letting you deploy a path nothing can satisfy. ge: 50 together with lt: 10 is reported as unsatisfiable.
On a tri-state toggle, auto stands for true or false, so a predicate with no in list that excludes the state auto stands for must exclude auto too. not_in: [true] on a published graph, where auto means true, would still let a request for auto put the graph in scope, so it is rejected. Write not_in: [true, "auto"], or list the allowed states with in. Also give the path a value inside the restriction, on the agent or the project, or pin it: a restriction that no configured value satisfies is rejected too. On the project, the project value itself must fall inside, because a conversation with no assistant selected would have no admissible value to use.
A value that falls outside a predicate does not fail the request. The resolver passes over it and carries on to the next source, so an agent that constrains inference.model to two models simply ignores a user who asks for a third, and answers with whatever the agent or the project prefers instead.
Note
The pattern in a matches constraint is an anchored regular expression that must match the entire value. It is a different language from the shell-style wildcards used in conditional segments of agent instructions.
When two restrictions on the same path use matches, the project restriction and an agent restriction, or two restrictions combined through extends, a value has to match both patterns, and the two must be valid together. A flag such as (?i) at the start of one pattern fails the deploy in that case. Scope it to a group instead, as in (?i:claude-.*).
Authentication#
The Model and KnowledgeGraph kinds reach external services through an auth block that accepts any of the variants below. The CodeInterpreter kind authenticates the same way, but accepts only the bearer variant, nested under backend.auth. The block never contains credential material. Instead, a variant that needs a credential carries a secret handle, a name bound to a credential stored securely on the cluster. The platform resolves the handle at request time. For how to register a handle, see the Registering a Handle section.
When the auth block is omitted, the connection is unauthenticated. When it is present, type is required and selects one of the following variants.
|
Fields |
Description |
|---|---|---|
|
|
Static bearer-token authentication. |
|
|
HTTP basic authentication. |
|
|
AWS Signature Version 4 authentication, for example for Amazon Bedrock. |
|
none |
OAuth authentication, where each user authorizes the service themselves rather than sharing one credential. The platform stores each user token and uses the one belonging to the person making the request, so there is no |
A minimal bearer block:
auth:
type: bearer
secret: anthropic_token
Registering a Handle#
A handle is a name, not a value. You author the name in the auth block, and the name travels in the deployed configuration. The credential itself is bound to the handle separately, on the cluster, and never appears in the project. This split means the person who authors the configuration does not need to hold the provider API key, and the key is never committed to version control.
Registering a handle is a two-part responsibility:
You (the configuration author) choose a handle name and reference it from the
authblock of aModel,KnowledgeGraph, orCodeInterpreterresource.An operator binds that handle to the real credential on the cluster, using the mechanism below. Binding is a deployment operation, so it is performed by whoever manages the GenAI service configuration, not from within the project.
The operator provides the credential to the GenAI service as an environment variable whose name is SQ_ followed by the handle name in uppercase. For the handle anthropic_token, the variable is SQ_ANTHROPIC_TOKEN. The variable set depends on the auth type:
|
Environment variables for a handle named |
|---|---|
|
|
|
|
|
|
|
None. Each user authorizes the service themselves, so there is no shared credential and no handle to bind. |
Deploy verifies that every referenced handle resolves and that the resolved credential matches the auth type. A handle that is missing or unbound fails the deploy with a 422 response, and the previous snapshot stays in place. A handle that resolves at deploy time but is later removed causes the resource that references it to become unavailable at runtime.
Rotating or revoking a credential is done at the cluster, by replacing the bound value. The project is not affected and does not need to be redeployed, because it references the handle name, not the value.
Project#
The project manifest, introduced on the Overview page. Every configuration must have exactly one, so a deploy fails if it carries none and fails again if it carries two. A Project has no metadata.id, and by convention it is written in a file named project.yaml, although the platform reads the kind rather than the file name.
Field |
Type |
Requirement |
Description |
|---|---|---|---|
|
map of path to value |
Optional, empty by default |
Project-wide soft defaults, keyed by preference path. |
|
map of path to predicate |
Optional, empty by default |
Project-wide restrictions on which values a path allows. See the Predicate Syntax for Constraints section. |
|
map of path to value |
Optional, empty by default |
Project-wide locked values that nothing can override. |
|
string |
Optional |
A default chat body used when a request resolves without a selected agent. |
|
object |
Optional, defaults listed below |
Policy that keeps each turn within the model context window. |
|
object |
Optional, no rules by default |
Operator approval policy for tool calls. |
|
object |
Optional, no rules by default |
Which Studio plugin tools agents can see. See the Studio Plugin Tools section. |
|
string |
Optional |
Display label and description. |
The context_budget object controls two independent safety behaviors. It is policy, not a preference, so a user or a request cannot turn it off.
Field |
Type |
Default |
Description |
|---|---|---|---|
|
boolean |
|
Clear older tool results once their token count crosses the trigger. |
|
integer |
|
Token count above which older tool results are cleared. Match it to the window of the models you run. |
|
integer |
|
Number of most-recent tool results never cleared by pruning. |
|
boolean |
|
Drop the oldest whole turns when the input approaches the model context window. |
|
number |
|
Fraction of the context window that turn truncation aims to stay below. |
|
integer |
|
Number of most-recent turns that turn truncation always preserves. |
The hitl object holds an ordered list of approval rules. Each rule matches a tool by name and assigns a disposition. The last matching rule wins. For what the dispositions mean and how these rules combine with the rules on a scheduled task, see the Scheduled Tasks and Approvals page.
Field |
Type |
Requirement |
Description |
|---|---|---|---|
|
string |
Required |
A glob matched against the tool name visible to the model. |
|
string |
Required |
One of |
Example, the manifest authored as project.yaml:
kind: Project
schema: v1
title: Research workspace
prefers:
inference.model: claude-sonnet
context_budget:
turn_truncation: true
tool_output_pruning: true
hitl:
rules:
- pattern: "delete_*"
disposition: reject
- pattern: "send_email"
disposition: approve
Model#
An agent, a user, or a request selects a model through the inference.model preference, whose value is the metadata.id of a Model resource.
Field |
Type |
Requirement |
Description |
|---|---|---|---|
|
string |
Required |
The model provider, for example |
|
string |
Required |
The model identifier as the provider publishes it, for example |
|
object |
Optional |
The authentication block used to reach the provider. See the Authentication section. |
|
string |
Optional |
Prose describing the model, recorded in the configuration for your own reference. |
|
string |
Optional |
A label for grouping models in the Chat interface. |
|
map |
Optional, empty by default |
Additional provider parameters passed through to the model backend. |
|
boolean |
Optional, default |
Authorizes the platform to send reasoning parameters to this model. Leave off unless the model supports reasoning at the provider and version you have configured. |
|
boolean |
Optional, default |
Authorizes this model to receive image content. Leave off unless the model accepts images at the provider and version you have configured. |
|
integer |
Optional, the provider profile by default |
Maximum input tokens the model accepts, used by the context budget. Set it to the real window for smaller-window models so truncation engages before the provider rejects the request. |
|
string |
Optional |
Display label and description. |
Example, a model authored as models/claude-sonnet.yaml:
kind: Model
schema: v1
metadata:
id: claude-sonnet
provider: anthropic
model_name: claude-sonnet-5
auth:
type: bearer
secret: anthropic_token
Model Providers#
On a Model resource, provider selects which backend the platform routes to. The platform supports the following providers. A provider value outside this set is not rejected at deploy time. Instead, the model fails when a request first tries to use it, so check the spelling against the table below.
|
Example |
Notes |
|---|---|---|
|
|
Anthropic Claude models. |
|
the OpenAI model ID |
OpenAI models. |
|
the Gemini model ID |
Google Gemini models. |
|
the Azure deployment name |
Azure OpenAI. Supply the endpoint, API version, and deployment name through |
|
the Cerebras model ID |
Cerebras-hosted models. |
Write model_name exactly as the provider spells it. The platform does not check the name at deploy, so a typo surfaces only when a request first tries to use the model. Take the value from the model list in the API documentation of the provider rather than from memory or from another tool, because providers rename and retire models over time.
Each supported provider authenticates with a bearer token. Set auth.type to bearer and reference a secret handle bound to the provider API key. For the full authentication reference, see the Authentication section.
Provider-specific parameters, such as sampling options or the Azure endpoint, API version, and deployment name, are passed through backend_kwargs. The platform forwards these to the provider as written, and a user or a request cannot override them.
Example, an OpenAI model authored as models/gpt-5.yaml:
kind: Model
schema: v1
metadata:
id: gpt-5
provider: openai
model_name: gpt-5.2
auth:
type: bearer
secret: openai_token
Example, a Google Gemini model with a provider-specific parameter, authored as models/gemini-flash.yaml:
kind: Model
schema: v1
metadata:
id: gemini-flash
provider: google
model_name: gemini-3.5-flash
auth:
type: bearer
secret: google_token
backend_kwargs:
temperature: 0.2
Agent#
An agent is authored in one of two file formats. A .md agent carries its instructions as the markdown body after the frontmatter. A .yaml agent carries configuration only and is typically used as a shared template through extends.
Field |
Type |
Requirement |
Description |
|---|---|---|---|
|
map of path to value |
Optional, empty by default |
Soft defaults the user can override. |
|
map of path to predicate |
Optional, empty by default |
Restrictions on which values a path allows for this agent. See the Predicate Syntax for Constraints section. |
|
map of path to value |
Optional, empty by default |
Locked values that nothing can override. |
|
list of identifiers |
Optional, empty by default |
Parent agents whose configuration folds into this one. Configuration composes through |
|
string |
Required with |
Prose that a calling agent reads to decide whether to call this agent. |
|
boolean |
Optional, default |
Whether the agent appears in the conversation picker for users to select. |
|
boolean |
Optional, default |
Whether another agent can call this agent as a subagent. |
|
integer |
Optional |
Display order in the picker for entrypoints, ascending, starting at zero. |
|
string |
Optional |
A static first message the agent speaks before the user does. When absent, the user starts the conversation. |
|
boolean |
Optional, default |
When set, selecting this agent fixes it for the conversation, and later turns ignore attempts to switch agents. |
|
object |
Optional, no rules by default |
Which Studio plugin tools this agent can see, within what the project allows. See the Studio Plugin Tools section. |
|
string |
Optional |
Display label and description. |
Example, an agent authored as a markdown file named agents/assistant.md. The --- lines fence the frontmatter, which is YAML and holds the fields listed above. Everything after the closing fence is markdown, and it becomes the agent instructions:
---
kind: Agent
schema: v1
metadata:
id: assistant
entrypoint: true
prefers:
inference.model: claude-sonnet
---
You are a helpful assistant. Answer questions clearly and concisely.
Example, a template authored as agents/house-style.yaml. A .yaml agent has no fences and no instructions, so the whole file is the field block. Because entrypoint and delegate both default to false, a template never appears in the picker and no agent can call it as a subagent:
kind: Agent
schema: v1
metadata:
id: house-style
prefers:
trait.style: concise
pins:
capability.code_interpreter.enabled: false
Another agent, agents/research.md, folds that template in through extends and adds its own instructions:
---
kind: Agent
schema: v1
metadata:
id: research
entrypoint: true
extends:
- house-style
---
You are a research analyst. Cite a source for every claim.
TraitDimension#
A TraitDimension resource groups reusable prompt fragments under one name. The metadata.id is the dimension name, and it appears in preference paths as trait.<id>. Agents and the project activate a trait through the trait.<dimension> preference.
Field |
Type |
Requirement |
Description |
|---|---|---|---|
|
map of identifier to trait |
Required |
The trait entries in the dimension, each keyed by a unique identifier. |
Each trait entry carries the following fields:
Field |
Type |
Requirement |
Description |
|---|---|---|---|
|
string |
Required |
The prose appended to the agent instructions when this trait is active. |
|
string |
Optional |
Display label and description. |
Example, a dimension authored as trait-dimensions/style.yaml. Markdown is only for agents, so every other kind, including this one, is written as YAML with no frontmatter fences:
kind: TraitDimension
schema: v1
metadata:
id: style
traits:
concise:
prompt_fragment: |
Keep your responses tight. No preamble, no recap.
detailed:
prompt_fragment: |
Be exhaustive. Walk through your reasoning and cite each step.
KnowledgeGraph#
A KnowledgeGraph resource points at a SPARQL endpoint the agents can query. Retrieval is active only when source.knowledge_graph.enabled resolves to true. Which of the published graphs are then in scope is a preference, with one path per graph: a graph is in scope unless source.knowledge_graph.graphs.<id>.enabled resolves to false. A graph out of scope cannot be queried, even by a call that names it. For both paths, see the Preference Reference page.
Field |
Type |
Requirement |
Description |
|---|---|---|---|
|
URL |
Required |
The SPARQL query endpoint URL. |
|
object |
Optional |
The authentication block used to reach the endpoint. See the Authentication section. |
|
integer |
Optional, default |
Query timeout in seconds. |
|
string |
Optional, default |
Language code used for the query. |
|
string |
Optional, default |
Result format returned to the agent. |
|
string |
Optional, default |
Query variant used against the endpoint. |
|
map of string to string |
Optional, empty by default |
Namespace prefixes made available to queries. |
|
string |
Optional |
Prose describing the graph, advertised to the agents that can query it. |
|
string |
Optional |
Display label and description. |
Example, a graph authored as knowledge-graphs/company_kg.yaml:
kind: KnowledgeGraph
schema: v1
metadata:
id: company_kg
endpoint:
sparql: https://kg.example.com/sparql
auth:
type: bearer
secret: kg_token
description: Company organizational and product knowledge graph.
To give a graph to one agent by default, set a false floor in the prefers block of project.yaml:
prefers:
source.knowledge_graph.graphs.company_kg.enabled: false
Then set true in the prefers block of the agent that should query it:
prefers:
source.knowledge_graph.graphs.company_kg.enabled: true
A prefers value is a default that a user or a request can change, so this does not keep the other agents off the graph. To do that, pin the path to false on each of them. The pins cover every conversation with an assistant selected. A conversation with no assistant selected uses the project settings alone, where the false floor stays a default that a user or a request can change. Write the path as one key: the nested form source.knowledge_graph.graphs.company_kg: {enabled: false} fails the deploy.
MCP#
An MCP resource points at an external Model Context Protocol server. Its tools are active only when capability.mcp.enabled resolves to true, at which point every MCP resource the project publishes becomes reachable.
Field |
Type |
Requirement |
Description |
|---|---|---|---|
|
URL |
Required |
The server URL. |
|
string |
Optional, default |
The transport used to reach the server, either |
|
string |
Optional, default |
How the platform authenticates to the server. One of |
|
string |
Required with |
The secret handle resolving to the shared bearer token. Not accepted for the other two modes. |
|
boolean |
Optional, default |
Whether tool calls on this server require human approval before they run. |
|
map of string to boolean |
Optional, empty by default |
Per-tool approval overrides, keyed by the upstream tool name. A value of |
|
string |
Optional |
Prose describing the server, recorded in the configuration for your own reference. The tools the server exposes carry their own descriptions, which is what an agent reads when it decides to call one. |
|
string |
Optional |
Display label and description. |
The three auth_mode values are:
anonymous
The server is open or trusts the cluster network. No handle is declared.
static_bearer
A single shared bearer token, named by
bearer_handle.per_user_oauth
Each user authorizes the server individually. The platform looks up the per-user token at runtime, so no handle is declared.
Example, a server authored as mcp/tickets.yaml:
kind: MCP
schema: v1
metadata:
id: tickets
url: https://mcp.example.com/
transport: streamable_http
auth_mode: static_bearer
bearer_handle: tickets_token
requires_approval: true
Studio Plugin Tools#
Tools that Squirro Studio plugins expose reach agents through one channel, which capability.studio_mcp.enabled switches on or off as a whole. The studio_mcp block on Project and on Agent chooses which of those tools each agent sees. When no level authors the block, every agent with the channel switched on sees every Studio plugin tool that the user has permission to use. The rules only narrow that set. They cannot give a user a tool that the plugin permission check withholds.
The block holds a single tools object:
Field |
Type |
Requirement |
Description |
|---|---|---|---|
|
list of rules |
Optional, unset by default |
When set, a tool must match one of these rules. An empty list hides every tool. |
|
list of rules |
Optional, empty by default |
A tool matching any of these rules is hidden, even when an |
|
list of rules |
Optional, empty by default, |
A tool matching any of these rules is hidden from every agent whose own |
Each rule names a plugin, a tool, or both:
Field |
Type |
Description |
|---|---|---|
|
string |
A glob pattern matched against the name of the Studio plugin. When omitted, the rule matches every plugin. |
|
string |
A glob pattern matched against the tool name the plugin registers, which is the function name unless the plugin sets |
A rule must set at least one of the two fields, and neither can be blank. To match every tool, write plugin: "*". Patterns are case-sensitive.
How Rules Combine#
A tool reaches an agent only when it passes each of these levels in turn:
The rules on
Project.The rules on each agent that the agent extends, starting with the most distant one.
The rules on the agent itself.
Every level can only remove tools, so an agent never sees a tool that the project or one of its parent agents hides. A hidden tool stays hidden until an allow rule on the agent, or on an agent it extends, names it. A deny rule on the project still wins over that allow rule.
Only an allow rule without glob characters (*, ? or [) names a hidden tool, for example plugin: admin or plugin: admin with tool: reset. A glob rule such as plugin: "*" or plugin: "adm*" still decides which other tools the agent sees, but it never shows a hidden tool. Otherwise a broad rule would show every hidden plugin at once. A rule that names only a tool, such as tool: read, is literal too, so it shows that tool in every plugin that hides it. To show a tool of one hidden plugin only, name the plugin as well.
An agent that another agent calls as a subagent applies the rules of the agent that called it first, then its own. A subagent therefore never sees a tool that the rules of the calling agent hide. A subagent that is called through another subagent applies the rules of every agent along the way.
A subagent can see a tool that the calling agent does not see in two cases. The first is a hidden tool. The allow rules of the calling agent do not count as naming a hidden tool. A subagent sees a hidden tool only when its own allow rules, or those of an agent it extends, name the tool, and it then sees the tool even if the calling agent does not.
The second case is a calling agent with the Studio channel off: its rules reach its subagents only when the channel is on for it. Setting capability.studio_mcp.enabled to false on an agent removes its Studio tools, but a subagent that it calls with the channel on, the default subagent included, sees Studio tools under the project rules and its own rules alone.
A hidden tool is not offered to the model, and a call to it fails. The rules decide only which tools an agent sees. Whether a visible tool asks for approval before it runs is set by the plugin author through requires_approval on @plugin.tool, and the project cannot change it.
Deploy fails when a rule sets neither field or leaves one blank, when a pattern holds a character that no Studio tool name can carry, and when an agent authors hidden. genai lint also advises when an agent allow rule names a plugin that the project denies outright or leaves out of its own allow rules, because that agent gets nothing from the plugin, and when a level that pins capability.studio_mcp.enabled to false, or constrains it so that neither true nor "auto" is admitted, also carries rules. A prefers value of false does not trigger that advice, because a user, a request or another level can change it.
Studio sends each tool to agents under one name that joins the plugin name and the tool name. In that name, every character other than a letter, a digit, _ and - becomes _, so write rules against that form. For example, crm_ matches a plugin named crmé, and a pattern that contains whitespace or é fails the deploy.
Some names can be read in more than one way. In that case the rules fail closed. A deny or hidden rule applies when it matches any reading, and an allow rule applies only when it matches every reading. Three kinds of name are affected:
A plugin name that contains two consecutive underscores, or that ends with an underscore. A
denyrule on that plugin still hides its tools. Anallowrule that names only that plugin does not show them, but a pattern such ascrm*does.A tool name that contains two consecutive underscores or starts with an underscore, such as
get__dataor_helper. Adenyrule on the plugin still hides the tool. Anallowrule that names only the plugin does not show it, but a pattern such ascrm*does.A plugin name and a tool name that together are longer than 55 characters. Studio limits the joined name to 64 characters and shortens a longer one, so the end of the name is unknown. A
denyorhiddenrule on the plugin still applies. Anallowrule shows the tool only through a pattern that ends in*and covers the rest of the name, such asplugin: "reporting*"with notoolpattern. Anallowrule that names the plugin, or the plugin and the tool, does not show the tool. A plugin name and a tool name that together are exactly 55 characters long are treated the same way when the tool name ends in an underscore and eight characters from0to9andatof, such as a date like_20241231, because a shortened name ends the same way.
A * pattern in an allow rule matches every plugin that starts the same way, so plugin: "reporting*" also shows tools of a plugin named reporting_internal.
A glob never names a hidden tool, so for these names an agent opts into a hidden tool only with one rule without glob characters for each reading. In the first two cases, the readings split the name at each pair of underscores. For example, studio_crm___run reads as plugin crm with tool _run, or as plugin crm_ with tool run, so the agent needs both plugin: crm and plugin: crm_. In the third case no rule names the shortened part, so a hidden tool with a name that long stays hidden from every agent.
Example, a project that keeps every tool whose name contains delete away from all agents and keeps the admin plugin for agents that ask for it, authored in project.yaml:
kind: Project
schema: v1
studio_mcp:
tools:
deny:
- tool: "*delete*"
hidden:
- plugin: admin
An agent that sees only the admin and crm plugins, authored in the frontmatter of agents/operations.md:
---
kind: Agent
schema: v1
metadata:
id: operations
entrypoint: true
studio_mcp:
tools:
allow:
- plugin: admin
- plugin: crm
---
You help the operations team run day-to-day tasks.
Every other agent in that project sees all Studio plugin tools except those from admin and those whose name contains delete.
DocumentSourceSettings#
A DocumentSourceSettings resource sets how the agents search and read documents. A project has one at most, and it carries no metadata.id. The implementation field selects the retrieval engine for the whole deployment, which changes the tools an agent sees and the citation contract, so it is a deployment-wide decision rather than a per-turn setting.
Field |
Type |
Requirement |
Description |
|---|---|---|---|
|
string |
Optional, default |
The retrieval engine. |
|
integer |
Optional, default |
Number of results a search returns. Applies to the |
|
integer |
Optional, default |
Token budget for a single fetch. Applies to the |
|
integer |
Optional, default |
Per-request retrieval timeout in seconds. Applies to both engines. |
The legacy engine accepts additional advanced tuning fields: retrieval_mode, fetch_top_n_search, fetch_top_n_summarize, context_expansion, intent_filters, semantic_profile_config, phrase_filter, and retrieval_budget_tokens. These fields have no effect under the split engine, and genai lint warns when a split deployment sets them. Squirro recommends the split engine for new projects.
Example, the settings authored as document-source-settings.yaml:
kind: DocumentSourceSettings
schema: v1
implementation: split
default_search_count: 10
CodeInterpreter#
A CodeInterpreter resource sets up the sandbox the agents run code in. A project has one at most, and it carries no metadata.id. Code execution is active only when capability.code_interpreter.enabled resolves to true.
The backend object selects the execution provider through its type field. The supported backend is openai.
Field |
Type |
Requirement |
Description |
|---|---|---|---|
|
string |
Required |
The execution provider. The supported value is |
|
string |
Required |
The model identifier as the provider publishes it, used for code execution. As with a |
|
object |
Required |
A |
Example, the sandbox configuration authored as code-interpreter.yaml:
kind: CodeInterpreter
schema: v1
backend:
type: openai
model_name: gpt-5.2
auth:
type: bearer
secret: openai_token