Multimedia
Traducción automática
Esta página se tradujo automáticamente a partir de la documentación en inglés, y la página en inglés es la versión de referencia. Si algo no se lee bien, Traducciones explica cómo avisarnos.
El texto no es lo único que puede devolver una herramienta.
El SDK incluye dos utilidades para resultados binarios (Image y Audio) y un tipo Icon para darles a tu servidor, herramientas, recursos y prompts una cara visible en la interfaz del cliente.
Devolver una imagen
Anota el tipo de retorno como Image, apúntalo a un archivo y devuélvelo:
from pathlib import Path
from mcp.server import MCPServer
from mcp.server.mcpserver import Image
mcp = MCPServer("Brand kit")
LOGO_FILE = Path(__file__).parent / "logo.png" # or the path to your file on disk
@mcp.tool()
def logo() -> Image:
"""The brand logo as a PNG."""
return Image(path=LOGO_FILE)
Imageacepta exactamente uno de los dos:path(un archivo que leer) odata(bytes en bruto).- El tipo MIME que ve el cliente se deduce del sufijo:
logo.pngse anuncia comoimage/png. - No hay nada especial en que sea un logo. Cualquier PNG junto a
server.pysirve: una gráfica que generó tu código, un diagrama, una foto.
Image es una comodidad del SDK, no un tipo del protocolo. En lo que se transmite, el valor devuelto se convierte en un bloque ImageContent (los bytes del archivo codificados en base64, más el tipo MIME):
result.content # [ImageContent(type="image", data="iVBORw0KGgoAAAANSUhEUg...", mime_type="image/png")]
result.structured_content # None
Dos cosas que notar:
dataestá en base64. Nunca tocaste los bytes; el SDK leyó el archivo e hizo la codificación.structured_contentesNone. UnImagees contenido para que lo mire el modelo, no datos para que los analice la aplicación: no hay esquema de salida. (Compara con Salida estructurada, donde la anotación de retorno es el esquema.)
Info
ImageContent y AudioContent viven en mcp.types, justo al lado del TextContent
en el que se convierte un resultado str simple (Herramientas). El resultado de una herramienta es una lista de bloques de contenido; Image y Audio son
la forma más corta de producir los dos tipos binarios.
Pruébalo
Coloca cualquier PNG junto a server.py, llámalo logo.png y ejecuta:
uv run mcp dev server.py
Abre la pestaña Tools y llama a logo. El resultado no es una cadena: es un bloque de contenido image, y el Inspector muestra tu imagen. Todo lo que hay entre el archivo en disco y los píxeles en pantalla lo hizo el SDK.
Devolver audio
Audio tiene la misma forma. Deja logo.png donde estaba y pon cualquier WAV a su lado como chime.wav:
from pathlib import Path
from mcp.server import MCPServer
from mcp.server.mcpserver import Audio, Image
mcp = MCPServer("Brand kit")
LOGO_FILE = Path(__file__).parent / "logo.png"
CHIME_FILE = Path(__file__).parent / "chime.wav"
@mcp.tool()
def logo() -> Image:
"""The brand logo as a PNG."""
return Image(path=LOGO_FILE)
@mcp.tool()
def chime() -> Audio:
"""The notification chime as a WAV."""
return Audio(path=CHIME_FILE)
El resultado es un bloque AudioContent:
result.content # [AudioContent(type="audio", data="UklGR...", mime_type="audio/wav")]
result.structured_content # None
Lo mismo: entra un archivo en disco, salen base64 y un tipo MIME, sin esquema de salida.
Bytes o un archivo
Ambas utilidades aceptan también data= (bytes en bruto) en lugar de path=. Ese es el modo para los bytes que nunca vinieron de un archivo propio: una columna de base de datos, una respuesta HTTP, algo que Pillow acaba de dibujar:
from pathlib import Path
from mcp.server import MCPServer
from mcp.server.mcpserver import Image
mcp = MCPServer("Brand kit")
LOGO_FILE = Path(__file__).parent / "logo.png"
@mcp.tool()
def logo_from_bytes() -> Image:
"""The brand logo as a PNG."""
png = LOGO_FILE.read_bytes() # a database read, an HTTP response, Pillow output...
return Image(data=png, format="png")
Con path= no hay nada que declarar: el archivo se lee cuando se construye el resultado y el tipo MIME se deduce del sufijo:
Image:.png,.jpg,.jpeg,.gif,.webp.Audio:.wav,.mp3,.ogg,.flac,.aac,.m4a.
Un sufijo que no reconoce recurre a application/octet-stream.
Check
Con data= no hay nombre de archivo, así que no hay nada de lo que deducir. Olvida format= y
el SDK recurre a un valor por defecto: image/png para imágenes, audio/wav para audio. Construye un
Audio así a partir de bytes MP3 y al cliente se le dice mime_type="audio/wav", y entonces
falla fielmente al decodificarlo. Cuando pases data=, pasa format=.
Iconos
Un Icon es metadatos, no contenido. No lleva la imagen; apunta a una con una URI, y el cliente puede descargarla y mostrarla junto al nombre de tu servidor, una herramienta, un recurso o un prompt.
from mcp.server import MCPServer
from mcp.types import Icon
LOGO = Icon(src="https://example.com/brand-kit.png", mime_type="image/png", sizes=["48x48"])
PALETTE = Icon(src="https://example.com/palette.svg", mime_type="image/svg+xml", sizes=["any"])
mcp = MCPServer("Brand kit", icons=[LOGO])
@mcp.tool(icons=[PALETTE])
def palette() -> list[str]:
"""The brand colour palette as hex codes."""
return ["#1d4ed8", "#f59e0b", "#10b981"]
@mcp.resource("brand://guidelines", icons=[LOGO])
def guidelines() -> str:
"""How to use the brand assets."""
return "Use the primary colour for calls to action."
srces una URI que el cliente puede resolver:https:, o una URIdata:si quieres el icono incrustado sin una descarga extra.mime_typeysizes("48x48", o"any"para un formato escalable) permiten al cliente elegir el adecuado cuando ofreces varios.theme="light"otheme="dark"marca un icono para un esquema de color.
El mismo argumento nombrado icons=[...] lo aceptan MCPServer(...), @mcp.tool(), @mcp.resource() y @mcp.prompt().
Dónde los ve un cliente
Los iconos viajan con lo que decoran. Los del servidor llegan cuando el cliente se conecta, en client.server_info (opcional en conexiones de la generación 2026, así que acota el tipo primero):
assert client.server_info is not None # python-sdk servers identify themselves by default
client.server_info.icons # [Icon(src="https://example.com/brand-kit.png", mime_type="image/png", sizes=["48x48"])]
Los iconos de una herramienta están en el objeto Tool de tools/list, los de un recurso en el Resource de resources/list, los de un prompt en el Prompt de prompts/list. El campo siempre se llama icons.
Resumen
- Devuelve un
Imageo unAudiodesde una herramienta y el cliente recibe un bloqueImageContent/AudioContent: tus bytes codificados en base64, con un tipo MIME. - Constrúyelo a partir de un
path=y deja que el sufijo decida el tipo MIME, o a partir dedata=en memoria más unformat=explícito. - Los resultados multimedia no llevan
structured_contentni esquema de salida. - Un
Icones un puntero: una URIsrcmásmime_type,sizesythemeopcionales. icons=[...]funciona en el servidor, en herramientas, en recursos y en prompts, y los clientes los encuentran en los objetos correspondientes.
Eso es todo lo que una herramienta puede poner dentro de un resultado. Lo que ocurre cuando una herramienta falla (y quién debería enterarse) está en Manejo de errores.