tiny-mcp-server

fredrikpaulin/tiny-mcp-server

3.2

If you are the rightful owner of tiny-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.

Tiny MCP Server is a minimal implementation of the Model Context Protocol (MCP) server for Bun, designed to facilitate communication between clients and server-side tools and resources.

Tools
2
Resources
0
Prompts
0

tiny-mcp-server

A minimal MCP server implementation for Bun. No dependencies, ~150 lines.

Install

bun add tiny-mcp-server

Usage

import { registerTool, registerResource, registerResourceTemplate, sample, serve } from "tiny-mcp-server";

// Register a tool
registerTool(
  "echo",
  "Echoes back the provided message",
  {
    type: "object",
    properties: {
      message: { type: "string", description: "Message to echo back" }
    },
    required: ["message"]
  },
  async ({ message }) => ({ echoed: message })
);

// Register a resource
registerResource(
  "info://server",
  "Server Info",
  "Basic server information",
  "application/json",
  async () => JSON.stringify({ name: "my-server", version: "1.0.0" })
);

// Register a resource template
registerResourceTemplate(
  "env://{name}",
  "Environment Variable",
  "Read an environment variable",
  "text/plain",
  async ({ name }) => process.env[name!] || ""
);

// Use sampling inside a tool
registerTool(
  "summarize",
  "Summarize text using the client's LLM",
  {
    type: "object",
    properties: { text: { type: "string" } },
    required: ["text"]
  },
  async ({ text }) => {
    const summary = await sample({
      messages: [{ role: "user", content: { type: "text", text: `Summarize: ${text}` } }],
      maxTokens: 200
    });
    return { summary };
  }
);

serve({ name: "my-server", version: "1.0.0" });

Run

bun server.ts

Test

# Initialize
echo '{"jsonrpc":"2.0","id":1,"method":"initialize"}' | bun server.ts

# List tools
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | bun server.ts

# Call a tool
echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"echo","arguments":{"message":"hello"}}}' | bun server.ts

# List resources
echo '{"jsonrpc":"2.0","id":1,"method":"resources/list"}' | bun server.ts

# Read a resource
echo '{"jsonrpc":"2.0","id":1,"method":"resources/read","params":{"uri":"info://server"}}' | bun server.ts

# Read a resource template
echo '{"jsonrpc":"2.0","id":1,"method":"resources/read","params":{"uri":"env://HOME"}}' | bun server.ts

API

registerTool(name, description, schema, handler)

Register a tool that can be called by MCP clients.

ParamTypeDescription
namestringTool identifier
descriptionstringHuman-readable description
schemaobjectJSON Schema for input validation
handler(params) => Promise<unknown>Async function to execute

registerResource(uri, name, description, mimeType, handler)

Register a resource that can be read by MCP clients.

ParamTypeDescription
uristringResource URI (e.g. file://config.json)
namestringHuman-readable name
descriptionstringHuman-readable description
mimeTypestringContent type (e.g. application/json)
handler() => Promise<string | Uint8Array>Async function returning content (text or binary)

Text resources return strings, binary resources return Uint8Array (auto base64 encoded):

// Binary resource
registerResource(
  "image://logo",
  "Logo",
  "Company logo",
  "image/png",
  async () => Bun.file("logo.png").bytes()
);

registerResourceTemplate(uriTemplate, name, description, mimeType, handler)

Register a dynamic resource with URI variables.

ParamTypeDescription
uriTemplatestringURI pattern with {var} placeholders
namestringHuman-readable name
descriptionstringHuman-readable description
mimeTypestringContent type
handler(vars) => Promise<string | Uint8Array>Async function receiving extracted variables

sample(options)

Request an LLM completion from the client. Can only be used inside tool/resource handlers after serve() is running.

ParamTypeDescription
options.messagesSampleMessage[]Conversation messages
options.maxTokensnumberMax tokens to generate (default: 1000)
options.temperaturenumberSampling temperature (optional)
options.systemPromptstringSystem prompt (optional)

Returns Promise<string> with the assistant's response text.

const response = await sample({
  messages: [
    { role: "user", content: { type: "text", text: "Hello!" } }
  ],
  maxTokens: 100
});

serve(options?)

Start the MCP server on stdio.

ParamTypeDescription
options.namestringServer name (default: "mcp-server")
options.versionstringServer version (default: "1.0.0")

License

MIT