This guide explains how to create new tools for the Hive agent framework using FastMCP. Tools are Python functions that agents can call to interact with external systems and services.
Create a simple tool that doesn’t require external API credentials:
my_tool.py
from fastmcp import FastMCPdef register_tools(mcp: FastMCP) -> None: """Register my tools with the MCP server.""" @mcp.tool() def my_tool( query: str, limit: int = 10, ) -> dict: """ Search for items matching a query. Use this when you need to find specific information. Args: query: The search query (1-500 chars) limit: Maximum number of results (1-100) Returns: Dict with search results or error dict """ # Validate inputs if not query or len(query) > 500: return {"error": "Query must be 1-500 characters"} if limit < 1 or limit > 100: limit = max(1, min(100, limit)) try: results = do_search(query, limit) return { "success": True, "query": query, "results": results, "total": len(results), } except Exception as e: return {"error": f"Search failed: {str(e)}"}
from typing import TYPE_CHECKINGimport osif TYPE_CHECKING: from aden_tools.credentials import CredentialStoreAdapterdef register_tools( mcp: FastMCP, credentials: CredentialStoreAdapter | None = None,) -> None: def _get_token() -> str | None: """Get API token from credentials or environment.""" if credentials is not None: return credentials.get("my_api") return os.getenv("MY_API_KEY") @mcp.tool() def my_api_tool(query: str) -> dict: """Tool that requires an API key.""" token = _get_token() if not token: return { "error": "MY_API_KEY environment variable not set", "help": "Get an API key at https://example.com/api-keys", } # Use the API key... response = call_api(token, query) return {"success": True, "data": response}
from .base import CredentialSpecMY_CREDENTIALS = { "my_api": CredentialSpec( env_var="MY_API_KEY", tools=["my_api_tool"], # List ALL tool names required=True, help_url="https://example.com/api-keys", description="API key for My Service", credential_id="my_api", credential_key="api_key", ),}
The tools list must include every tool name that requires this credential. CI will enforce this.
The docstring becomes the tool description in MCP:
@mcp.tool()def my_tool(query: str, limit: int = 10) -> dict: """ One-line summary of what the tool does. More detailed explanation of the tool's purpose and when to use it. Can span multiple paragraphs. Args: query: Description of the query parameter (include constraints) limit: Description of limit parameter (include range) Returns: Description of what the tool returns Examples: my_tool(query="fastmcp", limit=5) my_tool(query="python agents") """
# My ToolBrief description of what the tool does.## Use Cases- Use case 1- Use case 2## Parameters| Parameter | Type | Default | Description ||-----------|------|---------|-------------|| query | string | required | Search query || limit | integer | 10 | Max results |## Environment Variables- `MY_API_KEY` - API key from example.com## Examples```pythonresult = my_tool(query="fastmcp", limit=5)