Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.agno.com/llms.txt

Use this file to discover all available pages before exploring further.

Basic Usage

Attach a provider by calling get_tools() and passing the result to your agent:
from agno.agent import Agent
from agno.models.openai import OpenAIResponses
from agno.context.fs import FilesystemContextProvider

fs = FilesystemContextProvider(id="docs", root="./documentation")

agent = Agent(
    model=OpenAIResponses(id="gpt-5.4"),
    tools=fs.get_tools(),
)

agent.print_response("What files are in the docs folder?")
The agent now has a query_docs tool. Ask it questions about the filesystem and the provider’s sub-agent handles file traversal and content extraction.

Adding Instructions

Providers can generate usage hints. Include them in your agent’s instructions:
agent = Agent(
    model=OpenAIResponses(id="gpt-5.4"),
    tools=fs.get_tools(),
    instructions=fs.instructions(),
)
For multiple providers, combine their instructions:
instructions = "\n".join([
    fs.instructions(),
    web.instructions(),
    db.instructions(),
])

agent = Agent(
    model=...,
    tools=[*fs.get_tools(), *web.get_tools(), *db.get_tools()],
    instructions=instructions,
)

Read/Write Control

Restrict a provider to read-only or write-only:
from agno.context.gmail import GmailContextProvider

# Read-only: agent can search emails but not send
gmail = GmailContextProvider(write=False)

# Write-only: agent can send but not read inbox
gmail = GmailContextProvider(read=False, write=True)
This is useful for:
  • Audit workflows where the agent should only observe
  • Notification agents that send but don’t read
  • Sandboxed environments during development

Choosing a Mode

The mode parameter controls how the provider exposes itself:
The provider decides optimal exposure. Most read/write providers expose query_<id> + update_<id>.
from agno.context.slack import SlackContextProvider

slack = SlackContextProvider(id="slack")
# Agent sees: query_slack, update_slack

Sub-agent Model

Override the model used by the provider’s internal sub-agent:
from agno.models.openai import OpenAIResponses
from agno.context.database import DatabaseContextProvider

db = DatabaseContextProvider(
    sql_engine=write_engine,
    readonly_engine=read_engine,
    model=OpenAIResponses(id="gpt-5.4-mini"),  # Cheaper model for SQL generation
)

agent = Agent(
    model=OpenAIResponses(id="gpt-5.4"),  # Stronger model for reasoning
    tools=db.get_tools(),
)
This pattern saves cost: the sub-agent does mechanical work (SQL generation, API calls) while your main agent does synthesis and reasoning.

Lifecycle Management

Some providers hold async resources (MCP sessions, web backends). They require asetup() and aclose():
import asyncio
from agno.agent import Agent
from agno.context.mcp import MCPContextProvider

async def main():
    mcp = MCPContextProvider(
        server_name="github",
        transport="stdio",
        command="npx",
        args=["-y", "@modelcontextprotocol/server-github"],
    )

    await mcp.asetup()
    try:
        agent = Agent(model=..., tools=mcp.get_tools())
        await agent.arun("List my recent PRs")
    finally:
        await mcp.aclose()

asyncio.run(main())
Providers requiring lifecycle management:
  • MCPContextProvider - MCP server connection
  • WebContextProvider with MCP backends (ExaMCPBackend, ParallelMCPBackend) - MCP connection
  • WikiContextProvider with GitBackend - repo clone
Providers that don’t need it:
  • SlackContextProvider, GmailContextProvider, GoogleCalendarContextProvider, GoogleDriveContextProvider - lazy connection
  • FilesystemContextProvider, DatabaseContextProvider - sync resources

RunContext Propagation

When a provider runs a sub-agent, it forwards auth and state from the caller:
Calling Agent
  ↓ tool call with run_context
Provider._query_tool()
  ↓ extracts user_id, session_id, metadata, dependencies
Sub-agent.arun(question, user_id=..., session_id=..., ...)
This ensures:
  • Per-user auth tokens reach the sub-agent’s tools
  • Framework-injected state (e.g., Slack’s action_token) survives the hop
  • User/session isolation works across provider boundaries
Message history and session_state stay with the outer agent. Sub-agents run isolated.

Next

Build Custom Providers

Create your own provider for any data source

Provider Catalog

Browse all built-in providers