Skip to main content
MCP (Model Context Protocol) tools are functions decorated with @mcp.tool() that extend the capabilities of your AI agents.

Basic Example

File: mcp/tools/math.py
from server import mcp

@mcp.tool()
def multiply(first_val: float, second_val: float) -> float:
    '''
    Calculate the product of two numbers

    Args:
        first_val: the first value to be multiplied
        second_val: the second value to be multiplied
    '''
    return round(first_val * second_val, 4)

Key Requirements

1. Use the @mcp.tool() Decorator

All tools must be decorated with @mcp.tool() to be discovered by Osmosis.

2. Place in mcp/tools/ Directory

Organize your tool modules within the mcp/tools/ directory.

3. Include Type Hints

Type hints are required for all parameters and return values:
def my_tool(input_text: str, count: int) -> list[str]:
    # Implementation
    pass

4. Add Docstrings

Comprehensive docstrings help the AI understand when and how to use your tool:
@mcp.tool()
def search_database(query: str, limit: int = 10) -> list[dict]:
    """
    Search the database for matching records

    Args:
        query: Search query string
        limit: Maximum number of results to return (default: 10)

    Returns:
        List of matching records as dictionaries
    """
    # Implementation
    pass

5. Export in __init__.py

Export your tools in mcp/tools/__init__.py:
from .math import multiply
from .search import search_database

__all__ = ['multiply', 'search_database']

Server Setup

FastMCP Server Configuration

File: mcp/server/mcp_server.py
from fastmcp import FastMCP
from starlette.requests import Request
from starlette.responses import JSONResponse

mcp = FastMCP("OsmosisTools")

@mcp.custom_route("/health", methods=["GET"])
async def health(request: Request) -> JSONResponse:
    return JSONResponse({"status": "healthy"})

Entry Point

File: mcp/main.py
import argparse
from server.mcp_server import mcp
from tools import *  # Import all tools

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--host", default="0.0.0.0")
    parser.add_argument("--port", type=int, default=8080)
    args = parser.parse_args()

    mcp.run(transport="http", host=args.host, port=args.port)

Complete Example

Here’s a more complex tool that demonstrates best practices:
from server import mcp
from typing import Optional
import json

@mcp.tool()
def fetch_user_profile(
    user_id: str,
    include_history: bool = False,
    max_items: Optional[int] = None
) -> dict:
    """
    Fetch a user's profile information from the database

    This tool retrieves user profile data and optionally includes
    their activity history. Use this when you need to look up
    information about a specific user.

    Args:
        user_id: Unique identifier for the user
        include_history: Whether to include activity history (default: False)
        max_items: Maximum number of history items to return (optional)

    Returns:
        Dictionary containing user profile data with keys:
        - id: User ID
        - name: User's full name
        - email: User's email address
        - history: Activity history (if include_history=True)

    Raises:
        ValueError: If user_id is not found
    """
    # Your implementation here
    profile = {
        "id": user_id,
        "name": "John Doe",
        "email": "john@example.com"
    }

    if include_history:
        history = get_user_history(user_id, max_items)
        profile["history"] = history

    return profile

Testing Your Tools

Local Testing

Start your MCP server locally:
python mcp/main.py
Test in another terminal:
python mcp/test/test.py

Unit Tests

Create tests for your tools:
# tests/test_math.py
from mcp.tools.math import multiply

def test_multiply():
    assert multiply(2.0, 3.0) == 6.0
    assert multiply(0.5, 0.5) == 0.25
    assert multiply(-2.0, 3.0) == -6.0
For coding guidelines, testing strategies, and CI/CD setup, see Best Practices.

Next Steps

Reward Functions

Learn about reward functions

GitHub Integration

Connect your repository to Osmosis