Skip to content
Merged
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
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Include what changed, why, and how to migrate. Search for related sections and g
- **TypeScript**: Strict type checking, ES modules, explicit return types
- **Naming**: PascalCase for classes/types, camelCase for functions/variables
- **Files**: Lowercase with hyphens, test files with `.test.ts` suffix
- **Imports**: ES module style, include `.js` extension, group imports logically
- **Imports**: ES module style, no `.js` extension on relative imports (project uses `moduleResolution: bundler`), group imports logically
- **Formatting**: 2-space indentation, semicolons required, single quotes preferred
- **Testing**: Place tests under each package's `test/` directory (vitest only includes `test/**/*.test.ts`), use descriptive test names
- **Comments**: JSDoc for public APIs, inline comments for complex logic
Expand Down
2 changes: 1 addition & 1 deletion common/eslint-config/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default defineConfig(
settings: {
'import/resolver': {
typescript: {
// Let the TS resolver handle NodeNext-style imports like "./foo.js"
// Resolve extensionless relative imports (moduleResolution: bundler) to their TS sources
extensions: ['.js', '.jsx', '.ts', '.tsx', '.d.ts'],
// Use the tsconfig in each package root (when running ESLint from that package)
project: 'tsconfig.json'
Expand Down
4 changes: 2 additions & 2 deletions common/tsconfig/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"compilerOptions": {
"target": "esnext",
"lib": ["esnext"],
"module": "NodeNext",
"moduleResolution": "NodeNext",
"module": "ESNext",
"moduleResolution": "bundler",
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
Expand Down
16 changes: 9 additions & 7 deletions docs/client-quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,10 @@ Create a `tsconfig.json` in the root of your project:
```json
{
"compilerOptions": {
"target": "ES2023",
"lib": ["ES2023"],
"module": "Node16",
"moduleResolution": "Node16",
"target": "ESNext",
"lib": ["ESNext"],
"module": "ESNext",
"moduleResolution": "bundler",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
Expand Down Expand Up @@ -236,7 +236,8 @@ Now let's add the core functionality for processing queries and handling tool ca
messages,
});

finalText.push(followUp.content[0].type === 'text' ? followUp.content[0].text : '');
const firstBlock = followUp.content[0];
finalText.push(firstBlock?.type === 'text' ? firstBlock.text : '');
}
}

Expand Down Expand Up @@ -284,13 +285,14 @@ Finally, we'll add the main execution logic:

```ts source="../examples/client-quickstart/src/index.ts#main"
async function main() {
if (process.argv.length < 3) {
const serverScriptPath = process.argv[2];
if (!serverScriptPath) {
console.log('Usage: node build/index.js <path_to_server_script>');
return;
}
const mcpClient = new MCPClient();
try {
await mcpClient.connectToServer(process.argv[2]);
await mcpClient.connectToServer(serverScriptPath);

// Check if we have a valid API key to continue
const apiKey = process.env.ANTHROPIC_API_KEY;
Expand Down
7 changes: 4 additions & 3 deletions docs/server-quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,10 @@ Create a `tsconfig.json` in the root of your project:
```json
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"target": "ESNext",
"lib": ["ESNext"],
"module": "ESNext",
"moduleResolution": "bundler",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
Expand Down
1 change: 1 addition & 0 deletions examples/client-quickstart/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"@modelcontextprotocol/client": "workspace:^"
},
"devDependencies": {
"@modelcontextprotocol/tsconfig": "workspace:^",
"@types/node": "^24.10.1",
"typescript": "catalog:devTools"
}
Expand Down
8 changes: 5 additions & 3 deletions examples/client-quickstart/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ class MCPClient {
messages,
});

finalText.push(followUp.content[0].type === 'text' ? followUp.content[0].text : '');
const firstBlock = followUp.content[0];
finalText.push(firstBlock?.type === 'text' ? firstBlock.text : '');
}
}

Expand Down Expand Up @@ -156,13 +157,14 @@ class MCPClient {

//#region main
async function main() {
if (process.argv.length < 3) {
const serverScriptPath = process.argv[2];
if (!serverScriptPath) {
console.log('Usage: node build/index.js <path_to_server_script>');
return;
}
const mcpClient = new MCPClient();
try {
await mcpClient.connectToServer(process.argv[2]);
await mcpClient.connectToServer(serverScriptPath);

// Check if we have a valid API key to continue
const apiKey = process.env.ANTHROPIC_API_KEY;
Expand Down
12 changes: 4 additions & 8 deletions examples/client-quickstart/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
{
"extends": "@modelcontextprotocol/tsconfig",
"compilerOptions": {
"target": "ES2023",
"lib": ["ES2023"],
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": false,
"declarationMap": false,
"types": ["node"],
"paths": {
"@modelcontextprotocol/client": ["./node_modules/@modelcontextprotocol/client/src/index.ts"],
"@modelcontextprotocol/client/stdio": ["./node_modules/@modelcontextprotocol/client/src/stdio.ts"],
Expand Down
5 changes: 1 addition & 4 deletions examples/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@
"prepack": "pnpm run build:esm && pnpm run build:cjs",
"lint": "eslint src/ && prettier --ignore-path ../../.prettierignore --check .",
"lint:fix": "eslint src/ --fix && prettier --ignore-path ../../.prettierignore --write .",
"check": "pnpm run typecheck && pnpm run lint",
"start": "pnpm run server",
"server": "tsx watch --clear-screen=false scripts/cli.ts server",
"client": "tsx scripts/cli.ts client"
"check": "pnpm run typecheck && pnpm run lint"
},
"dependencies": {
"@modelcontextprotocol/client": "workspace:^",
Expand Down
2 changes: 1 addition & 1 deletion examples/client/src/elicitationUrlExample.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
} from '@modelcontextprotocol/client';
import open from 'open';

import { InMemoryOAuthClientProvider } from './simpleOAuthClientProvider.js';
import { InMemoryOAuthClientProvider } from './simpleOAuthClientProvider';

// Set up OAuth (required for this example)
const OAUTH_CALLBACK_PORT = 8090; // Use different port than auth server (3001)
Expand Down
2 changes: 1 addition & 1 deletion examples/client/src/simpleOAuthClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { ListToolsRequest, OAuthClientMetadata } from '@modelcontextprotoco
import { Client, StreamableHTTPClientTransport, UnauthorizedError } from '@modelcontextprotocol/client';
import open from 'open';

import { InMemoryOAuthClientProvider } from './simpleOAuthClientProvider.js';
import { InMemoryOAuthClientProvider } from './simpleOAuthClientProvider';

// Configuration
const DEFAULT_SERVER_URL = 'http://localhost:3000/mcp';
Expand Down
1 change: 1 addition & 0 deletions examples/server-quickstart/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"zod": "catalog:runtimeShared"
},
"devDependencies": {
"@modelcontextprotocol/tsconfig": "workspace:^",
"@types/node": "^24.10.1",
"typescript": "catalog:devTools"
}
Expand Down
11 changes: 4 additions & 7 deletions examples/server-quickstart/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
{
"extends": "@modelcontextprotocol/tsconfig",
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": false,
"declarationMap": false,
"types": ["node"],
"paths": {
"@modelcontextprotocol/server": ["./node_modules/@modelcontextprotocol/server/src/index.ts"],
"@modelcontextprotocol/server/stdio": ["./node_modules/@modelcontextprotocol/server/src/stdio.ts"],
Expand Down
5 changes: 1 addition & 4 deletions examples/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@
"prepack": "pnpm run build:esm && pnpm run build:cjs",
"lint": "eslint src/ && prettier --ignore-path ../../.prettierignore --check .",
"lint:fix": "eslint src/ --fix && prettier --ignore-path ../../.prettierignore --write .",
"check": "pnpm run typecheck && pnpm run lint",
"start": "pnpm run server",
"server": "tsx watch --clear-screen=false scripts/cli.ts server",
"client": "tsx scripts/cli.ts client"
"check": "pnpm run typecheck && pnpm run lint"
},
"dependencies": {
"@hono/node-server": "catalog:runtimeServerOnly",
Expand Down
2 changes: 1 addition & 1 deletion examples/server/src/elicitationUrlExample.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import type { Request, Response } from 'express';
import express from 'express';
import * as z from 'zod/v4';

import { InMemoryEventStore } from './inMemoryEventStore.js';
import { InMemoryEventStore } from './inMemoryEventStore';

// Create an MCP server with implementation details
const getServer = () => {
Expand Down
2 changes: 1 addition & 1 deletion examples/server/src/simpleStreamableHttp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import cors from 'cors';
import type { Request, Response } from 'express';
import * as z from 'zod/v4';

import { InMemoryEventStore } from './inMemoryEventStore.js';
import { InMemoryEventStore } from './inMemoryEventStore';

// Check for OAuth flag
const useOAuth = process.argv.includes('--oauth');
Expand Down
2 changes: 1 addition & 1 deletion examples/server/src/ssePollingExample.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { McpServer } from '@modelcontextprotocol/server';
import cors from 'cors';
import type { Request, Response } from 'express';

import { InMemoryEventStore } from './inMemoryEventStore.js';
import { InMemoryEventStore } from './inMemoryEventStore';

// Create a fresh MCP server per client connection to avoid shared state between clients
const getServer = () => {
Expand Down
6 changes: 1 addition & 5 deletions examples/shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@
"lint:fix": "eslint src/ --fix && prettier --ignore-path ../../.prettierignore --write .",
"check": "pnpm run typecheck && pnpm run lint",
"test": "vitest run",
"test:watch": "vitest",
"start": "pnpm run server",
"server": "tsx watch --clear-screen=false scripts/cli.ts server",
"client": "tsx scripts/cli.ts client"
"test:watch": "vitest"
},
"dependencies": {
"@modelcontextprotocol/core": "workspace:^",
Expand All @@ -54,7 +51,6 @@
"eslint-config-prettier": "catalog:devTools",
"eslint-plugin-n": "catalog:devTools",
"prettier": "catalog:devTools",
"tsx": "catalog:devTools",
"typescript": "catalog:devTools",
"typescript-eslint": "catalog:devTools",
"vitest": "catalog:devTools"
Expand Down
4 changes: 2 additions & 2 deletions examples/shared/src/authServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import cors from 'cors';
import type { Request, Response as ExpressResponse, Router } from 'express';
import express from 'express';

import type { DemoAuth } from './auth.js';
import { createDemoAuth, DEMO_USER_CREDENTIALS } from './auth.js';
import type { DemoAuth } from './auth';
import { createDemoAuth, DEMO_USER_CREDENTIALS } from './auth';

export interface SetupAuthServerOptions {
authServerUrl: URL;
Expand Down
8 changes: 4 additions & 4 deletions examples/shared/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Auth configuration
export type { CreateDemoAuthOptions, DemoAuth } from './auth.js';
export { createDemoAuth } from './auth.js';
export type { CreateDemoAuthOptions, DemoAuth } from './auth';
export { createDemoAuth } from './auth';

// Auth server setup + demo token verifier (pass to `requireBearerAuth` from @modelcontextprotocol/express)
export type { SetupAuthServerOptions } from './authServer.js';
export { createProtectedResourceMetadataRouter, demoTokenVerifier, getAuth, setupAuthServer } from './authServer.js';
export type { SetupAuthServerOptions } from './authServer';
export { createProtectedResourceMetadataRouter, demoTokenVerifier, getAuth, setupAuthServer } from './authServer';
4 changes: 2 additions & 2 deletions examples/shared/test/demoInMemoryOAuthProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

import { describe, expect, it } from 'vitest';

import type { CreateDemoAuthOptions } from '../src/auth.js';
import { createDemoAuth } from '../src/auth.js';
import type { CreateDemoAuthOptions } from '../src/auth';
import { createDemoAuth } from '../src/auth';

describe('createDemoAuth', () => {
const validOptions: CreateDemoAuthOptions = {
Expand Down
5 changes: 1 addition & 4 deletions packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,7 @@
"lint:fix": "eslint src/ --fix && prettier --ignore-path ../../.prettierignore --write .",
"check": "pnpm run typecheck && pnpm run lint",
"test": "vitest run",
"test:watch": "vitest",
"server": "tsx watch --clear-screen=false scripts/cli.ts server",
"client": "tsx scripts/cli.ts client"
"test:watch": "vitest"
},
"dependencies": {
"cross-spawn": "catalog:runtimeClientOnly",
Expand Down Expand Up @@ -111,7 +109,6 @@
"eslint-config-prettier": "catalog:devTools",
"eslint-plugin-n": "catalog:devTools",
"prettier": "catalog:devTools",
"tsx": "catalog:devTools",
"typescript": "catalog:devTools",
"typescript-eslint": "catalog:devTools",
"vitest": "catalog:devTools",
Expand Down
4 changes: 2 additions & 2 deletions packages/client/src/client/auth.examples.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

import type { AuthorizationServerMetadata } from '@modelcontextprotocol/core';

import type { OAuthClientProvider } from './auth.js';
import { fetchToken } from './auth.js';
import type { OAuthClientProvider } from './auth';
import { fetchToken } from './auth';

/**
* Base class providing no-op implementations of required OAuthClientProvider methods.
Expand Down
4 changes: 2 additions & 2 deletions packages/client/src/client/authExtensions.examples.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
* @module
*/

import { ClientCredentialsProvider, createPrivateKeyJwtAuth, PrivateKeyJwtProvider } from './authExtensions.js';
import { StreamableHTTPClientTransport } from './streamableHttp.js';
import { ClientCredentialsProvider, createPrivateKeyJwtAuth, PrivateKeyJwtProvider } from './authExtensions';
import { StreamableHTTPClientTransport } from './streamableHttp';

/**
* Example: Creating a private key JWT authentication function.
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/client/authExtensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import type { FetchLike, OAuthClientInformation, OAuthClientMetadata, OAuthTokens } from '@modelcontextprotocol/core';
import type { CryptoKey, JWK } from 'jose';

import type { AddClientAuthentication, OAuthClientProvider } from './auth.js';
import type { AddClientAuthentication, OAuthClientProvider } from './auth';

/**
* Helper to produce a `private_key_jwt` client authentication function.
Expand Down
8 changes: 4 additions & 4 deletions packages/client/src/client/client.examples.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@

import type { Prompt, Resource, Tool } from '@modelcontextprotocol/core';

import { Client } from './client.js';
import { SSEClientTransport } from './sse.js';
import { StdioClientTransport } from './stdio.js';
import { StreamableHTTPClientTransport } from './streamableHttp.js';
import { Client } from './client';
import { SSEClientTransport } from './sse';
import { StdioClientTransport } from './stdio';
import { StreamableHTTPClientTransport } from './streamableHttp';

/**
* Example: Using listChanged to automatically track tool and prompt updates.
Expand Down
4 changes: 2 additions & 2 deletions packages/client/src/client/crossAppAccess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
import type { FetchLike } from '@modelcontextprotocol/core';
import { IdJagTokenExchangeResponseSchema, OAuthErrorResponseSchema, OAuthTokensSchema } from '@modelcontextprotocol/core';

import type { ClientAuthMethod } from './auth.js';
import { applyClientAuthentication, discoverAuthorizationServerMetadata } from './auth.js';
import type { ClientAuthMethod } from './auth';
import { applyClientAuthentication, discoverAuthorizationServerMetadata } from './auth';

/**
* Options for requesting a JWT Authorization Grant via RFC 8693 Token Exchange.
Expand Down
4 changes: 2 additions & 2 deletions packages/client/src/client/middleware.examples.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
* @module
*/

import type { Middleware } from './middleware.js';
import { applyMiddlewares, createMiddleware } from './middleware.js';
import type { Middleware } from './middleware';
import { applyMiddlewares, createMiddleware } from './middleware';

// Stubs for hypothetical application middleware
declare function withOAuth(provider: unknown, url: string): Middleware;
Expand Down
4 changes: 2 additions & 2 deletions packages/client/src/client/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { FetchLike } from '@modelcontextprotocol/core';

import type { OAuthClientProvider } from './auth.js';
import { auth, extractWWWAuthenticateParams, UnauthorizedError } from './auth.js';
import type { OAuthClientProvider } from './auth';
import { auth, extractWWWAuthenticateParams, UnauthorizedError } from './auth';

/**
* Middleware function that wraps and enhances fetch functionality.
Expand Down
4 changes: 2 additions & 2 deletions packages/client/src/client/sse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
import type { ErrorEvent, EventSourceInit } from 'eventsource';
import { EventSource } from 'eventsource';

import type { AuthProvider, OAuthClientProvider } from './auth.js';
import { adaptOAuthProvider, auth, extractWWWAuthenticateParams, isOAuthClientProvider, UnauthorizedError } from './auth.js';
import type { AuthProvider, OAuthClientProvider } from './auth';
import { adaptOAuthProvider, auth, extractWWWAuthenticateParams, isOAuthClientProvider, UnauthorizedError } from './auth';

export class SseError extends Error {
constructor(
Expand Down
Loading
Loading