Thanks to visit codestin.com
Credit goes to github.com

Skip to content

charl-kruger/ts-mcp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🦑 ts-mcp 🦑

GitHub last commit npm GitHub License

A lightweight TypeScript-first toolkit for connecting web apps to any Model Context Protocol (MCP) server.

  • useMcp React hook – drop-in for React / Next.js
  • Framework-agnostic core (BrowserOAuthClientProvider, onMcpAuthorization)
  • Handles OAuth 2 PKCE in the browser (popup & fallback)
  • Transparent HTTP ⇢ SSE transport fallback with auto-reconnect
  • Tiny, tree-shakable & 100 % typed (ES modules + .d.ts)

Try it out: MCP Inspector · Workers AI Playground


Installation

npm i ts-mcp            # pnpm add ts-mcp / yarn add ts-mcp

Peer-dependencies (only if you use them):

npm i react react-dom                # for the React hook (web)
npm i react-native @react-native-async-storage/async-storage   # for React Native
npm i @angular/core                  # for the Angular service example

✨ Features

🔄 Automatic connection lifecycle with retry & reconnect
🔐 Full OAuth PKCE flow (popup + manual fallback URL)
🌐 Dual transport – streaming HTTP or SSE (auto-detect)
🪝 Simple React / React Native hook API (useMcp)
🧩 Works in Angular, Vue, vanilla TS – export is just TypeScript
📝 Built-in rolling log for easy debugging

Quick Start (React)

import { useMcp } from "ts-mcp/react";

export default function Chat() {
  const { state, tools, error, callTool, retry, authenticate, clearStorage } =
    useMcp({
      url: "https://my-mcp.example.com/sse",
      clientName: "My React App",
      autoReconnect: true,
      debug: process.env.NODE_ENV === "development",
    });

  if (state === "failed") {
    return (
      <div>
        <p>Connection failed: {error}</p>
        <button onClick={retry}>Retry</button>
        <button onClick={authenticate}>Auth Popup</button>
      </div>
    );
  }

  if (state !== "ready") return <p>Connecting…</p>;

  const search = () => callTool("search", { query: "hello" });

  return (
    <>
      <p>{tools.length} tool(s) online</p>
      <button onClick={search}>Search</button>
    </>
  );
}

Quick Start (React Native)

import React from "react";
import { View, Text, Button } from "react-native";
import { useMcp, AsyncStorageOAuthClientProvider } from "ts-mcp/react-native";

export default function App() {
  const provider = React.useMemo(
    () => new AsyncStorageOAuthClientProvider("https://my-mcp.example.com"),
    []
  );

  const { state, tools, authUrl, authenticate } = useMcp({
    url: "https://my-mcp.example.com/sse",
    provider,
    debug: __DEV__,
  });

  if (authUrl) {
    // You can open the authUrl with `Linking.openURL(authUrl)`
  }

  return (
    <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
      <Text>{state}</Text>
      <Text>{tools.length} tools</Text>
      {state === "failed" && <Button title="Retry" onPress={authenticate} />}
    </View>
  );
}

Quick Start (Angular ≥ 17)

// Prefer the ready-made service shipped by the library:
import { McpService } from 'ts-mcp/angular';

// Add it to your component / constructor as usual
constructor(private readonly mcp: McpService) {}

async ngOnInit() {
  await this.mcp.init();
  const tools = await this.mcp.listTools();
}

Want a custom wrapper? The original service implementation is still available here — copy & modify at will.


Setting up the OAuth callback

React Router

import { useEffect } from "react";
import { onMcpAuthorization } from "ts-mcp";

export default function OAuthCallback() {
  useEffect(() => {
    onMcpAuthorization(
      new BrowserOAuthClientProvider("https://my-mcp.example.com")
    );
  }, []);
  return <p>Authenticating… You can close this window.</p>;
}

Angular Router

import { Component, OnInit } from "@angular/core";
import { onMcpAuthorization } from "ts-mcp";

@Component({ selector: "app-mcp-callback", template: "<p>Authenticating…</p>" })
export class McpCallbackComponent implements OnInit {
  ngOnInit() {
    onMcpAuthorization(
      new BrowserOAuthClientProvider("https://my-mcp.example.com")
    );
  }
}

Add a route for /oauth/callback that points to this component.


API Reference (summary)

useMcp(options)UseMcpResult

UseMcpOptions (selected):

Name Type Default Description
url string Required – MCP SSE/HTTP endpoint
clientName string "MCP React Client" Friendly name in OAuth registration
autoRetry boolean | number false Retry initial connection after failure (ms)
autoReconnect boolean | number 3000 Reconnect after disconnect (ms)
debug boolean false Verbose console & in-hook log

UseMcpResult (selected):

Property Type Notes
state 'discovering' | 'authenticating' | 'connecting' | 'loading' | 'ready' | 'failed' Full lifecycle
tools Tool[] Populated once state === 'ready'
callTool (name, args?) ⇒ Promise<any> JSON-RPC
retry() () ⇒ void Manual reconnect when failed
authenticate() () ⇒ Promise<void> Opens/forces OAuth popup
clearStorage() () ⇒ void Wipes tokens, client info, state

Framework-agnostic helpers

Export Use case
BrowserOAuthClientProvider Drop-in OAuth provider for any front-end. Stores tokens in localStorage.
onMcpAuthorization() Run on your /oauth/callback page to complete PKCE exchange & notify opener.

License

MIT © The MCP community

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published