muppet logo
Concepts

Transports

Connect your server to LLMs

Transports basically defines how the messages will be shared between the LLMs and your server. We use bridge function to connect the muppet instance with the transport layer. You can learn more about the bridge function here

Examples for all these transports are available here. You can learn more about transports in the MCP documentation.

Stdio Transport

The StdioServerTransport is a transport layer that allows you to connect your server to LLMs using standard input and output streams. This transport layer is useful for running your server in environments where you don't have access to a network, such as in a local development environment or in a container or a private network.

import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { Hono } from "hono";
import { bridge, muppet } from "muppet";
 
const app = new Hono();
 
// Define your tools, prompts, and resources here
// ...
 
bridge({
  mcp: muppet(app, {
    name: "My Muppet",
    version: "1.0.0",
  }),
  transport: new StdioServerTransport(),
});
 

This does blocks your stdio streams, so you won't be able to use console.log or other stdio functions while the server is running. muppet has a built-in logger that you can use to log messages. You can use the logger prop to set the logger for your server. It uses pino under the hood, so you can use any pino compatible logger.

muppet(app, {
  logger: pino(
    pino.destination(
      "./muppet.log",
    ),
  )
})

This will store all the logs in the muppet.log file.

SSE Transport

The SSEServerTransport is a transport layer that allows you to connect your server to LLMs using Server-Sent Events (SSE). This transport layer only runs in nodejs runtime.

import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
import { Hono } from "hono";
import { bridge, muppet } from "muppet";
import express from "express";
 
const app = new Hono();
 
// Define your tools, prompts, and resources here
// ...
 
const mcp = muppet(app, {
  name: "My Muppet",
  version: "1.0.0",
});
 
let transport: SSEServerTransport | null = null;
 
const server = express().use((req, res, next) => {
  console.log("Request received", req.url);
  next();
});
 
server.get("/sse", async (req, res) => {
  transport = new SSEServerTransport("/messages", res);
 
  bridge({
    mcp,
    transport,
  });
});
 
server.post("/messages", (req, res) => {
  if (transport) {
    transport.handlePostMessage(req, res);
  }
});
 
server.listen(3001);
 

There is a better way, which is to use SSEHonoTransport which runs on all runtimes which support streaming with hono.

SSE Hono Transport

This transport layer is similar to SSEServerTransport, but it uses the hono's streaming capabilities to send the response. This makes running this transport layer on all runtimes which support streaming, such as nodejs, deno, bun, and cloudflare workers. You can learn more about this in the hono documentation.

import { serve } from "@hono/node-server";
import { Hono } from "hono";
import { bridge, muppet } from "muppet";
import { SSEHonoTransport, streamSSE } from "muppet/streaming";
 
const app = new Hono();
 
// Define your tools, prompts, and resources here
// ...
 
const mcp = muppet(app, {
  name: "My Muppet",
  version: "1.0.0",
});
 
let transport: SSEHonoTransport | null = null;
 
const server = new Hono();
 
server.get("/sse", async (c) => {
  return streamSSE(c, async (stream) => {
    transport = new SSEHonoTransport("/messages");
    transport.connectWithStream(stream);
 
    await bridge({
      mcp,
      transport,
    });
  });
});
 
server.post("/messages", async (c) => {
  if (!transport) {
    throw new Error("Transport not initialized");
  }
 
  await transport.handlePostMessage(c);
  return c.text("ok");
});
 
server.onError((err, c) => {
  console.error(err);
  return c.body(err.message, 500);
});
 
serve(
  {
    fetch: server.fetch,
    port: 3001,
  },
  (info) => {
    console.log(`Server started at http://localhost:${info.port}`);
  },
);
 

On this page