compose_feedback_services() called import_server() without awaiting it. That method became async in FastMCP 2.14, so on the version this package was built against it composed nothing while logging success. FastMCP 4 removed it outright. Use mount(), which is sync on 2.12 through 4.x. The test suite could not start (pytest-html hook, plugin not installed), so nothing caught this. Add pytest-html, bring examples/ over from the docs repo since the integration tests import them, and fix the tests that had drifted from the code. 407 tests pass on FastMCP 2.12.2, 2.14.3 and 4.0.10. - Declare fastmcp>=2.12.2,<5; CI matrix covers each family plus a non-blocking canary on the newest FastMCP - Add a composition test with real servers; the mocked ones could not see a missing await - Rewrite the README against the actual API and execute its examples - Ignore ruff UP042: StrEnum would change stored enum formatting - Version 2026.09.27
7.4 KiB
7.4 KiB
Simple FastMCP Feedback Integration
File: simple_integration.py
Purpose: Minimal 3-line integration example
Lines: 48 lines of clean, documented code
Complexity: Beginner-friendly
🎯 Overview
This example demonstrates the absolute minimal integration of FastMCP Feedback into any FastMCP server. With just 3 lines of code, you get a complete, production-ready feedback system.
✨ Key Features
Minimal Code
# This is all you need - 3 lines of code!
app = FastMCP("Simple Feedback App")
add_feedback_tools(app, database_url="sqlite:///simple_feedback.db")
Automatic Tool Registration
The integration automatically adds 5 production-ready tools:
- ✅
submit_feedback- Submit bug reports & feature requests - ✅
list_feedback- Query and filter feedback - ✅
get_feedback_statistics- Analytics and metrics - ✅
delete_feedback- Remove feedback items - ✅
update_feedback_status- Change status (admin)
Zero Configuration
- Database - Automatically creates SQLite database
- Schema - Auto-generates tables on first run
- Validation - Built-in Pydantic input validation
- Error Handling - Graceful failure scenarios
🚀 Usage
Direct Execution
# Run the example
python examples/simple_integration.py
# With uv (recommended)
uv run examples/simple_integration.py
Expected Output
🚀 Simple FastMCP Feedback Integration
==================================================
✅ Feedback system added!
📊 Available tools:
• submit_feedback - Submit feedback to the system
• get_feedback_statistics - Get feedback statistics and analytics
• list_feedback - List feedback items with optional filtering
• delete_feedback - Delete feedback item
• update_feedback_status - Update feedback status
🎯 Total tools: 5
🎬 Starting server...
Connect this as an MCP server in Claude Desktop
📋 Integration Steps
Step 1: Install Dependencies
# Using uv (recommended)
uv add fastmcp-feedback
# Using pip
pip install fastmcp-feedback
Step 2: Add to Your Server
from fastmcp import FastMCP
from fastmcp_feedback import add_feedback_tools
# Your existing FastMCP server
app = FastMCP("My Awesome App")
# Add your existing tools here...
# app.add_tool(my_custom_tool)
# Add complete feedback system in one line
add_feedback_tools(app, database_url="sqlite:///feedback.db")
Step 3: Configure Claude Desktop
{
"mcpServers": {
"my-app-with-feedback": {
"command": "python",
"args": ["my_server.py"]
}
}
}
🔧 Customization Options
Database Configuration
# SQLite (development)
add_feedback_tools(app, database_url="sqlite:///feedback.db")
# PostgreSQL (production)
add_feedback_tools(app, database_url="postgresql://user:pass@host/db")
# In-memory (testing)
add_feedback_tools(app, database_url="sqlite:///:memory:")
Analytics Configuration
from fastmcp_feedback import add_feedback_tools, FeedbackInsights
# Enable analytics with custom retention
insights = FeedbackInsights(enabled=True, retention_days=30)
add_feedback_tools(app, insights=insights)
Tool Prefixing
# Add with prefix to avoid naming conflicts
add_feedback_tools(app, prefix="support_")
# Creates: support_submit_feedback, support_list_feedback, etc.
📊 What You Get
Complete CRUD Operations
# Users can submit feedback
await submit_feedback({
"type": "bug",
"title": "App crashes on login",
"description": "Detailed error description",
"submitter": "user@example.com"
})
# Admins can manage feedback
await update_feedback_status({
"feedback_id": "123",
"new_status": "resolved"
})
# Analytics for insights
stats = await get_feedback_statistics()
# Returns: total_count, by_type, by_status, recent_count
Input Validation
- Type Validation - Must be: bug, feature, improvement, question
- Required Fields - title, description, submitter cannot be empty
- Length Limits - title ≤ 255 chars, description ≤ 10,000 chars
- Format Validation - email validation for contact_info (optional)
Database Schema
Automatically creates:
CREATE TABLE feedback (
id INTEGER PRIMARY KEY AUTOINCREMENT,
type VARCHAR(50) NOT NULL,
title VARCHAR(255) NOT NULL,
description TEXT NOT NULL,
submitter VARCHAR(255) NOT NULL,
contact_info VARCHAR(255),
status VARCHAR(50) NOT NULL DEFAULT 'open',
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL
);
🎓 Learning Examples
Basic Usage Pattern
#!/usr/bin/env python3
from fastmcp import FastMCP
from fastmcp_feedback import add_feedback_tools
app = FastMCP("My App")
# Your custom tools
@app.tool()
def my_custom_feature():
return "Custom functionality"
# Add feedback system
add_feedback_tools(app)
# Run server
app.run()
Error Handling
try:
add_feedback_tools(app, database_url="invalid://url")
except Exception as e:
print(f"Failed to add feedback tools: {e}")
# Graceful fallback or alternative configuration
🔍 Under the Hood
What add_feedback_tools() Does
- Creates Database Instance - Initializes FeedbackDatabase with provided URL
- Sets Up Insights - Configures optional analytics collection
- Registers Tools - Adds 5 tools to your FastMCP server
- Validates Configuration - Ensures database connectivity
- Logs Success - Confirms successful integration
Tool Implementation Pattern
# Each tool is implemented as an async function
@app.tool(description="Submit feedback to the system")
async def submit_feedback(request: dict) -> dict:
# Validate input with Pydantic
validated_request = SubmitFeedbackRequest(**request)
# Store in database
feedback = await database.create_feedback(validated_request)
# Record analytics (if enabled)
insights.record_metric("feedback_submitted", metadata)
return {"success": True, "feedback_id": feedback.id}
🚀 Next Steps
For More Features
If you need advanced capabilities, see:
- Demo Server - Complete feature showcase
- Production Server - Environment configuration
- Architecture Guide - System design
For Customization
# Use individual mixins for fine-grained control
from fastmcp_feedback.mixins import SubmissionMixin, RetrievalMixin
submission = SubmissionMixin(database, insights)
submission.register_tools(app, prefix="feedback_")
For Testing
# Test your integration
import pytest
from fastmcp_feedback import add_feedback_tools
@pytest.mark.asyncio
async def test_feedback_integration():
app = FastMCP("Test App")
add_feedback_tools(app, database_url="sqlite:///:memory:")
tools = await app.get_tools()
assert "submit_feedback" in tools
🤝 Contributing
When modifying this example:
- Keep It Simple - This is the "Hello World" of FastMCP Feedback
- Document Changes - Update this file with any modifications
- Test Integration - Ensure the 3-line pattern still works
- Preserve Clarity - Maintain beginner-friendly explanations
This simple integration example proves that adding a complete, production-ready feedback system to any FastMCP server requires just 3 lines of code while providing enterprise-grade functionality.