From ed92b66ec9eb91470c974205d157cfb7ab661d45 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 22:07:22 +0000 Subject: [PATCH 1/5] feat: add SSE transport support This commit adds support for Server-Sent Events (SSE) transport for MCP servers. - Updates `HttpServerConfig` to include an optional `transport` field, defaulting to 'http'. - Updates `connectToServer` to use `SSEClientTransport` when `transport` is set to 'sse'. - Uses `@modelcontextprotocol/sdk/client/sse.js` for SSE transport. - Adds test coverage for the new configuration option. Co-authored-by: Zman771 <605281+Zman771@users.noreply.github.com> --- src/client.ts | 25 +++++++++++++++++++++++-- src/config.ts | 1 + tests/config.test.ts | 19 +++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/client.ts b/src/client.ts index 50731cf..389ab91 100644 --- a/src/client.ts +++ b/src/client.ts @@ -3,6 +3,7 @@ */ import { Client } from '@modelcontextprotocol/sdk/client/index.js'; +import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'; import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'; import type { Tool } from '@modelcontextprotocol/sdk/types.js'; @@ -236,10 +237,17 @@ export async function connectToServer( }, ); - let transport: StdioClientTransport | StreamableHTTPClientTransport; + let transport: + | StdioClientTransport + | StreamableHTTPClientTransport + | SSEClientTransport; if (isHttpServer(config)) { - transport = createHttpTransport(config); + if (config.transport === 'sse') { + transport = createSseTransport(config); + } else { + transport = createHttpTransport(config); + } } else { transport = createStdioTransport(config); @@ -302,6 +310,19 @@ function createHttpTransport( }); } +/** + * Create SSE transport for remote servers + */ +function createSseTransport(config: HttpServerConfig): SSEClientTransport { + const url = new URL(config.url); + + return new SSEClientTransport(url, { + requestInit: { + headers: config.headers, + }, + }); +} + /** * Create stdio transport for local servers * Uses stderr: 'pipe' to capture server output for debugging diff --git a/src/config.ts b/src/config.ts index 99a4e25..695b66c 100644 --- a/src/config.ts +++ b/src/config.ts @@ -48,6 +48,7 @@ export interface HttpServerConfig extends BaseServerConfig { url: string; headers?: Record; timeout?: number; + transport?: 'sse'; } export type ServerConfig = StdioServerConfig | HttpServerConfig; diff --git a/tests/config.test.ts b/tests/config.test.ts index a48602c..f5f70f0 100644 --- a/tests/config.test.ts +++ b/tests/config.test.ts @@ -42,6 +42,25 @@ describe('config', () => { expect((config.mcpServers.test as any).command).toBe('echo'); }); + test('loads server with sse transport', async () => { + const configPath = join(tempDir, 'sse_config.json'); + await writeFile( + configPath, + JSON.stringify({ + mcpServers: { + sse: { + url: 'http://localhost:3000/sse', + transport: 'sse', + }, + }, + }), + ); + + const config = await loadConfig(configPath); + expect(config.mcpServers.sse).toBeDefined(); + expect((config.mcpServers.sse as any).transport).toBe('sse'); + }); + test('throws on missing config file', async () => { const configPath = join(tempDir, 'nonexistent.json'); await expect(loadConfig(configPath)).rejects.toThrow('not found'); From e6672c37222c19ae57b29f8834a226a9d2a150c0 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 22:43:12 +0000 Subject: [PATCH 2/5] feat: add SSE transport support This commit introduces support for the SSE (Server-Sent Events) transport protocol in mcp-cli. - **Config**: Added `SseServerConfig` interface. SSE servers must be explicitly configured with `"type": "sse"`. - **Client**: Added `createSseTransport` which automatically appends `/sse` to the URL if not present, adhering to common conventions for SSE endpoints. - **Client**: Updated `connectToServer` to route connections to the appropriate transport (SSE, HTTP, or Stdio) based on the configuration. - **Tests**: Added unit tests for the new configuration type and type guards. This aligns the implementation with the provided design document, ensuring backward compatibility for existing HTTP server configurations. Co-authored-by: Zman771 <605281+Zman771@users.noreply.github.com> --- src/client.ts | 23 ++++++++++++++--------- src/config.ts | 25 ++++++++++++++++++++++--- tests/config.test.ts | 16 ++++++++++++++-- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/client.ts b/src/client.ts index 389ab91..0e36207 100644 --- a/src/client.ts +++ b/src/client.ts @@ -10,6 +10,7 @@ import type { Tool } from '@modelcontextprotocol/sdk/types.js'; import { type HttpServerConfig, type ServerConfig, + type SseServerConfig, type StdioServerConfig, debug, filterTools, @@ -19,6 +20,7 @@ import { getTimeoutMs, isDaemonEnabled, isHttpServer, + isSseServer, isToolAllowed, } from './config.js'; import { @@ -242,12 +244,10 @@ export async function connectToServer( | StreamableHTTPClientTransport | SSEClientTransport; - if (isHttpServer(config)) { - if (config.transport === 'sse') { - transport = createSseTransport(config); - } else { - transport = createHttpTransport(config); - } + if (isSseServer(config)) { + transport = createSseTransport(config); + } else if (isHttpServer(config)) { + transport = createHttpTransport(config); } else { transport = createStdioTransport(config); @@ -277,7 +277,7 @@ export async function connectToServer( } // For successful connections, forward stderr to console - if (!isHttpServer(config)) { + if (!isHttpServer(config) && !isSseServer(config)) { const stderrStream = (transport as StdioClientTransport).stderr; if (stderrStream) { stderrStream.on('data', (chunk: Buffer) => { @@ -313,8 +313,13 @@ function createHttpTransport( /** * Create SSE transport for remote servers */ -function createSseTransport(config: HttpServerConfig): SSEClientTransport { - const url = new URL(config.url); +function createSseTransport(config: SseServerConfig): SSEClientTransport { + // SSE transport expects the URL to end with /sse + let urlStr = config.url; + if (!urlStr.endsWith('/sse')) { + urlStr = `${urlStr.replace(/\/$/, '')}/sse`; + } + const url = new URL(urlStr); return new SSEClientTransport(url, { requestInit: { diff --git a/src/config.ts b/src/config.ts index 695b66c..dd9108d 100644 --- a/src/config.ts +++ b/src/config.ts @@ -48,10 +48,22 @@ export interface HttpServerConfig extends BaseServerConfig { url: string; headers?: Record; timeout?: number; - transport?: 'sse'; } -export type ServerConfig = StdioServerConfig | HttpServerConfig; +/** + * SSE server configuration (remote) - uses SSE transport + */ +export interface SseServerConfig extends BaseServerConfig { + url: string; + headers?: Record; + timeout?: number; + type: 'sse'; +} + +export type ServerConfig = + | StdioServerConfig + | HttpServerConfig + | SseServerConfig; export interface McpServersConfig { mcpServers: Record; @@ -144,11 +156,18 @@ export function isToolAllowed(toolName: string, config: ServerConfig): boolean { return true; } +/** + * Check if a server config is SSE-based + */ +export function isSseServer(config: ServerConfig): config is SseServerConfig { + return 'url' in config && (config as SseServerConfig).type === 'sse'; +} + /** * Check if a server config is HTTP-based */ export function isHttpServer(config: ServerConfig): config is HttpServerConfig { - return 'url' in config; + return 'url' in config && !isSseServer(config); } /** diff --git a/tests/config.test.ts b/tests/config.test.ts index f5f70f0..f2d3f80 100644 --- a/tests/config.test.ts +++ b/tests/config.test.ts @@ -11,6 +11,7 @@ import { getServerConfig, listServerNames, isHttpServer, + isSseServer, isStdioServer, } from '../src/config'; @@ -50,7 +51,7 @@ describe('config', () => { mcpServers: { sse: { url: 'http://localhost:3000/sse', - transport: 'sse', + type: 'sse', }, }, }), @@ -58,7 +59,7 @@ describe('config', () => { const config = await loadConfig(configPath); expect(config.mcpServers.sse).toBeDefined(); - expect((config.mcpServers.sse as any).transport).toBe('sse'); + expect((config.mcpServers.sse as any).type).toBe('sse'); }); test('throws on missing config file', async () => { @@ -252,6 +253,17 @@ describe('config', () => { test('isHttpServer identifies HTTP config', () => { expect(isHttpServer({ url: 'https://example.com' })).toBe(true); expect(isHttpServer({ command: 'echo' })).toBe(false); + expect(isHttpServer({ url: 'https://example.com', type: 'sse' })).toBe( + false, + ); + }); + + test('isSseServer identifies SSE config', () => { + expect(isSseServer({ url: 'https://example.com', type: 'sse' })).toBe( + true, + ); + expect(isSseServer({ url: 'https://example.com' })).toBe(false); + expect(isSseServer({ command: 'echo' })).toBe(false); }); test('isStdioServer identifies stdio config', () => { From 3bca782b6c588ed222cd606b8e9ff0907260b98f Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 22:53:43 +0000 Subject: [PATCH 3/5] docs: add SSE transport documentation - Updated `README.md` to include a new "SSE Transport (Legacy)" section. - Added configuration examples for enabling SSE transport with `"type": "sse"`. - Included a deprecation note advising users to prefer Streamable HTTP transport for new servers. Co-authored-by: Zman771 <605281+Zman771@users.noreply.github.com> --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 4d1c6a3..315bddc 100644 --- a/README.md +++ b/README.md @@ -299,6 +299,24 @@ The CLI uses `mcp_servers.json`, compatible with Claude Desktop, Gemini or VS Co } ``` +### SSE Transport (Legacy) + +For servers using the deprecated SSE transport protocol, add `"type": "sse"` to the configuration: + +```json +{ + "mcpServers": { + "legacy-server": { + "url": "http://localhost:8000", + "type": "sse" + } + } +} +``` + +> [!NOTE] +> SSE transport is deprecated. New servers should use Streamable HTTP transport. + **Environment Variable Substitution:** Use `${VAR_NAME}` syntax anywhere in the config. Values are substituted at load time. By default, missing environment variables cause an error with a clear message. Set `MCP_STRICT_ENV=false` to use empty values instead (with a warning). ### Tool Filtering From 45dabfd5e8f5ce5f9ba45ffdb4852f4ca75fb4bd Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 23:06:57 +0000 Subject: [PATCH 4/5] Bump version to 0.3.1 and document SSE support - Update version in package.json and src/version.ts - Update CHANGELOG.md with SSE Transport Support details Co-authored-by: Zman771 <605281+Zman771@users.noreply.github.com> --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- src/version.ts | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c56163..8854188 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.3.1] - 2026-02-03 + +### Added + +- **SSE Transport Support** - Support for Server-Sent Events transport protocol + - Requires `type: "sse"` in server config + - Enables connection to MCP servers using SSE (e.g. LangChain, remote servers) + ## [0.3.0] - 2026-01-22 ### Added diff --git a/package.json b/package.json index a1985d7..fcec25c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mcp-cli", - "version": "0.3.0", + "version": "0.3.1", "description": "A lightweight CLI for interacting with MCP (Model Context Protocol) servers", "type": "module", "main": "src/index.ts", diff --git a/src/version.ts b/src/version.ts index dfade73..6cbd37a 100644 --- a/src/version.ts +++ b/src/version.ts @@ -2,4 +2,4 @@ * Version constant - single source of truth * This file is auto-updated by scripts/release.sh */ -export const VERSION = '0.3.0'; +export const VERSION = '0.3.1'; From 1f1a6fcc3bfb7c85d458703229f62d1374052672 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 03:47:32 +0000 Subject: [PATCH 5/5] Bump version to 0.3.1 and document SSE support - Update version in package.json and src/version.ts - Update CHANGELOG.md with SSE Transport Support details Co-authored-by: Zman771 <605281+Zman771@users.noreply.github.com>