Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export default [
'@frontmcp/uipack',
'@frontmcp/uipack/*',
'@frontmcp/protocol',
'@frontmcp/protocol/client',
'@frontmcp/testing',
'@frontmcp/observability',
'^#(mcp-.+|crypto-.+|async-.+|event-.+|langchain-.+|sse-.+|express-.+|server-.+|stdio-.+|env|runtime-context|path|client|import-computed|js-yaml|semver|uipack-render)$',
Expand Down
16 changes: 8 additions & 8 deletions libs/protocol/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# @frontmcp/protocol

FrontMCP's single point of contact with the upstream [`@modelcontextprotocol/sdk`](https://www.npmjs.com/package/@modelcontextprotocol/sdk): it re-exports the MCP protocol types, server, client and transports that the other `@frontmcp/*` packages use. This is an internal package, published only so those packages can depend on it. Don't import it from application code: import MCP types from [`@frontmcp/sdk`](https://www.npmjs.com/package/@frontmcp/sdk), and use `McpClient` from [`@frontmcp/testing`](https://www.npmjs.com/package/@frontmcp/testing) when a test needs a raw client.
FrontMCP's single point of contact with the upstream [`@modelcontextprotocol/sdk`](https://www.npmjs.com/package/@modelcontextprotocol/sdk): it re-exports the MCP protocol types, server, client and transports that the other `@frontmcp/*` packages use. The client and its transports come from the `@frontmcp/protocol/client` subpath, so a server, or a browser or Worker bundle of one, doesn't load them. This is an internal package, published only so those packages can depend on it. Don't import it from application code: import MCP types from [`@frontmcp/sdk`](https://www.npmjs.com/package/@frontmcp/sdk), and use `McpClient` from [`@frontmcp/testing`](https://www.npmjs.com/package/@frontmcp/testing) when a test needs a raw client.

[![npm](https://img.shields.io/npm/v/@frontmcp/protocol.svg)](https://www.npmjs.com/package/@frontmcp/protocol) [![License](https://img.shields.io/npm/l/@frontmcp/protocol.svg)](https://github.com/agentfront/frontmcp/blob/main/LICENSE)

Expand All @@ -10,13 +10,13 @@ You don't install it yourself: `@frontmcp/sdk` depends on it. It needs Node.js 2

## What it exports

| Area | Contents |
| ------------------- | ---------------------------------------------------------------------------------------------------------------- |
| Protocol types | Everything in `@modelcontextprotocol/sdk/types.js`: requests, results, notifications, schemas, `McpError` |
| Protocol 2026-07-28 | `MCP_20260728_META`, `MCP_20260728_ERROR_CODES`, `CacheableResult`, `DiscoverResult`, `InputRequiredResult`, … |
| Server | `McpServer`, `StreamableHTTPServerTransport`, `WebStandardStreamableHTTPServerTransport`, `StdioServerTransport` |
| Client | `Client`, `StreamableHTTPClientTransport`, `SSEClientTransport`, `StdioClientTransport` |
| Other | `InMemoryTransport`, `Transport`, `RequestHandlerExtra`, `AuthInfo` |
| Area | Contents |
| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| Protocol types | Everything in `@modelcontextprotocol/sdk/types.js`: requests, results, notifications, schemas, `McpError` |
| Protocol 2026-07-28 | `MCP_20260728_META`, `MCP_20260728_ERROR_CODES`, `CacheableResult`, `DiscoverResult`, `InputRequiredResult`, … |
| Server | `McpServer`, `StreamableHTTPServerTransport`, `WebStandardStreamableHTTPServerTransport`, `StdioServerTransport` |
| Client (`@frontmcp/protocol/client`) | `Client`, `StreamableHTTPClientTransport`, `SSEClientTransport`, `StdioClientTransport` |
| Other | `InMemoryTransport`, `Transport`, `RequestHandlerExtra`, `AuthInfo` |

The browser build swaps in browser versions of the server and Streamable HTTP modules through the package's `imports` map. The stdio transports need Node.js: in a browser or worker build they throw when constructed.

Expand Down
11 changes: 11 additions & 0 deletions libs/protocol/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,17 @@
"types": "./dist/index.d.ts",
"default": "./dist/esm/index.mjs"
}
},
"./client": {
"development": "./src/clients.ts",
"require": {
"types": "./dist/clients.d.ts",
"default": "./dist/clients.js"
},
"import": {
"types": "./dist/clients.d.ts",
"default": "./dist/esm/clients.mjs"
}
}
},
"devDependencies": {
Expand Down
6 changes: 4 additions & 2 deletions libs/protocol/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"libs/protocol/src/browser-stdio-server.ts",
"libs/protocol/src/client.ts",
"libs/protocol/src/lazy-client.ts",
"libs/protocol/src/lazy-mcp-streamable-http.ts"
"libs/protocol/src/lazy-mcp-streamable-http.ts",
"libs/protocol/src/clients.ts"
],
"assets": ["libs/protocol/README.md", "libs/protocol/CHANGELOG.md", "LICENSE", "libs/protocol/package.json"],
"esbuildOptions": {
Expand Down Expand Up @@ -79,7 +80,8 @@
"libs/protocol/src/browser-stdio-server.ts",
"libs/protocol/src/client.ts",
"libs/protocol/src/lazy-client.ts",
"libs/protocol/src/lazy-mcp-streamable-http.ts"
"libs/protocol/src/lazy-mcp-streamable-http.ts",
"libs/protocol/src/clients.ts"
],
"esbuildOptions": {
"minifyWhitespace": true,
Expand Down
10 changes: 8 additions & 2 deletions libs/protocol/src/__tests__/exports.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import * as browserStreamableHttp from '../browser-mcp-streamable-http';
import * as browserServerTypes from '../browser-server-types';
import { StdioClientTransport as BrowserStdioClientTransport } from '../browser-stdio-client';
import { StdioServerTransport as BrowserStdioServerTransport } from '../browser-stdio-server';
import * as clients from '../clients';
import { InMemoryTransport } from '../in-memory';
import * as protocol from '../index';
import { Server as NodeServer } from '../node-mcp-server';
Expand All @@ -38,8 +39,13 @@ describe('@frontmcp/protocol exports', () => {
expect(protocol.LATEST_PROTOCOL_VERSION).toBe(LATEST_PROTOCOL_VERSION);
expect(protocol.PROTOCOL_2026_07_28).toBe('2026-07-28');
expect(protocol.StdioServerTransport).toBe(SdkStdioServerTransport);
expect(typeof protocol.Client).toBe('function');
expect(typeof protocol.StreamableHTTPClientTransport).toBe('function');
});

it('serves the MCP client and its transports from the client subpath, not the root', () => {
for (const name of ['Client', 'StreamableHTTPClientTransport', 'SSEClientTransport', 'StdioClientTransport']) {
expect(typeof (clients as Record<string, unknown>)[name]).toBe('function');
expect(name in protocol).toBe(false);
}
});

it('gives browsers stand-ins that say what is not available', () => {
Expand Down
2 changes: 2 additions & 0 deletions libs/protocol/src/clients.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// `@frontmcp/protocol/client`: the MCP client and its transports, kept out of the root that every server and server bundle loads.
export * from '#client';
3 changes: 0 additions & 3 deletions libs/protocol/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ export * from './auth-types';
// Shared protocol types (Transport, RequestHandlerExtra)
export * from './shared';

// MCP Client
export * from '#client';

// Stdio transport
export * from './stdio';

Expand Down
3 changes: 3 additions & 0 deletions libs/sdk/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"@frontmcp/auth",
"@frontmcp/guard",
"@frontmcp/protocol",
"@frontmcp/protocol/*",
"@frontmcp/observability",
"@opentelemetry/api",
"@opentelemetry/sdk-trace-base",
Expand Down Expand Up @@ -89,6 +90,7 @@
"@frontmcp/auth",
"@frontmcp/guard",
"@frontmcp/protocol",
"@frontmcp/protocol/*",
"@frontmcp/observability",
"@opentelemetry/api",
"@opentelemetry/sdk-trace-base",
Expand Down Expand Up @@ -133,6 +135,7 @@
"@frontmcp/auth",
"@frontmcp/guard",
"@frontmcp/protocol",
"@frontmcp/protocol/*",
"@frontmcp/observability",
"@opentelemetry/api",
"@opentelemetry/sdk-trace-base",
Expand Down
2 changes: 1 addition & 1 deletion libs/sdk/src/agent/__tests__/agent-context-wiring.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import 'reflect-metadata';

import { z } from '@frontmcp/lazy-zod';
import {
Client,
LoggingMessageNotificationSchema,
MCP_20260728_META,
type CallToolResult,
type Progress,
} from '@frontmcp/protocol';
import { Client } from '@frontmcp/protocol/client';

import {
createTestFetchServer,
Expand Down
3 changes: 2 additions & 1 deletion libs/sdk/src/agent/__tests__/agent-streaming.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import 'reflect-metadata';

import { z } from '@frontmcp/lazy-zod';
import { Client, type CallToolResult, type Progress } from '@frontmcp/protocol';
import { type CallToolResult, type Progress } from '@frontmcp/protocol';
import { Client } from '@frontmcp/protocol/client';

import {
createTestFetchServer,
Expand Down
18 changes: 9 additions & 9 deletions libs/sdk/src/direct/__tests__/connect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ const mockMcpClient = {
getPrompt: jest.fn().mockResolvedValue({ messages: [] }),
};

jest.mock('@frontmcp/protocol', () => ({
...jest.requireActual('@frontmcp/protocol'),
jest.mock('@frontmcp/protocol/client', () => ({
...jest.requireActual('@frontmcp/protocol/client'),
Client: jest.fn().mockImplementation(() => mockMcpClient),
}));

Expand Down Expand Up @@ -120,7 +120,7 @@ describe('connect utilities', () => {

it('should use default clientInfo when not provided', async () => {
const { connect } = await import('../connect');
const { Client } = await import('@frontmcp/protocol');
const { Client } = await import('@frontmcp/protocol/client');
const config = createTestConfig();

await connect(config);
Expand All @@ -133,7 +133,7 @@ describe('connect utilities', () => {

it('should pass custom clientInfo to MCP client', async () => {
const { connect } = await import('../connect');
const { Client } = await import('@frontmcp/protocol');
const { Client } = await import('@frontmcp/protocol/client');
const config = createTestConfig();

await connect(config, {
Expand Down Expand Up @@ -242,7 +242,7 @@ describe('connect utilities', () => {

it('should pass capabilities to MCP client', async () => {
const { connect } = await import('../connect');
const { Client } = await import('@frontmcp/protocol');
const { Client } = await import('@frontmcp/protocol/client');
const config = createTestConfig();

// Note: ClientCapabilities uses 'roots', not 'tools' (tools is a ServerCapability)
Expand All @@ -262,7 +262,7 @@ describe('connect utilities', () => {
describe('connectOpenAI', () => {
it('should use OpenAI client info', async () => {
const { connectOpenAI } = await import('../connect');
const { Client } = await import('@frontmcp/protocol');
const { Client } = await import('@frontmcp/protocol/client');
const config = createTestConfig();

await connectOpenAI(config);
Expand Down Expand Up @@ -295,7 +295,7 @@ describe('connect utilities', () => {
describe('connectClaude', () => {
it('should use Claude client info', async () => {
const { connectClaude } = await import('../connect');
const { Client } = await import('@frontmcp/protocol');
const { Client } = await import('@frontmcp/protocol/client');
const config = createTestConfig();

await connectClaude(config);
Expand All @@ -307,7 +307,7 @@ describe('connect utilities', () => {
describe('connectLangChain', () => {
it('should use LangChain client info', async () => {
const { connectLangChain } = await import('../connect');
const { Client } = await import('@frontmcp/protocol');
const { Client } = await import('@frontmcp/protocol/client');
const config = createTestConfig();

await connectLangChain(config);
Expand All @@ -319,7 +319,7 @@ describe('connect utilities', () => {
describe('connectVercelAI', () => {
it('should use Vercel AI client info', async () => {
const { connectVercelAI } = await import('../connect');
const { Client } = await import('@frontmcp/protocol');
const { Client } = await import('@frontmcp/protocol/client');
const config = createTestConfig();

await connectVercelAI(config);
Expand Down
6 changes: 3 additions & 3 deletions libs/sdk/src/direct/__tests__/direct-client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,14 @@ const mockMcpClient = {

// MockClient defined inside the mock factory to avoid hoisting issues
// (jest.mock is hoisted, but accessing outer variables before they're defined causes errors)
jest.mock('@frontmcp/protocol', () => ({
...jest.requireActual('@frontmcp/protocol'),
jest.mock('@frontmcp/protocol/client', () => ({
...jest.requireActual('@frontmcp/protocol/client'),
Client: jest.fn().mockImplementation(() => mockMcpClient),
}));

// Import the mocked Client to use in tests for assertions

const { Client: MockClient } = require('@frontmcp/protocol');
const { Client: MockClient } = require('@frontmcp/protocol/client');

describe('DirectClientImpl', () => {
// Minimal mock scope
Expand Down
2 changes: 1 addition & 1 deletion libs/sdk/src/direct/direct-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*/

import {
Client,
ElicitRequestSchema,
ResourceUpdatedNotificationSchema,
type CallToolResult,
Expand All @@ -20,6 +19,7 @@ import {
type ReadResourceResult,
type ServerCapabilities,
} from '@frontmcp/protocol';
import { Client } from '@frontmcp/protocol/client';
import { fileExists, pathResolve, randomUUID } from '@frontmcp/utils';

import { listAllPages } from '../common/utils/list-all-pages.utils';
Expand Down
4 changes: 1 addition & 3 deletions libs/sdk/src/remote-mcp/mcp-client.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@

import { decodeJwtPayloadSafe } from '@frontmcp/auth';
import {
Client,
SSEClientTransport,
StreamableHTTPClientTransport,
type AuthInfo,
type CallToolResult,
type GetPromptResult,
Expand All @@ -18,6 +15,7 @@ import {
type Tool,
type Transport,
} from '@frontmcp/protocol';
import { Client, SSEClientTransport, StreamableHTTPClientTransport } from '@frontmcp/protocol/client';

import { type FrontMcpLogger } from '../common';
import { listAllPages } from '../common/utils/list-all-pages.utils';
Expand Down
2 changes: 1 addition & 1 deletion libs/sdk/src/remote-mcp/mcp-client.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import {
type AuthInfo,
type CallToolResult,
type Client,
type GetPromptResult,
type Prompt,
type ReadResourceResult,
Expand All @@ -16,6 +15,7 @@ import {
type Tool,
type Transport,
} from '@frontmcp/protocol';
import { type Client } from '@frontmcp/protocol/client';

// ═══════════════════════════════════════════════════════════════════
// CONNECTION TYPES
Expand Down
3 changes: 2 additions & 1 deletion libs/sdk/src/skill/__tests__/skill-filter.flow.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'reflect-metadata';

import { Client, InMemoryTransport, type ReadResourceResult } from '@frontmcp/protocol';
import { InMemoryTransport, type ReadResourceResult } from '@frontmcp/protocol';
import { Client } from '@frontmcp/protocol/client';

import {
createTestFetchServer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/
import 'reflect-metadata';

import { Client } from '@frontmcp/protocol';
import { Client } from '@frontmcp/protocol/client';

import { App, LogLevel, Tool, ToolContext } from '../../common';
import { FrontMcpInstance } from '../../front-mcp/front-mcp';
Expand Down
2 changes: 1 addition & 1 deletion libs/sdk/src/transport/in-memory-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export interface InMemoryServerResult {
*
* @example
* ```typescript
* import { Client } from '@frontmcp/protocol';
* import { Client } from '@frontmcp/protocol/client';
* import { FrontMcpInstance, createInMemoryServer } from '@frontmcp/sdk';
*
* // Create a FrontMCP instance
Expand Down
2 changes: 1 addition & 1 deletion libs/sdk/src/transport/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export type {
* @example
* ```typescript
* import { createInMemoryServer } from '@frontmcp/sdk';
* import { Client } from '@frontmcp/protocol';
* import { Client } from '@frontmcp/protocol/client';
*
* const { clientTransport, setAuthInfo, close } = await createInMemoryServer(scope, {
* authInfo: { token: 'jwt-token' }
Expand Down
3 changes: 2 additions & 1 deletion libs/sdk/tsconfig.lib.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"@frontmcp/ui/*": ["libs/ui/dist/*/index.d.ts"],
"@frontmcp/auth": ["libs/auth/dist/index.d.ts"],
"@frontmcp/guard": ["libs/guard/dist/index.d.ts"],
"@frontmcp/protocol": ["libs/protocol/dist/index.d.ts"]
"@frontmcp/protocol": ["libs/protocol/dist/index.d.ts"],
"@frontmcp/protocol/client": ["libs/protocol/dist/clients.d.ts"]
}
},
"include": ["src/**/*.ts"],
Expand Down
4 changes: 2 additions & 2 deletions libs/testing/src/raw-client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
* Raw MCP protocol client re-exports for low-level e2e testing.
* For programmatic access, prefer connect()/connectOpenAI() from @frontmcp/sdk.
*/
export { Client as McpClient } from '@frontmcp/protocol';
export { StdioClientTransport as McpStdioClientTransport } from '@frontmcp/protocol';
export { Client as McpClient } from '@frontmcp/protocol/client';
export { StdioClientTransport as McpStdioClientTransport } from '@frontmcp/protocol/client';
export { isTcpPortListening } from './port-probe';
3 changes: 2 additions & 1 deletion libs/testing/tsconfig.lib.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"@frontmcp/sdk/*": ["libs/sdk/dist/*/index.d.ts"],
"@frontmcp/ui": ["libs/ui/dist/index.d.ts"],
"@frontmcp/ui/*": ["libs/ui/dist/*/index.d.ts"],
"@frontmcp/protocol": ["libs/protocol/dist/index.d.ts"]
"@frontmcp/protocol": ["libs/protocol/dist/index.d.ts"],
"@frontmcp/protocol/client": ["libs/protocol/dist/clients.d.ts"]
}
},
"include": ["src/**/*.ts"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
*/
import 'reflect-metadata';

import { Client, type CallToolResult } from '@frontmcp/protocol';
import { type CallToolResult } from '@frontmcp/protocol';
import { Client } from '@frontmcp/protocol/client';
import { App, createInMemoryServer, FrontMcpInstance, LogLevel, Tool, ToolContext } from '@frontmcp/sdk';

import { ApprovalPlugin } from '../index';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
*/
import 'reflect-metadata';

import { Client, type CallToolResult } from '@frontmcp/protocol';
import { type CallToolResult } from '@frontmcp/protocol';
import { Client } from '@frontmcp/protocol/client';
import {
Adapter,
App,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
import 'reflect-metadata';

import { z } from '@frontmcp/lazy-zod';
import { Client, type CallToolResult } from '@frontmcp/protocol';
import { type CallToolResult } from '@frontmcp/protocol';
import { Client } from '@frontmcp/protocol/client';
import { App, createInMemoryServer, FrontMcpInstance, LogLevel, Tool, ToolContext } from '@frontmcp/sdk';

import CodeCallPlugin from '../codecall.plugin';
Expand Down
Loading
Loading