> ## Documentation Index
> Fetch the complete documentation index at: https://phidatainc-studio-tools-doc.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Python Functions as Tools

> Turn any Python function into an agent tool.

Any python function can be used as a tool by an Agent.

For example, here's how to use a `get_top_hackernews_stories` function as a tool:

```python hn_agent.py theme={null}
import json
import httpx

from agno.agent import Agent

def get_top_hackernews_stories(num_stories: int = 10) -> str:
    """
    Use this function to get top stories from Hacker News.

    Args:
        num_stories (int): Number of stories to return. Defaults to 10.

    Returns:
        str: JSON string of top stories.
    """

    # Fetch top story IDs
    response = httpx.get('https://hacker-news.firebaseio.com/v0/topstories.json')
    story_ids = response.json()

    # Fetch story details
    stories = []
    for story_id in story_ids[:num_stories]:
        story_response = httpx.get(f'https://hacker-news.firebaseio.com/v0/item/{story_id}.json')
        story = story_response.json()
        if "text" in story:
            story.pop("text", None)
        stories.append(story)
    return json.dumps(stories)

agent = Agent(tools=[get_top_hackernews_stories], markdown=True)
agent.print_response("Summarize the top 5 stories on hackernews?", stream=True)
```

## Accessing built-in parameters in Tools

Agno automatically injects some built-in parameters into your tool functions, so you can easily gain access to important information and objects in your tools.

These built-in parameters are:

* `run_context`: The run context object from where you can access the session state, dependencies, metadata, etc.
* `agent`: The agent object.
* `team`: The team object.
* `images`: The images object.
* `videos`: The videos object.
* `audio`: The audio object.
* `files`: The files object.

For example to access agent in a tool, you can do:

```python theme={null}
from agno.agent import Agent
from agno.models.openai import OpenAIResponses

def get_agent_model(agent: Agent) -> str:
    """Get the model of the agent."""
    return agent.model.id

agent = Agent(
    model=OpenAIResponses(id="gpt-5.2"),
    tools=[get_agent_model],
)

agent.print_response("What is the model of the agent?", stream=True)
```

See [Tool Built-in Parameters](/tools/overview#tool-built-in-parameters) for more details on `run_context`, `agent`, `team`, and media parameters.

## Magic of the @tool decorator

To modify the behavior of a tool, use the `@tool` decorator. Some notable features:

* `requires_confirmation=True`: Requires user confirmation before execution.
* `requires_user_input=True`: Requires user input before execution. Use `user_input_fields` to specify which fields require user input.
* `external_execution=True`: The tool will be executed outside of the agent's control.
* `show_result=True`: Show the output of the tool call in the Agent's response, `True` by default. Without this flag, the result of the tool call is sent to the model for further processing.
* `stop_after_tool_call=True`: Stop the agent run after the tool call.
* `tool_hooks`: Run custom logic before and after this tool call.
* `cache_results=True`: Cache the tool result to avoid repeating the same call. Use `cache_dir` and `cache_ttl` to configure the cache.

Here's an example that uses many possible parameters on the `@tool` decorator.

```python advanced_tool.py theme={null}
import httpx
from agno.agent import Agent
from agno.tools import tool
from typing import Any, Callable, Dict

def logger_hook(function_name: str, function_call: Callable, arguments: Dict[str, Any]):
    """Hook function that wraps the tool execution"""
    print(f"About to call {function_name} with arguments: {arguments}")
    result = function_call(**arguments)
    print(f"Function call completed with result: {result}")
    return result

@tool(
    name="fetch_hackernews_stories",                # Custom name for the tool (otherwise the function name is used)
    description="Get top stories from Hacker News",  # Custom description (otherwise the function docstring is used)
    stop_after_tool_call=True,                      # Return the result immediately after the tool call and stop the agent
    tool_hooks=[logger_hook],                       # Hook to run before and after execution
    requires_confirmation=True,                     # Requires user confirmation before execution
    cache_results=True,                             # Enable caching of results
    cache_dir="/tmp/agno_cache",                    # Custom cache directory
    cache_ttl=3600                                  # Cache TTL in seconds (1 hour)
)
def get_top_hackernews_stories(num_stories: int = 5) -> str:
    """
    Fetch the top stories from Hacker News.

    Args:
        num_stories: Number of stories to fetch (default: 5)

    Returns:
        str: The top stories in text format
    """
    # Fetch top story IDs
    response = httpx.get("https://hacker-news.firebaseio.com/v0/topstories.json")
    story_ids = response.json()

    # Get story details
    stories = []
    for story_id in story_ids[:num_stories]:
        story_response = httpx.get(f"https://hacker-news.firebaseio.com/v0/item/{story_id}.json")
        story = story_response.json()
        stories.append(f"{story.get('title')} - {story.get('url', 'No URL')}")

    return "\n".join(stories)

agent = Agent(tools=[get_top_hackernews_stories])
agent.print_response("Show me the top news from Hacker News")
```

See the [@tool Decorator Reference](/reference/tools/decorator) for more details.
