Tiny-Tools-Agent

aaabulkhair/Tiny-Tools-Agent

3.3

If you are the rightful owner of Tiny-Tools-Agent and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

This document provides a comprehensive overview of a Model Context Protocol (MCP) server, detailing its architecture, features, and usage.

Tools
  1. clock.now

    Get current time

  2. clock.shift

    Calculate time with offset

Tiny Tools MCP Showcase: A Complete LangGraph Agent System

A production-ready demonstration of a 4-node LangGraph agent with Model Context Protocol (MCP) tool integration, Redis-backed memory, and local LLM support.

Python 3.10+ LangGraph FastAPI Redis

Table of Contents

Overview

This project demonstrates a complete AI agent system built with LangGraph that showcases modern patterns for tool-based AI interactions. The system consists of two main components:

  1. MCP Server: A secure FastAPI-based server that provides tool capabilities
  2. LangGraph Agent: A 4-node workflow that intelligently selects and executes tools

The project serves as both a working demonstration and a reference implementation for building production-ready AI agent systems with proper memory management, error handling, and observability.

Architecture

System Components

graph TB
    User[πŸ‘€ User] --> Agent[πŸ€– LangGraph Agent]
    Agent --> LLM[🧠 Local LLM Server]
    Agent --> MCP[πŸ”§ MCP Tool Server]
    Agent --> Redis[πŸ’Ύ Redis Memory]
    MCP --> Tools[βš™οΈ Tool Implementations]
    
    subgraph "Agent Workflow"
        P[πŸ“‹ Planner] --> E[⚑ Executor]
        E --> M[πŸ’Ύ Memory]
        M --> R[πŸ’¬ Responder]
        R --> P
    end

4-Node LangGraph Workflow

The agent follows a linear pipeline with conditional looping:

  1. Planner Node (planner_node)

    • Analyzes user requests using local LLM
    • Creates structured tool execution plans
    • Handles JSON parsing failures with intelligent fallbacks
    • Integrates conversation memory for context-aware planning
  2. Tool Executor Node (tool_executor_node)

    • Validates and executes planned tool calls via HTTP
    • Supports parallel tool execution and result chaining
    • Comprehensive error handling and retry logic
    • Real-time progress indicators
  3. Memory Updater Node (memory_updater_node)

    • Persists conversation state to Redis
    • Extracts entities and key facts automatically
    • Maintains conversation history and context
    • Graceful degradation to in-memory storage
  4. Responder Node (responder_node)

    • Generates natural language responses using LLM
    • Integrates tool results seamlessly
    • Detects follow-up intents for conversation flow
    • Provides user-friendly error messages

Project Structure

tiny-tools-mcp-showcase/
β”œβ”€β”€ app/                          # MCP Server (FastAPI)
β”‚   β”œβ”€β”€ main.py                   # FastAPI app with security & rate limiting
β”‚   β”œβ”€β”€ manifest.py               # Tool capability discovery
β”‚   β”œβ”€β”€ tools/
β”‚   β”‚   β”œβ”€β”€ schemas.py            # Pydantic validation models
β”‚   β”‚   └── impl.py               # Tool implementation engine
β”‚   └── tests/
β”‚       └── test_tools.py         # Comprehensive MCP server tests
β”œβ”€β”€ agent/                        # LangGraph Agent
β”‚   β”œβ”€β”€ workflow.py               # Main orchestrator & CLI interface
β”‚   β”œβ”€β”€ nodes.py                  # 4-node implementation
β”‚   β”œβ”€β”€ edges.py                  # Conditional routing logic
β”‚   β”œβ”€β”€ memory.py                 # Redis-backed conversation memory
β”‚   β”œβ”€β”€ prompt_fragments.py       # LLM prompt templates
β”‚   └── tests/
β”‚       └── test_agent.py         # Agent workflow tests
β”œβ”€β”€ logs/                         # Execution traces & debugging
β”œβ”€β”€ docker-compose.yml            # Multi-service orchestration
β”œβ”€β”€ Dockerfile                    # MCP server containerization
β”œβ”€β”€ Makefile                      # Development automation
└── pyproject.toml               # Project configuration & dependencies

Features

πŸš€ Core Capabilities

  • Intelligent Tool Selection: LLM-powered planning with efficiency optimization
  • Conversation Memory: Redis-backed persistent state with automatic fallback
  • Local LLM Integration: Compatible with LM Studio, Ollama, and OpenAI-compatible servers
  • Secure MCP Server: Rate limiting, CORS, authentication, and input validation
  • Rich Terminal UI: Clean progress indicators and error handling
  • Comprehensive Logging: JSON execution traces for debugging and monitoring

πŸ› οΈ Available Tools

ToolDescriptionUsage Example
clock.nowGet current time"What time is it?"
clock.shiftCalculate time with offset"What time will it be in 2 hours?"

πŸ”§ Technical Features

  • Type Safety: Full Pydantic validation throughout the stack
  • Async/Await: Non-blocking operations for optimal performance
  • Error Recovery: Graceful handling of LLM, tool, and network failures
  • Session Management: Isolated conversations with reset capability
  • Extensible Design: Easy addition of new tools and capabilities
  • Production Ready: Docker support, health checks, and monitoring

Installation

Prerequisites

  • Python 3.10+ with pip
  • Local LLM Server (LM Studio, Ollama, or OpenAI-compatible)
  • Docker (optional, for Redis and containerized deployment)
  • Redis (optional, for persistent memory)

Method 1: Local Development (Recommended)

  1. Clone the repository:

    git clone <repository-url>
    cd tiny-tools-mcp-showcase
    
  2. Install dependencies:

    pip install -e .
    
  3. Start Redis (optional but recommended):

    # Using Docker
    docker run -d --name redis -p 6379:6379 redis:alpine
    
    # Or using Docker Compose
    docker-compose up -d redis
    

Method 2: Docker Development

  1. Clone and start services:
    git clone <repository-url>
    cd tiny-tools-mcp-showcase
    docker-compose up -d
    

Quick Start

1. Start Your Local LLM

Ensure you have a local LLM server running on http://127.0.0.1:1234:

  • LM Studio: Download and start a model server
  • Ollama: ollama serve with your preferred model
  • Other: Any OpenAI-compatible API server

2. Start the MCP Server

# Local development
python -m uvicorn app.main:app --host 0.0.0.0 --port 7443 --reload

# Or using Make
make start-server

# Or using Docker
docker-compose up -d mcp

3. Test the MCP Server (Optional)

# Health check
curl http://localhost:7443/health

# Get tool manifest
curl http://localhost:7443/mcp/manifest

# Execute a tool
curl -X POST http://localhost:7443/mcp/tool.execute \
     -H "Content-Type: application/json" \
     -d '{"capability": "clock.now", "args": {}}'

4. Run the Agent

# Interactive terminal interface
python agent/workflow.py

# Or using Make
make demo

# Or programmatically
python -c "
import asyncio
from agent.workflow import run_agent
result = asyncio.run(run_agent('What time is it?'))
print(result)
"

5. Try Example Queries

πŸ’¬ What time is it?
πŸ§ πŸ”§ βœ“ 1 tools
πŸ€– It's currently 2:30 PM.

πŸ’¬ What time will it be in 90 minutes?
πŸ§ πŸ”§πŸ’ΎπŸ’¬ βœ“ 2 tools
πŸ€– In 90 minutes, it will be 4:00 PM.

πŸ’¬ I have a meeting after 2 hours when will it be
πŸ§ πŸ”§πŸ’ΎπŸ’¬ βœ“ 2 tools
πŸ€– Your meeting will be at 4:30 PM.

πŸ’¬ quit
πŸ‘‹ Goodbye!

Configuration

Environment Variables

VariableDefaultDescription
LLM_URLhttp://127.0.0.1:1234Local LLM server endpoint
REDIS_URLredis://localhost:6379Redis connection string
MCP_API_KEYdemo-key-change-in-productionOptional API key for MCP server
PYTHONPATH/appPython module path (for Docker)

Local LLM Configuration

The agent is tested with various local LLM providers:

  • LM Studio: Use any chat model with OpenAI-compatible API
  • Ollama: Models like llama2, mistral, codellama
  • Text Generation WebUI: With OpenAI extension enabled
  • vLLM: High-performance inference server

Redis Configuration

Redis is used for conversation memory with automatic fallback:

  • With Redis: Persistent conversations across restarts
  • Without Redis: In-memory storage (warnings are normal)
  • TTL: 24-hour automatic session cleanup

Usage Guide

Interactive Terminal Interface

The primary interface is a clean terminal conversation:

python agent/workflow.py

Commands:

  • Type your questions naturally
  • !reset - Clear conversation memory
  • quit, exit, bye - End conversation

Programmatic Usage

import asyncio
from agent.workflow import TinyToolsAgent, run_agent

# Single interaction
async def example():
    result = await run_agent("What time is it?", session_id="user123")
    print(result["bot_response"])

# Agent instance
async def conversation():
    agent = TinyToolsAgent()
    
    # Single message
    result = await agent.run_single("What time is it?", "session123")
    
    # Interactive conversation
    await agent.run_conversation("session123")

asyncio.run(example())

Tool Usage Patterns

Time Queries
"What time is it?" β†’ Uses clock.now (1 tool)
"What time will it be in 2 hours?" β†’ Uses clock.now + clock.shift (2 tools)
"I have a meeting in 45 minutes when will it be" β†’ Uses both tools
Conversation Flow
User: What time is it?
πŸ§ πŸ”§ βœ“ 1 tools
Bot: It's 2:30 PM.

User: What about in 30 minutes?
πŸ§ πŸ”§πŸ’ΎπŸ’¬ βœ“ 2 tools  
Bot: In 30 minutes, it will be 3:00 PM.

API Reference

MCP Server Endpoints

EndpointMethodDescription
/GETServer information and endpoint list
/healthGETHealth check for monitoring
/mcp/manifestGETComplete tool capability manifest
/mcp/capabilities/summaryGETBrief capability summary for prompts
/mcp/tool.executePOSTExecute tools with validation

Agent API

# Main classes
from agent.workflow import TinyToolsAgent
from agent.nodes import AgentState
from agent.memory import ConversationMemory

# Convenience functions
from agent.workflow import run_agent, start_conversation

Tool Execution Response Format

{
  "success": true,
  "result": {
    "current_time": "2:30 PM",
    "timestamp": "2024-01-15T14:30:00"
  },
  "error": null,
  "execution_time_ms": 5.2
}

Development

Setting Up Development Environment

# Install in development mode
make dev

# Or manually
pip install -e ".[dev]"

Running Tests

# Run all tests
make test

# Run with coverage
make test-coverage

# Run specific test files
pytest app/tests/test_tools.py -v
pytest agent/tests/test_agent.py -v

Code Quality

# Format code
make format

# Lint code
make lint

# Type checking
mypy app/ agent/

Adding New Tools

  1. Define schemas in app/tools/schemas.py:

    class NewToolArgs(BaseModel):
        param: str = Field(description="Tool parameter")
    
    class NewToolResult(BaseModel):
        result: str = Field(description="Tool result")
    
  2. Implement function in app/tools/impl.py:

    def execute_new_tool(args: NewToolArgs) -> NewToolResult:
        return NewToolResult(result=f"Processed: {args.param}")
    
  3. Register tool in schemas registry:

    TOOL_SCHEMAS["new.tool"] = {
        "args": NewToolArgs,
        "result": NewToolResult,
        "description": "Description of new tool",
        "cost_estimate": 0.1,
        "avg_latency_ms": 10.0
    }
    
  4. Add implementation to registry:

    TOOL_IMPLEMENTATIONS["new.tool"] = execute_new_tool
    
  5. Write tests in app/tests/test_tools.py

Development Commands

# Start MCP server in development mode
make start-mcp

# Start agent in development mode  
make start-agent

# Clean build artifacts
make clean

# Build Docker images
make docker-build

# Start full stack with Docker
make docker-up

Testing

Test Structure

tests/
β”œβ”€β”€ app/tests/
β”‚   └── test_tools.py        # MCP server tests
└── agent/tests/
    └── test_agent.py        # Agent workflow tests

Running Tests

# All tests
pytest

# Specific test file
pytest app/tests/test_tools.py::TestToolImplementations::test_clock_now_tool

# With coverage
pytest --cov=app --cov=agent --cov-report=html

# Async tests
pytest -v -s agent/tests/test_agent.py

Test Categories

  • Unit Tests: Individual component testing
  • Integration Tests: Component interaction testing
  • API Tests: HTTP endpoint testing
  • Workflow Tests: End-to-end agent testing

Deployment

Docker Deployment

# Build and start all services
docker-compose up -d

# Scale services
docker-compose up -d --scale mcp=2

# View logs
docker-compose logs -f mcp

Production Considerations

  1. Security:

    • Change default API keys
    • Configure proper CORS origins
    • Use HTTPS in production
    • Set up proper authentication
  2. Monitoring:

    • Health check endpoints
    • Execution trace logging
    • Performance metrics collection
    • Error rate monitoring
  3. Scaling:

    • Redis cluster for high availability
    • Load balancing for MCP servers
    • Horizontal scaling of agent instances

Environment-Specific Configuration

# Development
export LLM_URL="http://localhost:1234"
export REDIS_URL="redis://localhost:6379"

# Production
export LLM_URL="https://your-llm-server.com"
export REDIS_URL="redis://your-redis-cluster:6379"
export MCP_API_KEY="your-secure-api-key"

Troubleshooting

Common Issues

1. LLM Connection Issues
Error: Error calling local LLM: Connection refused

Solution: Ensure your local LLM server is running on the correct port.

2. MCP Server Not Responding
Warning: Could not fetch tool manifest

Solution: Start the MCP server and check port 7443 is available.

3. Redis Connection Warnings
Warning: Redis not available, using in-memory storage

Solution: Start Redis or ignore (in-memory fallback works fine).

4. Tool Execution Failures
⚠ 0/1 tools

Solution: Check MCP server logs and ensure tools are properly registered.

5. JSON Parsing Errors
Planning failed: Invalid JSON response

Solution: The agent has built-in fallback logic for this. Check LLM configuration.

Debug Mode

Enable verbose logging:

import logging
logging.basicConfig(level=logging.DEBUG)

Log Analysis

Execution traces are saved in logs/trace-{session}-{timestamp}.json:

{
  "session_id": "abc123",
  "timestamp": "2024-01-15T14:30:00",
  "user_message": "What time is it?",
  "bot_response": "It's 2:30 PM",
  "execution_summary": {
    "planning_success": true,
    "execution_success": true,
    "tools_executed": 1
  },
  "plan": [...],
  "tool_results": [...]
}

Performance Tuning

  1. LLM Settings:

    • Adjust temperature (0.1 for consistent results)
    • Optimize max_tokens for your use case
    • Consider model size vs. speed tradeoffs
  2. Redis Optimization:

    • Adjust TTL based on conversation patterns
    • Monitor memory usage
    • Consider Redis clustering for scale
  3. Tool Execution:

    • Implement parallel execution for independent tools
    • Add caching for expensive operations
    • Monitor execution times and optimize slow tools

Contributing

We welcome contributions! Please see our contributing guidelines:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes with proper tests and documentation
  4. Run the test suite: make test
  5. Submit a pull request

Development Workflow

  1. Issues: Report bugs or request features via GitHub issues
  2. Pull Requests: Follow the PR template and ensure tests pass
  3. Code Review: All changes require review before merging
  4. Documentation: Update documentation for any new features

Code Style

  • Follow PEP 8 for Python code
  • Use type hints throughout
  • Write comprehensive docstrings
  • Add tests for new functionality
  • Keep functions focused and small

License

This project is licensed under the MIT License - see the file for details.

Acknowledgments


Built with ❀️ for the AI agent community