FastMCP Multi-Tenancy

by timothywangdev
Verified

remote-capable server

The server can be hosted and run remotely because it primarily relies on remote services or has no dependency on the local environment.

Integrations

  • Supports serverless deployment to AWS Lambda with state persistence across function invocations.

  • Supports deployment as a scalable application with multiple replicas for high availability and load balancing.

  • Enables authorized access to Notion databases and pages with capabilities for searching, reading, writing, and deleting content with granular permission scopes.

MCPToolKit: marco de servidor MCP listo para producción

Los problemas que resolvemos

1. Escalado de servidores MCP en producción

El marco estándar FastMCP enfrenta desafíos importantes en entornos de producción:

  • Administración del estado : los servidores FastMCP tradicionales mantienen el estado en la memoria, lo que dificulta el escalamiento horizontal
  • Limitaciones sin servidor : los entornos sin servidor requieren arquitecturas sin estado, para las cuales FastMCP no fue diseñado.
  • Compatibilidad con múltiples inquilinos : ejecutar varios inquilinos en el mismo servidor requiere una gestión de sesiones compleja.

2. Compatibilidad con OAuth delegado

Administrar la autenticación para servidores MCP es complejo:

  • Autenticación a nivel de herramienta : los usuarios solo deben autenticarse cuando una herramienta lo requiera
  • Integración de terceros : la compatibilidad con OAuth para servicios como Notion, Slack, etc. requiere una gestión de tokens compleja.
  • Seguridad : Administrar múltiples flujos de autenticación manteniendo la seguridad es un desafío

Nuestra solución

MCPToolKit proporciona un marco de trabajo listo para producción que soluciona estos problemas y mantiene total compatibilidad con FastMCP. Así funciona:

Este diagrama de arquitectura ilustra cómo MCPToolKit permite servidores MCP listos para producción:

  1. Los clientes LLM (p. ej., Claude, ChatGPT, Cursor) inician solicitudes al servidor MCP. Estos clientes pueden ser cualquier aplicación que necesite interactuar con las herramientas MCP.
  2. Load Balancer distribuye las solicitudes entrantes entre múltiples instancias de servidor MCP, lo que permite el escalamiento horizontal y la alta disponibilidad.
  3. Las instancias del servidor MCP (1 a N) gestionan la ejecución de herramientas y el acceso a recursos. Cada instancia:
    • Mantiene su propio estado de Redis para la persistencia de la sesión.
    • Puede gestionar solicitudes de forma independiente
    • Comparte la misma base de código y configuración
    • Se puede escalar horizontalmente según la demanda.
  4. Redis funciona como tienda estatal central y proporciona:
    • Persistencia del estado de la sesión tras reinicios del servidor
    • Almacenamiento y gestión de tokens OAuth
    • Estado compartido entre instancias del servidor
    • Habilita instancias de servidor sin estado
  5. El servidor de autorización MCP (resaltado en rosa) administra todas las operaciones relacionadas con OAuth:
    • Implementa OAuth 2.1 con PKCE para autenticación segura
    • Maneja la emisión y actualización de tokens
    • Gestiona los flujos de consentimiento
    • Centraliza la lógica de OAuth para todas las instancias del servidor
  6. Los proveedores de OAuth (p. ej., Notion y Slack) son servicios de terceros con los que los usuarios pueden autenticarse. El servidor de autorización gestiona estas conexiones de forma segura.

Esta arquitectura permite:

  • Escalabilidad horizontal real a través de instancias de servidor sin estado
  • Gestión centralizada de OAuth
  • Alta disponibilidad a través de múltiples instancias de servidor
  • Gestión segura de tokens
  • Experiencia de usuario consistente en todas las sesiones

Migración desde FastMCP

Migrar de FastMCP a MCPToolKit es sencillo. Aquí te explicamos cómo actualizar tu servidor FastMCP:

# Before (FastMCP) - from mcp.server.fastmcp import FastMCP - - # Create an MCP server - mcp = FastMCP("Demo") # After (MCPToolKit) + from mcptoolkit import MCPToolKit + import os + + # Create a production-ready MCP server + mcp = MCPToolKit( + name="Demo", + redis_url=os.environ["REDIS_URL"] # Required: Set REDIS_URL in your environment + ) # Your tools and resources remain exactly the same @mcp.tool() def add(a: int, b: int) -> int: """Add two numbers""" return a + b @mcp.resource("greeting://{name}") def get_greeting(name: str) -> str: """Get a personalized greeting""" return f"Hello, {name}!"

La migración requiere sólo unos pocos cambios simples:

  1. Cambiar la declaración de importación
  2. Establezca la variable de entorno REDIS_URL (necesaria para producción)
  3. ¡Listo! Todas tus herramientas, recursos e indicaciones siguen funcionando igual que antes.

Para el desarrollo local, puede configurar la variable de entorno:

export REDIS_URL="redis://localhost:6379/0"

Para implementaciones sin servidor, también deberá actualizar su configuración de implementación:

# Before (FastMCP) - # api/index.py - from mcp.server.fastmcp import FastMCP - - mcp = FastMCP("Demo") - app = mcp.create_fastapi_app() # After (MCPToolKit) + # api/index.py + from mcptoolkit.vercel import create_vercel_app + import os + + app = create_vercel_app( + name="Demo", + redis_url=os.environ["REDIS_URL"] # Required: Set REDIS_URL in your environment + )

Características principales:

  • Estado respaldado por Redis : el estado de la sesión persiste tras reinicios del servidor e invocaciones de funciones
  • Listo para usar sin servidor : diseñado para Vercel, AWS Lambda y otras plataformas sin servidor
  • Escalamiento horizontal : la persistencia del estado permite un verdadero escalamiento horizontal
  • Compatibilidad con múltiples inquilinos : varios usuarios pueden conectarse al mismo punto final con sesiones aisladas

2. Compatibilidad con OAuth delegado

from mcptoolkit import MCPToolKit, requires_auth from mcptoolkit.auth.providers import NotionProvider, SlackProvider # Define default scopes for each provider default_notion_scopes = [ "read:database", "write:page", "read:page" ] default_slack_scopes = [ "channels:read", "chat:write", "reactions:write" ] server = MCPToolKit(name="Auth Server") @server.tool() @requires_auth(provider=NotionProvider( scopes=default_notion_scopes, consent_required=True # Require explicit user consent )) def notion_search(query: str, ctx: Context) -> str: # Access authenticated Notion client with specific scopes notion = ctx.get_oauth_client("notion") return notion.search(query) @server.tool() @requires_auth(provider=SlackProvider( scopes=default_slack_scopes, consent_required=True )) def slack_message(channel: str, message: str, ctx: Context) -> str: # Access authenticated Slack client with specific scopes slack = ctx.get_oauth_client("slack") return slack.post_message(channel, message)

Características principales:

  • Autenticación perezosa : los usuarios solo se autentican cuando una herramienta lo requiere
  • Soporte de proveedores : Soporte integrado para proveedores comunes (Notion, Slack, etc.)
  • Gestión de tokens : actualización y almacenamiento automático de tokens
  • Seguridad : Almacenamiento y transmisión seguros de tokens
  • Ámbitos granulares : control detallado sobre los permisos OAuth
  • Gestión del consentimiento : pantallas de consentimiento fáciles de usar con agrupaciones lógicas de permisos
  • Human-in-the-Loop : Requisitos de aprobación opcionales para acciones de alto riesgo

Flujo de OAuth

MCPToolKit implementa un flujo OAuth 2.1 seguro con PKCE:

  1. El cliente LLM inicia una solicitud a un servidor MCP
  2. El servidor responde con un error 401 No autorizado y redirecciona el enlace
  3. El usuario inicia sesión en el proveedor OAuth y otorga los alcances solicitados
  4. El servidor devuelve un código de autorización al cliente
  5. El cliente intercambia el código por tokens de acceso y actualización
  6. Los tokens se utilizan para solicitudes posteriores
  7. El servidor MCP llama al servicio de terceros

Arquitectura del servidor de autorización

MCPToolKit admite dos modelos de implementación para el servidor de autorización:

  1. Servidor de autorización integrado
    • El servidor MCP actúa como proveedor de identidad y parte confiada
    • Gestiona directamente el inicio de sesión, el consentimiento y la emisión de tokens.
    • Administra la duración de los tokens, la lógica de actualización y la revocación.
    • Ideal para aplicaciones independientes
  2. Servidor de autorización externo
    • El servidor MCP actúa como una parte confiada
    • Delega el flujo OAuth a servicios externos (por ejemplo, Stytch)
    • Se centra en el control de acceso a nivel de herramientas
    • Ideal para integrarse con la infraestructura de identidad existente

Ambos modelos admiten:

  • OAuth 2.1 con PKCE
  • Registro dinámico de clientes
  • Metadatos del servidor de autorización (RFC 8414)
  • Ámbitos personalizados basados en recursos/acciones
  • Gestión del consentimiento del usuario final
  • Definiciones de alcance granulares por proveedor
  • Visibilidad y control a nivel de organización
  • Permisos implícitos (los usuarios sólo pueden otorgar los permisos que tienen)

Gestión del consentimiento y acceso

MCPToolKit proporciona una gestión integral del consentimiento y el acceso:

  • Visibilidad a nivel de organización : vea todas las aplicaciones conectadas autorizadas en su organización
  • Permisos granulares : vea qué miembros han otorgado acceso y qué ámbitos han autorizado.
  • Gestión de acceso : revoque el acceso a usuarios o aplicaciones específicas en cualquier momento
  • Consentimiento fácil de usar : presente los permisos RBAC en agrupaciones lógicas
  • Permisos implícitos : los usuarios solo pueden otorgar a una aplicación los mismos permisos que ellos tienen
  • Human-in-the-Loop : Requerir la aprobación humana para acciones de alto riesgo

Protección de acciones de alto riesgo

@server.tool() @requires_auth(provider=NotionProvider( scopes=["delete:database"], human_approval_required=True # Require explicit human approval )) def delete_database(database_id: str, ctx: Context) -> str: # This action will require explicit human approval notion = ctx.get_oauth_client("notion") return notion.delete_database(database_id)

Arquitectura

Opciones de implementación

Kubernetes

apiVersion: apps/v1 kind: Deployment metadata: name: mcp-server spec: replicas: 3 template: spec: containers: - name: mcp-server image: your-mcp-server env: - name: REDIS_URL valueFrom: secretKeyRef: name: redis-credentials key: url

Sin servidor (Vercel)

# api/index.py from mcptoolkit.vercel import create_vercel_app app = create_vercel_app( name="Serverless MCP", redis_url=os.environ.get("REDIS_URL") )

Inicio rápido

  1. Instalar MCPToolKit:
pip install mcp-python-sdk
  1. Crea tu servidor:
from mcptoolkit import MCPToolKit, requires_auth server = MCPToolKit( name="My Production Server", redis_url="redis://localhost:6379/0" ) @server.tool() def public_tool() -> str: return "This tool doesn't require auth" @server.tool() @requires_auth(provider="notion") def notion_tool() -> str: return "This tool requires Notion auth"
  1. Implemente en su plataforma preferida (Kubernetes, Vercel, etc.)

Requisitos

  • Python 3.9+
  • Instancia de Redis (para la persistencia del estado de la sesión)
  • Credenciales del proveedor de OAuth (si se utiliza autenticación delegada)

Licencia

Igual que el SDK de Python de MCP.

-
security - not tested
F
license - not found
-
quality - not tested

Una implementación multiinquilino y sin servidor de servidores MCP que se ejecuta en Vercel con modo de cómputo fluido, lo que permite que varios usuarios se conecten al mismo punto final mientras mantienen el estado de la sesión a través de Redis.

  1. The Problems We Solve
    1. 1. Scaling MCP Servers in Production
    2. 2. Delegated OAuth Support
  2. Our Solution
    1. Migration from FastMCP
      1. 2. Delegated OAuth Support
      2. OAuth Flow
      3. Authorization Server Architecture
      4. Consent and Access Management
      5. High-Risk Action Protection
    2. Architecture
      1. Deployment Options
    3. Quick Start
      1. Requirements
        1. License
          ID: 98dm4qyvdr