El registro (logging) y las notificaciones de progreso son sencillos de implementar, pero marcan una gran diferencia en la experiencia del usuario al trabajar con servidores MCP. Ayudan a los usuarios a entender qué está sucediendo durante operaciones de larga duración, en lugar de preguntarse si algo se ha roto.
Cuando Claude llama a una herramienta que tarda en completarse, como investigar un tema o procesar datos, los usuarios normalmente no ven nada hasta que la operación termina. Esto puede resultar frustrante porque no saben si la herramienta está funcionando o se ha detenido.
Con el registro y las notificaciones de progreso habilitados, los usuarios obtienen retroalimentación en tiempo real que muestra exactamente qué está sucediendo detrás de escena. Pueden ver barras de progreso, mensajes de estado y registros detallados mientras se ejecuta la operación.
Cómo funciona
En el SDK de Python de MCP, el registro y las notificaciones de progreso funcionan a través del argumento Context que se proporciona automáticamente a tus funciones de herramienta. Este objeto de contexto te da métodos para comunicarte de vuelta con el cliente durante la ejecución.
@mcp.tool(
name="research",
description="Research a given topic"
)
async def research(
topic: str = Field(description="Topic to research"),
*,
context: Context
):
await context.info("About to do research...")
await context.report_progress(20, 100)
sources = await do_research(topic)
await context.info("Writing report...")
await context.report_progress(70, 100)
results = await generate_report(sources)
return resultsLos métodos clave que usarás son:
context.info()- Envía mensajes de registro al clientecontext.report_progress()- Actualiza el progreso con los valores actual y total
Implementación del lado del cliente
En el lado del cliente, necesitas configurar funciones de callback para manejar estas notificaciones. El servidor emite estos mensajes, pero depende de tu aplicación cliente decidir cómo presentarlos a los usuarios.
async def logging_callback(params: LoggingMessageNotificationParams):
print(params.data)
async def print_progress_callback(
progress: float, total: float | None, message: str | None
):
if total is not None:
percentage = (progress / total) * 100
print(f"Progress: {progress}/{total} ({percentage:.1f}%)")
else:
print(f"Progress: {progress}")
async def run():
async with stdio_client(server_params) as (read, write):
async with ClientSession(
read,
write,
logging_callback=logging_callback
) as session:
await session.initialize()
await session.call_tool(
name="add",
arguments={"a": 1, "b": 3},
progress_callback=print_progress_callback,
)Proporcionas el callback de registro al crear la sesión del cliente, y el callback de progreso al realizar llamadas individuales a herramientas. Esto te da flexibilidad para manejar diferentes tipos de notificaciones de manera adecuada.
Opciones de presentación
Cómo presentes estas notificaciones depende del tipo de tu aplicación:
- Aplicaciones CLI - Simplemente imprime mensajes y progreso en la terminal
- Aplicaciones web - Usa WebSockets, eventos enviados por el servidor (server-sent events) o sondeo (polling) para enviar actualizaciones al navegador
- Aplicaciones de escritorio - Actualiza barras de progreso y pantallas de estado en tu interfaz de usuario
Recuerda que implementar estas notificaciones es completamente opcional. Puedes optar por ignorarlas por completo, mostrar solo ciertos tipos, o presentarlas de la manera que tenga sentido para tu aplicación. Son simplemente mejoras de experiencia de usuario para ayudar a los usuarios a entender qué está sucediendo durante operaciones de larga duración.