npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mcp-ts/client

v4.2.7

Published

A lightweight MCP client library for TypeScript with durable sessions across Redis, Supabase, Neon, and SQLite, cross-runtime agent support, and dynamic tool discovery to reduce LLM context usage.

Readme

@mcp-ts/client

High-performance Model Context Protocol (MCP) SDK for TypeScript and Node.js with OAuth 2.1 lifecycle management, multi-tenant durable sessions across Redis, SQLite, Neon, and Supabase, dynamic context-window optimization via ToolRouter, and first-class AI framework adapters.

npm install @mcp-ts/client @modelcontextprotocol/client @modelcontextprotocol/core

🏗️ Architecture & Core Concepts

graph LR
    subgraph Direct["Direct SDK Flow (TypeScript)"]
        UI["Browser UI"]
        Hook["useMcp Hook"]
        API["Next.js /api/mcp"]
        Mgr["McpManager"]
        Store[("Redis / SQLite / File / Memory")]
        MCP["MCP Servers"]

        UI <--> Hook
        Hook -- "HTTP RPC" --> API
        API --> Mgr
        Mgr -- "SSE events" --> Hook
        Mgr <--> Store
        Mgr <--> MCP
    end
┌────────────────────────────────────────────────────────┐
│                          mcp                           │  App / Storage root
│         (Configures durable storage & tenants)         │
└───────────────────────────┬────────────────────────────┘
                            │ .user(userId)
┌───────────────────────────▼────────────────────────────┐
│                        McpUser                         │  User / Tenant context
│  (addMcpServer, listMcpServers, finishAuth, listTools) │
└─────────────┬───────────────────────────┬──────────────┘
              │                           │
┌─────────────▼───────────────┐ ┌─────────▼──────────────┐
│         McpManager          │ │       ToolRouter       │
│  (Connection pool & cache)  │ │ (Context optimization) │
└─────────────┬───────────────┘ └─────────┬──────────────┘
              │                           │
┌─────────────▼───────────────┐ ┌─────────▼──────────────┐
│          McpClient          │ │      AI Adapters       │
│   (OAuth 2.1, SSE/HTTP)     │ │ (AI SDK, LangChain...) │
└─────────────────────────────┘ └────────────────────────┘

| Class / Module | Purpose | Primary Use Case | | :--- | :--- | :--- | | mcp / Mcp | App & Storage Root | Zero-config instance or app-wide database configuration | | McpUser | User Context | Adding/listing MCP servers and running tools per user | | McpClient | Single Connection | Direct connection to a single remote MCP server | | McpManager | Connection Pool | High-throughput batch connection management | | ToolRouter | Dynamic Optimization | 80–95% token savings using smart tool discovery | | AIAdapter | Framework Bindings | Turn MCP servers into tools for Vercel AI SDK, LangChain, etc. |


🚀 Quick Start

1. Server-Side (Next.js App Router)

Expose a full MCP endpoint with authentication in your Next.js application:

// app/api/mcp/route.ts
import { createNextMcpHandler } from '@mcp-ts/client';

export const dynamic = 'force-dynamic';
export const runtime = 'nodejs';

export const { GET, POST } = createNextMcpHandler({
  authenticate: async (req) => {
    // Return user auth context / user ID
    return { userId: 'user-123' };
  }
});

2. Client-Side (React Hook)

Connect and manage MCP servers directly from your React UI:

'use client';

import { useMcp } from '@mcp-ts/client/react';

export function McpControlPanel() {
  const { connections, connect } = useMcp({
    url: '/api/mcp',
    userId: 'user-123',
  });

  return (
    <div className="flex flex-col items-center gap-4">
      <button
        onClick={() =>
          connect({
            serverId: 'my-server',
            serverName: 'My MCP Server',
            serverUrl: 'https://mcp.example.com',
            callbackUrl: `${window.location.origin}/callback`,
          })
        }
      >
        Connect Server
      </button>

      {connections.map((conn) => (
        <div key={conn.sessionId} className="p-4 border rounded">
          <h3>{conn.serverName}</h3>
          <p>State: {conn.state}</p>
          <p>Tools: {conn.tools.length}</p>
        </div>
      ))}
    </div>
  );
}

3. Programmatic User-Scoped Management

import { mcp } from '@mcp-ts/client';

const user = mcp.user('user_123');

// Connect an MCP server (supports SSE & Streamable HTTP)
const result = await user.addMcpServer('https://mcp.tavily.com/mcp');

if (result.authRequired) {
  // Server requires OAuth 2.1 browser sign-in
  console.log('Redirect user to:', result.authUrl);
} else {
  console.log('Server connected! Session ID:', result.sessionId);
}

// In your OAuth callback route:
await user.finishAuth(code, state, iss);

// List all active user tools across connected servers
const { tools } = await user.listTools();

// Execute a tool directly
const response = await user.callTool('tavily_search', { query: 'Model Context Protocol' });

OAuth client registration and CIMD

When an MCP server requires OAuth, the client chooses a registration method in this order:

  1. Supplied client information, when clientInformation is already configured.
  2. Client ID Metadata Documents (CIMD), when clientMetadataUrl is configured and the authorization server advertises client_id_metadata_document_supported: true.
  3. Dynamic Client Registration (DCR), as a fallback when CIMD is unavailable or unsupported.

Configure CIMD with a stable HTTPS URL for the metadata document:

const client = new MCPClient({
  userId: 'user_123',
  sessionId: 'session_123',
  serverUrl: 'https://mcp.example.com/mcp',
  serverId: 'example',
  callbackUrl: 'https://app.example.com/oauth/callback',
  clientMetadataUrl: 'https://app.example.com/oauth/client-metadata.json',
});

The host application must serve that URL over HTTPS. The document must be valid JSON and include at least client_id, client_name, and redirect_uris. Its client_id must match the metadata URL exactly, including scheme, host, path, and any other URL components. The configured callbackUrl must be included in redirect_uris and remain identical throughout the authorization and callback flow.

For example, a framework-neutral GET route can return the document as JSON:

GET /oauth/client-metadata.json
Content-Type: application/json

{
  "client_id": "https://app.example.com/oauth/client-metadata.json",
  "client_name": "Example MCP Client",
  "redirect_uris": ["https://app.example.com/oauth/callback"],
  "token_endpoint_auth_method": "none"
}

The authorization server decides whether CIMD is available from its OAuth metadata. When it does not advertise support, mcp-ts falls back to DCR if the server provides a registration endpoint.


🔌 Framework Adapters

Integrating with agent frameworks is simple using built-in adapters.

Vercel AI SDK

Pass all user MCP servers seamlessly to generateText or streamText:

// app/api/chat/route.ts
import { mcp } from '@mcp-ts/client';
import { AIAdapter } from '@mcp-ts/client/adapters/ai';
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';

export async function POST(req: Request) {
  const { messages, userId } = await req.json();
  const user = mcp.user(userId);

  const tools = await AIAdapter.getTools(user);

  const result = streamText({
    model: openai('gpt-4o'),
    messages,
    tools,
  });

  return result.toDataStreamResponse();
}

AG-UI Adapter

import { McpManager } from '@mcp-ts/client';
import { AguiAdapter } from '@mcp-ts/client/adapters/agui-adapter';

const client = new McpManager('user_123');
await client.connect();

const adapter = new AguiAdapter(client);
const tools = await adapter.getTools();

Mastra Adapter

import { McpManager } from '@mcp-ts/client';
import { MastraAdapter } from '@mcp-ts/client/adapters/mastra-adapter';

const client = new McpManager('user_123');
await client.connect();

const tools = await MastraAdapter.getTools(client);

LangChain Adapter

import { mcp } from '@mcp-ts/client';
import { LangChainAdapter } from '@mcp-ts/client/adapters/langchain';

const user = mcp.user('user_123');
const tools = await LangChainAdapter.getTools(user);

🧩 AG-UI Middleware

Execute MCP tools server-side when using remote agent frameworks (LangGraph, AutoGen, CrewAI, etc.):

import { HttpAgent } from '@ag-ui/client';
import { McpManager } from '@mcp-ts/client';
import { AguiAdapter } from '@mcp-ts/client/adapters/agui-adapter';
import { createMcpMiddleware } from '@mcp-ts/client/adapters/agui-middleware';

// 1. Connect to MCP servers
const client = new McpManager('user_123');
await client.connect();

// 2. Extract tools
const adapter = new AguiAdapter(client);
const mcpTools = await adapter.getTools();

// 3. Attach middleware to remote agent
const agent = new HttpAgent({ url: 'http://localhost:8000/agent' });
agent.use(
  createMcpMiddleware({
    toolPrefix: 'server-',
    tools: mcpTools,
  })
);

The middleware intercepts tool calls from remote agents, executes MCP tools server-side, and returns results back to the agent.


🛠️ MCP Apps Extension (SEP-1865)

Render interactive UIs for your tools using McpAppRenderer:

import { useRenderToolCall } from '@copilotkit/react-core';
import { McpAppRenderer } from '@mcp-ts/client/react';
import { useMcpContext } from './mcp';

export function ToolRenderer() {
  const { mcpClient } = useMcpContext();

  useRenderToolCall({
    name: '*',
    render: ({ name, args, result, status }) => (
      <McpAppRenderer
        client={mcpClient}
        name={name}
        input={args}
        result={result}
        status={status}
      />
    ),
  });

  return null;
}

🧠 Dynamic Tool Routing (ToolRouter)

For users with dozens or hundreds of tools, ToolRouter dynamically injects discovery meta-tools (mcp_search_tools, mcp_execute_tool) into the LLM context, reducing token usage by up to 95%:

import { mcp, ToolRouter } from '@mcp-ts/client';
import { AIAdapter } from '@mcp-ts/client/adapters/ai-adapter';

const user = mcp.user('user_123');

// 1. Dynamic discovery via ToolRouter (BM25 search + pinned tools):
const router = new ToolRouter(user, {
  pinnedTools: ['slack_send_message'],
});

const tools = await AIAdapter.getTools(user, {
  toolRouter: router,
});

// 2. OR zero-token dynamic context via AI SDK v7 deferLoading:
const deferredTools = await AIAdapter.getTools(user, {
  deferLoading: true,
});

⚙️ Storage Backends & Environment Setup

The library supports multiple durable storage backends out of the box. You can explicitly select one via MCP_TS_STORAGE_TYPE or specify it programmatically.

Supported Types: redis, sqlite, neon, supabase, file, memory.

Programmatic Configuration

import { Mcp, sessions } from '@mcp-ts/client';

// Redis storage
const mcp = new Mcp({
  storage: sessions.use('redis', {
    redisUrl: process.env.REDIS_URL,
  }),
});

const user = mcp.user('user_123');

Environment Variable Setup

  1. Redis (Recommended for production):

    MCP_TS_STORAGE_TYPE=redis
    REDIS_URL=redis://localhost:6379
  2. SQLite (Fast & Persistent):

    MCP_TS_STORAGE_TYPE=sqlite
    MCP_TS_STORAGE_SQLITE_PATH=./sessions.db
  3. Neon (Serverless Postgres):

    MCP_TS_STORAGE_TYPE=neon
    NEON_DATABASE_URL=postgresql://user:[email protected]/dbname?sslmode=verify-full&channel_binding=require
  4. File System (Great for local dev):

    MCP_TS_STORAGE_TYPE=file
    MCP_TS_STORAGE_FILE=./sessions.json
  5. In-Memory (Default for testing):

    MCP_TS_STORAGE_TYPE=memory

📦 Peer Dependencies & Package Exports

[!NOTE] Adapters and external storage backends are loaded via optional peer dependencies and must be installed independently. This ensures your application only includes the integrations you explicitly choose, keeping bundle sizes small.

Entry Points

| Entry Point | Description | | :--- | :--- | | @mcp-ts/client | Root exports: mcp, Mcp, McpUser, McpClient, McpManager, ToolRouter | | @mcp-ts/client/adapters/ai | Vercel AI SDK integration (AIAdapter.getTools) | | @mcp-ts/client/adapters/langchain | LangChain / LangGraph tool binding (LangChainAdapter.getTools) | | @mcp-ts/client/adapters/mastra | Mastra agent framework adapter (MastraAdapter.getTools) | | @mcp-ts/client/adapters/agui-adapter | AG-UI Client adapter | | @mcp-ts/client/adapters/agui-middleware | AG-UI chat & streaming middleware | | @mcp-ts/client/sse | Browser JSON-RPC client primitives | | @mcp-ts/client/react | React hooks (useMcp, useMcpApps, useMcpOAuthPopup, McpAppRenderer) | | @mcp-ts/client/vue | Vue composables (useMcp) | | @mcp-ts/client/shared | Shared types, interfaces (BaseClient, ToolClient), and event emitters |


📚 Documentation Links


🤝 Contributing & License