Claude-skill-registry-data mcp-server

This skill should be used when setting up a stateless MCP (Model Context Protocol) server in FastAPI using the Official MCP SDK with 5 task management tools that interact with SQLModel database.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry-data
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry-data "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/mcp-server" ~/.claude/skills/majiayu000-claude-skill-registry-data-mcp-server && rm -rf "$T"
manifest: data/mcp-server/SKILL.md
source content

MCP Server Setup Skill

This skill provides guidance for setting up a stateless MCP server using the Official MCP SDK in FastAPI.

Purpose

Create a stateless MCP server that provides 5 task management tools (add_task, list_tasks, complete_task, delete_task, update_task) with proper user isolation, database integration, and error handling.

When to Use

Use this skill when:

  • Setting up a new MCP server for chatbot integration
  • Adding MCP tools for task management functionality
  • Creating MCP server infrastructure with database integration
  • Implementing tool chaining and error handling for MCP

Capabilities

  • Stateless Design: Each request independent, no server-side state between calls
  • User Isolation: All tools require user_id and enforce ownership at query level
  • Tool Chaining: Tools designed to be safely called by other tools
  • Async Performance: Full async/await support for concurrent operations
  • Error Handling: Structured errors (400, 401, 403, 404, 500) with descriptive messages

MCP Server Architecture

Server Structure

backend/
├── mcp_server.py      # Main MCP server with FastAPI integration
├── mcp_tools.py       # Tool implementations
├── mcp_config.py      # Server configuration
└── main.py            # Updated with MCP server startup

Tool Signatures

ToolParametersReturns
add_task
user_id: str, title: str, description?: str, priority?: int, due_date?: str{success: bool, task_id: str, task: dict}
list_tasks
user_id: str, status?: str, priority?: int{success: bool, tasks: list[dict]}
complete_task
user_id: str, task_id: str{success: bool, task: dict}
delete_task
user_id: str, task_id: str{success: bool, deleted_task_id: str}
update_task
user_id: str, task_id: str, title?: str, description?: str, priority?: int, due_date?: str{success: bool, task: dict}

Implementation Pattern

MCP Server Setup

from mcp.server.fastapi import FastAPIMCP
from fastapi import FastAPI

app = FastAPI()
mcp_server = FastAPIMCP(app)

@mcp_server.tool()
async def add_task(user_id: str, title: str, description: str = None) -> dict:
    """Add a new task for the specified user."""
    # Extract user_id from context
    # Validate parameters
    # Execute with user_id filter: WHERE user_id = :user_id
    # Return structured JSON response

Database Session Management

from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker

engine = create_async_engine(DATABASE_URL)
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)

async def get_db_session():
    async with async_session() as session:
        yield session

User ID Enforcement

async def add_task(user_id: str, title: str, ...) -> dict:
    if not user_id:
        raise ValueError("user_id is required")

    # Always filter by user_id in queries
    statement = select(Task).where(
        Task.id == task_id,
        Task.user_id == user_id  # Critical for isolation
    )

Tool Implementation Checklist

For each tool, implement:

  1. Parameter Validation: Check required fields, types, and constraints
  2. User ID Extraction: Get user_id from request context or parameters
  3. Database Operation: Execute with proper user_id filtering
  4. Response Construction: Return structured JSON with success status
  5. Error Handling: Catch exceptions and return appropriate error codes
  6. Logging: Log operation outcomes for debugging

Error Taxonomy

StatusConditionExample
400Invalid input parametersMissing required fields, invalid types
401Missing/unauthorized userNo user_id provided
403User not authorizeduser_id doesn't match resource owner
404Resource not foundTask doesn't exist
500Internal errorDatabase connection failed

Tool Chaining Support

Design tools to support chaining:

async def complete_task(user_id: str, task_id: str) -> dict:
    """Mark a task as complete. Can be called by other tools."""
    task = await get_task_by_id(user_id, task_id)
    if task:
        task.completed = True
        await session.commit()
    return {"success": True, "task": task_to_dict(task)}

async def list_tasks(user_id: str, status: str = None) -> dict:
    """List tasks. Supports filtering by status."""
    # This can chain to complete_task or other tools

Dependencies

mcp>=0.9.0
fastapi>=0.100.0
sqlmodel>=0.0.14
sqlalchemy>=2.0.0

Running the Server

cd backend
uvicorn mcp_server:app --host 0.0.0.0 --port 8001

Integration with Main App

# main.py
from mcp_server import mcp

app = FastAPI()
app.include_router(mcp.router)

@app.on_event("startup")
async def startup():
    await mcp.run()

Verification Checklist

  • All 5 tools registered and accessible
  • User ID enforced in every database query
  • JSON responses match specification
  • Error handling returns appropriate codes
  • Tool chaining works correctly
  • Server starts without errors
  • Database connections work