Before you start
Every snippet runs inside anAsyncCominty context and uses these
placeholders. Replace them with your own values.
The example agent
Every recipe starts from the same agent:agent.chat, the built-in Chat agent.
It has no capabilities saved, so every capability is always, with no filter.
The recipes work the same with Hive. They do not apply to Planner, which
ignores capabilities. See Built-in agents.
Each recipe opens with its Starting point: what the agent has before the
call, and what the recipe changes.
Where a recipe says “the agent can”, it means the agent can use it if the
question calls for it. A capability that is on does not force the agent to use
it. That is why the messages name what they want (“in my documents”, “without
searching the web”): the scope enforces, the words guide the agent. See
Help the agent follow a scope.
If you use your own agent, check its capabilities on the Agents page
first. A scope on a capability your agent sets to
never returns a 422. So
does enabled=False on a capability it sets to on_request.Recipe 1: skip the web for one message
Goal: “Answer this question from what you know. Do not search the web.” Starting point: the example agent.web is always, so the agent may
search the web on any message. This recipe turns it off for one message.
- Python SDK
- HTTP
examples/11_capabilities.py
Expected behavior: The agent answers the first question from what it
already knows. Web search is off for this message, and the message says so. The
agent still sees the web tool, but a call to it would be refused. It still has
every other capability: it could search your documents or call Linear if the
question needed it. On the second message you sent no scope, so web search is
back, and the message asks for it (“online”).
Recipe 2: answer from one source, then one document
Goal: “Summarize only the 2024 board deck.” Starting point: the example agent.indexed_documents is always, with no
filter, so every source is searchable. This recipe narrows one message to a
source, then the next one to a document.
Start by limiting the message to the source that holds your board decks. Copy
the source ID from the Documents page.
- Python SDK
- HTTP
- Python SDK
- HTTP
examples/11_capabilities.py
Expected behavior: In the first message, the agent searches only the source
you named. Documents from your other sources cannot show up in its answer, even
if they mention board decks. In the second message, it reads only the 2024 deck
and summarizes that one file. A different message in the same thread, without
the scope, searches every source again.
A scope that carries only
document_ids focuses the message on those
documents. It does not keep the thread’s source_ids.Recipe 3: keep some connections, or none
Goal: “Answer without calling Linear.” Or: “Use Linear, but not Slack.” Starting point: the example agent.mcp is always, with no filter, and
Linear and Slack are connected. This recipe turns MCP off for one message, then
keeps only Linear for another.
Turn MCP off for one message:
- Python SDK
- HTTP
- Python SDK
- HTTP
examples/08_mcp_linear.py
Expected behavior: With enabled=False, Linear and Slack stay connected,
but they are off for this message. The agent drafts the template without calling
them. On the next message, with no scope, it can call Linear again. With
connections=["linear"], the agent can call Linear for this message. Slack
stays unavailable, even though it is connected to the agent. The connection
names are the ones on the Integrations page of the platform.
Recipe 4: no tools at all
Goal: “Rewrite this text. Do not search or call anything.” Starting point: the example agent. Web, documents, and MCP are allalways. This recipe turns the three of them off for one message.
For a pure transformation, turn off every tool for the message. It makes the
answer faster and more predictable.
- Python SDK
- HTTP
examples/07_custom_agent.py
Expected behavior: Web, document search, and MCP are off for this message.
The agent still sees their tools, but cannot run them. It rewrites the sentence
you gave it and nothing else. The next message without a scope gets its
capabilities back.
Recipe 5: a thread that never uses the web
Goal: “Support conversations must never browse the web.” Starting point: the example agent.web is always. This recipe removes it
from the thread.
This time the rule is for the whole thread. Use thread_capabilities with
activation="never".
- Python SDK
- HTTP
examples/11_capabilities.py
Expected behavior: The agent answers from your documents and its own
knowledge. It has no web search tool on any message of the thread: with
never, the tool is not installed, unlike a scope that only switches it off.
Asking for web search on a later message does not work: the request is
rejected with a 422 APIError before the agent runs, because the thread does
not have the capability to turn on. The other capabilities (documents, MCP, and
so on) keep the agent’s values, because you only redefined web.
Recipe 6: generate an image only when asked
Goal: “Let the agent draw, but only when the user asks for it.” Starting point: the example agent.image_generation is always, so the
agent may draw on any message. This recipe sets it to on_request for the
thread.
Use on_request. The capability is installed but off until a message turns it
on.
- Python SDK
- HTTP
examples/11_capabilities.py
Expected behavior: On the first message, image generation is off. The
agent describes the flow in words. On the second message, the scope turns image
generation on, so the agent can produce the diagram. On the third message you
sent no scope, so image generation is off again and the agent answers in words.
Sending ImageGenerationScope(enabled=False) on an on_request capability is
an error, because the capability is already off.
Recipe 7: restrict a thread to a few sources, connections, and skills
Goal: “This support thread may only read two sources, call Linear, and use one skill.” Starting point: the example agent. Every capability isalways, with no
filter. This recipe restricts three of them for the whole thread.
- Python SDK
- HTTP
examples/11_capabilities.py
Expected behavior: The agent searches only the two sources you listed, and
no other. It can call Linear but no other connection. It can load only the one
skill. Web search, image generation, and the other capabilities keep what the
agent has, because you did not pass them. The three lists apply to every message
of the thread.
What ALL and invalid values do
A filter you leave out means no restriction. ALL says it explicitly.
InvalidParams before it sends anything:
A filter together with
activation="never" or enabled=False is also refused,
because those states take no filter.
Recipe 8: one memory per customer
Goal: “Remember each customer’s preferences, and never mix customers up.” Starting point: the example agent. It has no memory namespace, so it has no memory. This recipe gives each thread one. Memory is a capability. Give each thread a namespace that includes the customer id.- Python SDK
- HTTP
examples/11_capabilities.py ·
examples/09_memory.py
Expected behavior: The agent has memory tools on this thread. It writes the
preference to a file in the customer-acme namespace, and reads it back on the
next message. A thread started for another customer uses a different namespace,
so it cannot see this file. With activation="never", the agent has no memory
tools and writes nothing, even if the agent normally has a namespace. A
follow-up cannot change the namespace: start a new thread to use another one.
Read what the agent stored with client.memory.
Recipe 9: lock the thread, then focus each message
Goal: “A support thread with a fixed policy, where each question can narrow it further.” Starting point: the example agent. Every capability isalways, with no
filter. The thread replaces web, documents, and MCP with its own policy. Each
message then narrows that policy.
Combine both levels. The thread sets the policy once. Each message narrows it
without ever going beyond it.
- Python SDK
- HTTP
examples/11_capabilities.py
Expected behavior:
Each scope applies to its message only. After message 2, message 3 searches
both sources again. The thread policy is the ceiling. A message can go down
from it, never above it.
Next steps
Capabilities
The definitions, activation modes, and filters.
Troubleshooting and migration
Move from
disabled_tools, and understand each error.