Skip to main content
Glama

Coolify MCP Server

by StuMason
mcp-js-readme.md12 kB
# MCP TypeScript SDK ![NPM Version](https://img.shields.io/npm/v/%40modelcontextprotocol%2Fsdk) ![MIT licensed](https://img.shields.io/npm/l/%40modelcontextprotocol%2Fsdk) ## Table of Contents - [Overview](#overview) - [Installation](#installation) - [Quickstart](#quickstart) - [What is MCP?](#what-is-mcp) - [Core Concepts](#core-concepts) - [Server](#server) - [Resources](#resources) - [Tools](#tools) - [Prompts](#prompts) - [Running Your Server](#running-your-server) - [stdio](#stdio) - [HTTP with SSE](#http-with-sse) - [Testing and Debugging](#testing-and-debugging) - [Examples](#examples) - [Echo Server](#echo-server) - [SQLite Explorer](#sqlite-explorer) - [Advanced Usage](#advanced-usage) - [Low-Level Server](#low-level-server) - [Writing MCP Clients](#writing-mcp-clients) - [Server Capabilities](#server-capabilities) ## Overview The Model Context Protocol allows applications to provide context for LLMs in a standardized way, separating the concerns of providing context from the actual LLM interaction. This TypeScript SDK implements the full MCP specification, making it easy to: - Build MCP clients that can connect to any MCP server - Create MCP servers that expose resources, prompts and tools - Use standard transports like stdio and SSE - Handle all MCP protocol messages and lifecycle events ## Installation ```bash npm install @modelcontextprotocol/sdk ``` ## Quick Start Let's create a simple MCP server that exposes a calculator tool and some data: ```typescript import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { z } from 'zod'; // Create an MCP server const server = new McpServer({ name: 'Demo', version: '1.0.0', }); // Add an addition tool server.tool('add', { a: z.number(), b: z.number() }, async ({ a, b }) => ({ content: [{ type: 'text', text: String(a + b) }], })); // Add a dynamic greeting resource server.resource( 'greeting', new ResourceTemplate('greeting://{name}', { list: undefined }), async (uri, { name }) => ({ contents: [ { uri: uri.href, text: `Hello, ${name}!`, }, ], }), ); // Start receiving messages on stdin and sending messages on stdout const transport = new StdioServerTransport(); await server.connect(transport); ``` ## What is MCP? The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) lets you build servers that expose data and functionality to LLM applications in a secure, standardized way. Think of it like a web API, but specifically designed for LLM interactions. MCP servers can: - Expose data through **Resources** (think of these sort of like GET endpoints; they are used to load information into the LLM's context) - Provide functionality through **Tools** (sort of like POST endpoints; they are used to execute code or otherwise produce a side effect) - Define interaction patterns through **Prompts** (reusable templates for LLM interactions) - And more! ## Core Concepts ### Server The McpServer is your core interface to the MCP protocol. It handles connection management, protocol compliance, and message routing: ```typescript const server = new McpServer({ name: 'My App', version: '1.0.0', }); ``` ### Resources Resources are how you expose data to LLMs. They're similar to GET endpoints in a REST API - they provide data but shouldn't perform significant computation or have side effects: ```typescript // Static resource server.resource('config', 'config://app', async (uri) => ({ contents: [ { uri: uri.href, text: 'App configuration here', }, ], })); // Dynamic resource with parameters server.resource( 'user-profile', new ResourceTemplate('users://{userId}/profile', { list: undefined }), async (uri, { userId }) => ({ contents: [ { uri: uri.href, text: `Profile data for user ${userId}`, }, ], }), ); ``` ### Tools Tools let LLMs take actions through your server. Unlike resources, tools are expected to perform computation and have side effects: ```typescript // Simple tool with parameters server.tool( 'calculate-bmi', { weightKg: z.number(), heightM: z.number(), }, async ({ weightKg, heightM }) => ({ content: [ { type: 'text', text: String(weightKg / (heightM * heightM)), }, ], }), ); // Async tool with external API call server.tool('fetch-weather', { city: z.string() }, async ({ city }) => { const response = await fetch(`https://api.weather.com/${city}`); const data = await response.text(); return { content: [{ type: 'text', text: data }], }; }); ``` ### Prompts Prompts are reusable templates that help LLMs interact with your server effectively: ```typescript server.prompt('review-code', { code: z.string() }, ({ code }) => ({ messages: [ { role: 'user', content: { type: 'text', text: `Please review this code:\n\n${code}`, }, }, ], })); ``` ## Running Your Server MCP servers in TypeScript need to be connected to a transport to communicate with clients. How you start the server depends on the choice of transport: ### stdio For command-line tools and direct integrations: ```typescript import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; const server = new McpServer({ name: 'example-server', version: '1.0.0', }); // ... set up server resources, tools, and prompts ... const transport = new StdioServerTransport(); await server.connect(transport); ``` ### HTTP with SSE For remote servers, start a web server with a Server-Sent Events (SSE) endpoint, and a separate endpoint for the client to send its messages to: ```typescript import express from 'express'; import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js'; const server = new McpServer({ name: 'example-server', version: '1.0.0', }); // ... set up server resources, tools, and prompts ... const app = express(); app.get('/sse', async (req, res) => { const transport = new SSEServerTransport('/messages', res); await server.connect(transport); }); app.post('/messages', async (req, res) => { // Note: to support multiple simultaneous connections, these messages will // need to be routed to a specific matching transport. (This logic isn't // implemented here, for simplicity.) await transport.handlePostMessage(req, res); }); app.listen(3001); ``` ### Testing and Debugging To test your server, you can use the [MCP Inspector](https://github.com/modelcontextprotocol/inspector). See its README for more information. ## Examples ### Echo Server A simple server demonstrating resources, tools, and prompts: ```typescript import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'; import { z } from 'zod'; const server = new McpServer({ name: 'Echo', version: '1.0.0', }); server.resource( 'echo', new ResourceTemplate('echo://{message}', { list: undefined }), async (uri, { message }) => ({ contents: [ { uri: uri.href, text: `Resource echo: ${message}`, }, ], }), ); server.tool('echo', { message: z.string() }, async ({ message }) => ({ content: [{ type: 'text', text: `Tool echo: ${message}` }], })); server.prompt('echo', { message: z.string() }, ({ message }) => ({ messages: [ { role: 'user', content: { type: 'text', text: `Please process this message: ${message}`, }, }, ], })); ``` ### SQLite Explorer A more complex example showing database integration: ```typescript import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import sqlite3 from 'sqlite3'; import { promisify } from 'util'; import { z } from 'zod'; const server = new McpServer({ name: 'SQLite Explorer', version: '1.0.0', }); // Helper to create DB connection const getDb = () => { const db = new sqlite3.Database('database.db'); return { all: promisify<string, any[]>(db.all.bind(db)), close: promisify(db.close.bind(db)), }; }; server.resource('schema', 'schema://main', async (uri) => { const db = getDb(); try { const tables = await db.all("SELECT sql FROM sqlite_master WHERE type='table'"); return { contents: [ { uri: uri.href, text: tables.map((t: { sql: string }) => t.sql).join('\n'), }, ], }; } finally { await db.close(); } }); server.tool('query', { sql: z.string() }, async ({ sql }) => { const db = getDb(); try { const results = await db.all(sql); return { content: [ { type: 'text', text: JSON.stringify(results, null, 2), }, ], }; } catch (err: unknown) { const error = err as Error; return { content: [ { type: 'text', text: `Error: ${error.message}`, }, ], isError: true, }; } finally { await db.close(); } }); ``` ## Advanced Usage ### Low-Level Server For more control, you can use the low-level Server class directly: ```typescript import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; const server = new Server( { name: 'example-server', version: '1.0.0', }, { capabilities: { prompts: {}, }, }, ); server.setRequestHandler(ListPromptsRequestSchema, async () => { return { prompts: [ { name: 'example-prompt', description: 'An example prompt template', arguments: [ { name: 'arg1', description: 'Example argument', required: true, }, ], }, ], }; }); server.setRequestHandler(GetPromptRequestSchema, async (request) => { if (request.params.name !== 'example-prompt') { throw new Error('Unknown prompt'); } return { description: 'Example prompt', messages: [ { role: 'user', content: { type: 'text', text: 'Example prompt text', }, }, ], }; }); const transport = new StdioServerTransport(); await server.connect(transport); ``` ### Writing MCP Clients The SDK provides a high-level client interface: ```typescript import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; const transport = new StdioClientTransport({ command: 'node', args: ['server.js'], }); const client = new Client( { name: 'example-client', version: '1.0.0', }, { capabilities: { prompts: {}, resources: {}, tools: {}, }, }, ); await client.connect(transport); // List prompts const prompts = await client.listPrompts(); // Get a prompt const prompt = await client.getPrompt('example-prompt', { arg1: 'value', }); // List resources const resources = await client.listResources(); // Read a resource const resource = await client.readResource('file:///example.txt'); // Call a tool const result = await client.callTool({ name: 'example-tool', arguments: { arg1: 'value', }, }); ``` ## Documentation - [Model Context Protocol documentation](https://modelcontextprotocol.io) - [MCP Specification](https://spec.modelcontextprotocol.io) - [Example Servers](https://github.com/modelcontextprotocol/servers) ## Contributing Issues and pull requests are welcome on GitHub at https://github.com/modelcontextprotocol/typescript-sdk. ## License This project is licensed under the MIT License—see the [LICENSE](LICENSE) file for details.

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/StuMason/coolify-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server