Integrating Claude Managed Agents with Enterprise Tools: The Asana AI Teammates Pattern
Most AI value in organizations is trapped in isolated experiments. Learn how Asana built AI Teammates on Claude Managed Agents to bridge the gap — letting agents ideate, orchestrate, and complete real project management work alongside human teams.
This lesson is original educational writing based on this video by Anthropic (published May 8, 2026). All credit for the original content goes to the creators.
1. The isolated-experiment problem
There’s a gap between what organizations demonstrate in AI pilots and what they actually deploy. Teams build impressive prototypes — a chatbot that drafts project briefs, an agent that summarizes meeting notes — but those experiments live in sandboxes, disconnected from the places where work actually happens.
The video opens with a pointed observation: most of the AI value in your organization is locked in isolated experiments. The agents can ideate and answer questions, but they can’t orchestrate a workflow or complete a task inside the tool your team already uses every day.
This is the difference between AI that supports work and AI that does work. An agent that summarizes a project status and pastes the result into a Slack message is supporting. An agent that reads open tasks, identifies blockers, reassigns work based on team capacity, and updates the project board is completing.
The path from support to completion runs through one insight: the agent needs to live inside the tool, not alongside it.
2. What Claude Managed Agents provides
Before looking at the Asana integration, it helps to understand what Claude Managed Agents contributes to an enterprise build. The platform is a managed hosting layer for Claude agents — it handles the infrastructure that otherwise blocks teams from shipping agents to production.
The three core primitives are:
Agent (the brain): a configuration that defines model, system prompt, tools available, MCP server connections, and skills. The agent loop runs server-side — when the user closes their browser, the agent keeps running.
Environment (the hands): a sandboxed container where tool execution happens. Deliberately decoupled from the agent loop, which delivers two production-critical properties: security (the agent’s reasoning process is isolated from credential storage) and latency (the agent loop starts immediately, without waiting for the container — Anthropic reports a >90% reduction in P95 time-to-first-token from this architecture).
Session (the binding): ties an Agent to an Environment and creates a durable, resumable conversation. Sessions emit events — not token-by-token responses — so your application can stream intermediate results, tool calls, and progress updates to users in real time.
What the platform handles for you: context compaction, prompt caching, retry and recovery logic, session persistence, and a built-in observability console. What you control: the task definition, the system prompt, and the tool implementations that connect to your organization’s data.
3. The Asana AI Teammates architecture
Asana’s AI Teammates are agents that operate as members of a project team. They aren’t a chatbot layer on top of Asana — they’re participants in the project management workflow, with the ability to read tasks, update statuses, assign work, draft content, and coordinate across multiple workstreams.
The integration is built on Claude Managed Agents as the underlying execution layer. Here’s how the primitives map to the Asana use case:
The key architectural choice is how the enterprise tool interacts with the session layer. Asana doesn’t embed Claude directly in their frontend — instead, they wire user actions (assigning a task, requesting a brief, asking a question about project status) to session events. The agent receives those events, reasons about what to do, calls tools against the Asana API (via the Environment), and streams results back.
This means the agent is a genuine participant in the tool, not a sidebar. When it updates a task, the task actually changes in Asana’s data layer. When it drafts a project brief, the brief appears in the right project context. The work is real.
4. Three integration patterns
The Asana integration illustrates three patterns that apply to any enterprise tool integration built on Managed Agents.
Pattern 1: Trigger-based sessions
Rather than always having an agent running, sessions start when something happens: a user tags the AI Teammate on a task, a new project is created, a milestone deadline approaches. The trigger fires a webhook that creates a new session (or resumes an existing one) with the relevant context preloaded.
This keeps costs predictable and behavior purposeful — the agent acts when needed, not as a background process consuming resources indefinitely.
Pattern 2: Context-first tool design
The most effective Asana AI Teammates aren’t just given access to the Asana API. They’re given curated context: the specific project’s history, the team’s working agreements, past similar projects. The agent’s tools are designed to surface the right information at the right moment, not just to expose raw API endpoints.
A tool called get_project_health that returns a structured summary (on-track tasks, overdue items, team workload, recent comments) is far more useful than GET /tasks with all parameters exposed. The tool design encodes domain knowledge.
Pattern 3: Outcome-oriented tasks
Managed Agents supports an “outcomes” mode where you define what success looks like in prose or as a rubric, and the agent iterates until it satisfies that rubric — rather than executing a fixed sequence of steps.
For project management, this maps well to tasks like: “Draft a project kickoff brief that covers goals, milestones, team assignments, and risks. Make sure each section has at least two concrete action items.” The agent won’t stop at a first draft that’s missing action items — it will revise until the rubric is met.
Check your understanding
5 questions · your answers are saved in this browser only
-
1. What is the primary problem the Asana AI Teammates integration is designed to solve?
-
2. Why is the agent loop deliberately decoupled from tool execution in Claude Managed Agents?
-
3. In the trigger-based session pattern, when does an agent session start?
-
4. What distinguishes "outcomes" mode from standard tool-call execution in Claude Managed Agents?
-
5. What makes a well-designed tool like `get_project_health` more valuable than raw API access in an enterprise integration?
5. Credential management and security
Enterprise integrations live or die on trust. Giving an agent the ability to update project tasks, reassign team members, or send notifications means the agent needs credentials — OAuth tokens, API keys, service accounts. Managed Agents addresses this with a dedicated Vaults system.
Vaults store credentials encrypted, and they are fetched by the Environment at tool-call time — they never appear in the agent’s context window. When the agent calls update_task, the Environment handler retrieves the Asana OAuth token from the vault, makes the API call, and returns only the result. Claude never sees the token.
This architectural pattern matters for compliance and for trust. It means you can:
- Scope credentials per user (each session uses that user’s OAuth token, not a shared service account)
- Rotate credentials without redeploying the agent
- Audit credential access through the vault’s access log, independent of the session log
For organizations deploying AI inside tools that manage business-critical data, this is a prerequisite — not a nice-to-have.
6. The generalization: any enterprise tool
The Asana integration isn’t unique to project management software. The pattern applies to any enterprise tool that:
- Has a webhook API (so actions in the tool can trigger sessions)
- Has a read/write API (so the agent can both get context and take action)
- Has work that benefits from multi-step reasoning (not just lookup)
Customer relationship management platforms, engineering issue trackers, document collaboration tools, HR systems — all fit this template. The differentiating variable is how well you design the tools (what context to surface, what actions to expose) and how you define outcomes (what does “completed well” look like for this type of task).
The Asana case is instructive precisely because project management is coordination-heavy. A project team isn’t just a database of tasks; it’s a system of obligations, deadlines, skill sets, and communication patterns. An AI Teammate that navigates that system successfully — updating the right tasks, flagging the right risks, involving the right people — is demonstrating exactly the kind of reasoning that makes Claude useful for enterprise work.
Build it yourself
Follow these exact steps to reproduce it yourself · estimated time: ~45 min
Prerequisites
- An Anthropic API key with Claude Managed Agents access
- A project management tool or task tracker with a REST API (Asana, Linear, Jira, GitHub Issues)
- Python 3.10+ and pip
- Basic familiarity with webhooks
Build a minimal “project intelligence” agent that can answer questions about a project and take one action (updating a task status) inside your existing tool.
Step 1 — Set up dependencies
mkdir project-agent && cd project-agent
python3 -m venv .venv && source .venv/bin/activate
pip install anthropic python-dotenv requestsCreate .env:
ANTHROPIC_API_KEY=sk-ant-...
PROJECT_TOOL_API_KEY=your-tool-api-keyStep 2 — Design your tools
Before writing code, decide what context the agent needs and what actions it should take. For a project intelligence agent, two tools cover a lot of ground:
TOOL_DEFINITIONS = [
{
"name": "get_project_summary",
"description": (
"Fetch a structured health summary for a project. "
"Returns: open tasks, overdue tasks, team members and their assigned tasks, "
"and the last 5 comments or updates."
),
"input_schema": {
"type": "object",
"properties": {
"project_id": {
"type": "string",
"description": "The project identifier"
}
},
"required": ["project_id"]
}
},
{
"name": "update_task_status",
"description": "Update the status of a specific task. Use only when explicitly asked.",
"input_schema": {
"type": "object",
"properties": {
"task_id": {"type": "string"},
"new_status": {
"type": "string",
"enum": ["todo", "in_progress", "done", "blocked"]
},
"note": {
"type": "string",
"description": "Optional comment to add to the task"
}
},
"required": ["task_id", "new_status"]
}
}
]Step 3 — Create the agent
import anthropic
client = anthropic.Anthropic()
agent = client.beta.managed_agents.agents.create(
name="project-intelligence-agent",
model="claude-opus-4-7",
system_prompt="""You are a project intelligence assistant embedded in a team's project management tool.
Your role:
- Help team members understand project state, blockers, and priorities
- Update task statuses when explicitly requested
- Flag risks proactively when you see them in the data
Constraints:
- Always fetch current data before answering questions about project state — do not speculate
- Only update tasks when the user explicitly requests an update
- Be concise: project managers are busy, keep responses scannable
- When you see a risk (overdue tasks, capacity issues, unclear ownership), name it clearly""",
tools=TOOL_DEFINITIONS,
)
print(f"Agent ID: {agent.id}")Step 4 — Create the environment
env = client.beta.managed_agents.environments.create(
name="project-agent-env",
networking={
# Restrict to only the domains your tool needs
"allowed_domains": ["api.asana.com"] # replace with your tool's domain
}
)
print(f"Environment ID: {env.id}")Step 5 — Implement local tool handlers
Replace the placeholder implementations with real API calls to your project management tool:
import os, requests
PROJECT_TOOL_API_KEY = os.getenv("PROJECT_TOOL_API_KEY")
BASE_URL = "https://api.asana.com/api/1.0" # replace with your tool's base URL
HEADERS = {"Authorization": f"Bearer {PROJECT_TOOL_API_KEY}"}
def get_project_summary(project_id: str) -> dict:
# Fetch tasks
tasks_resp = requests.get(
f"{BASE_URL}/projects/{project_id}/tasks",
headers=HEADERS,
params={"opt_fields": "name,assignee,due_on,completed,notes"}
)
tasks = tasks_resp.json().get("data", [])
# Structure for the agent
from datetime import date
today = date.today().isoformat()
open_tasks = [t for t in tasks if not t.get("completed")]
overdue = [t for t in open_tasks if t.get("due_on") and t["due_on"] < today]
return {
"total_open": len(open_tasks),
"overdue_count": len(overdue),
"overdue_tasks": [{"id": t["gid"], "name": t["name"], "due": t.get("due_on")} for t in overdue],
"open_tasks": [{"id": t["gid"], "name": t["name"], "assignee": t.get("assignee", {}).get("name")} for t in open_tasks[:10]],
}
def update_task_status(task_id: str, new_status: str, note: str = None) -> dict:
completed = new_status == "done"
payload = {"data": {"completed": completed}}
resp = requests.put(f"{BASE_URL}/tasks/{task_id}", headers=HEADERS, json=payload)
if note:
requests.post(
f"{BASE_URL}/tasks/{task_id}/stories",
headers=HEADERS,
json={"data": {"text": note}}
)
return {"task_id": task_id, "updated_status": new_status, "success": resp.ok}
TOOL_HANDLERS = {
"get_project_summary": lambda inp: get_project_summary(**inp),
"update_task_status": lambda inp: update_task_status(**inp),
}Step 6 — Run a session
def ask_agent(agent_id: str, env_id: str, user_message: str, project_id: str):
# Create a session with project context
session = client.beta.managed_agents.sessions.create(
agent_id=agent_id,
environment_id=env_id,
title=f"Project {project_id}: {user_message[:40]}",
)
# Send the user's question with project context
client.beta.managed_agents.sessions.messages.create(
session_id=session.id,
content=f"[Project ID: {project_id}]\n\n{user_message}",
)
# Stream events and handle tool calls
print("Agent: ", end="", flush=True)
for event in client.beta.managed_agents.sessions.stream(session.id):
if event.type == "tool_call":
handler = TOOL_HANDLERS.get(event.tool_name)
if handler:
result = handler(event.tool_input)
client.beta.managed_agents.sessions.tool_results.create(
session_id=session.id,
tool_call_id=event.tool_call_id,
result=str(result),
)
elif event.type == "agent_response_chunk":
print(event.content, end="", flush=True)
elif event.type == "session_completed":
break
print()
# Try it
ask_agent(
agent.id,
env.id,
"What's the current state of this project? Any blockers I should know about?",
project_id="YOUR_PROJECT_ID"
)Step 7 — Add outcome-oriented tasks
For more complex requests — like drafting a status update — switch to outcomes mode:
def draft_status_update(agent_id: str, env_id: str, project_id: str):
session = client.beta.managed_agents.sessions.create(
agent_id=agent_id,
environment_id=env_id,
title=f"Status update draft: {project_id}",
)
# Submit as an outcome with a success rubric
client.beta.managed_agents.sessions.outcomes.create(
session_id=session.id,
description=f"""
Fetch the current state of project {project_id} and draft a weekly status update.
The update must include:
- One-sentence overall project health (On Track / At Risk / Off Track)
- Top 2-3 accomplishments this week (from recently completed tasks)
- Top 1-2 risks or blockers (overdue tasks, unassigned items)
- Recommended next actions for the team (at least 2 concrete items)
Do not include tasks with no activity in the last 7 days.
""".strip()
)
# Stream as before ...Production checklist
- Move API keys to Managed Agents Vaults — never hardcode or pass through environment variables in production
- Add per-user session scoping so each team member has their own session history
- Set up webhook triggers: when a task is tagged with “@AI-Teammate”, create a new session
- Restrict
allowed_domainsto only the endpoints your tools actually call - Review a few sessions in the Managed Agents observability console before going live
Where to go next
- Ship Your First Managed Agent — the hands-on workshop that walks through the core Agent, Environment, Session primitives step by step
- Agents That Remember — add persistent memory so your AI Teammate learns from past project patterns
- Tool, Skill, or Subagent? — how to decide when a tool call is enough versus when to spin up a specialized sub-agent
- Watch the original video to see the Asana AI Teammates integration demonstrated live