Labsco
QuantGeekDev logo

MCP Framework

β˜… 923

from QuantGeekDev

A TypeScript framework for building Model Context Protocol (MCP) servers.

πŸ”₯πŸ”₯πŸ”₯πŸ”₯βœ“ VerifiedFreeAdvanced setup

MCP Framework

MCP-Framework is a framework for building Model Context Protocol (MCP) servers elegantly in TypeScript.

MCP-Framework gives you architecture out of the box, with automatic directory-based discovery for tools, resources, and prompts. Use our powerful MCP abstractions to define tools, resources, or prompts in an elegant way. Our cli makes getting started with your own MCP server a breeze

Features

  • πŸ› οΈ Automatic discovery and loading of tools, resources, and prompts
  • Multiple transport support (stdio, SSE, HTTP Stream)
  • TypeScript-first development with full type safety
  • Built on the official MCP SDK
  • Easy-to-use base classes for tools, prompts, and resources
  • Out of the box authentication for SSE endpoints (OAuth 2.1, JWT, API Key)

Projects Built with MCP Framework

The following projects and services are built using MCP Framework:

A crypto tipping service that enables AI assistants to help users send cryptocurrency tips to content creators directly from their chat interface. The MCP service allows for:

  • Checking wallet types for users
  • Preparing cryptocurrency tips for users/agents to complete Setup instructions for various clients (Cursor, Sage, Claude Desktop) are available in their MCP Server documentation.

Support our work

Tip in Crypto

Read the full docs here

Creating a repository with mcp-framework

Using the CLI (Recommended)

Copy & paste β€” that's it
# Install the framework globally
npm install -g mcp-framework

# Create a new MCP server project
mcp create my-mcp-server

# Navigate to your project
cd my-mcp-server

# Your server is ready to use!

Development Workflow

  1. Create your project:

    Copy & paste β€” that's it
    mcp create my-mcp-server
    cd my-mcp-server
  2. Add tools:

    Copy & paste β€” that's it
    mcp add tool data-fetcher
    mcp add tool data-processor
    mcp add tool report-generator
  3. Define your tool schemas with automatic validation:

    Copy & paste β€” that's it
    // tools/DataFetcher.ts
    import { MCPTool, MCPInput as AddToolInput } from "mcp-framework";

import { z } from "zod";

const AddToolSchema = z.object({ a: z.number().describe("First number to add"), b: z.number().describe("Second number to add"), });

class AddTool extends MCPTool { name = "add"; description = "Add tool description"; schema = AddToolSchema;

async execute(input: AddToolInput<this>) { const result = input.a + input.b; return Result: ${result}; } } export default AddTool;

Copy & paste β€” that's it

4. **Build with automatic validation:**
```bash
npm run build  # Automatically validates schemas and compiles
  1. Optional: Run standalone validation:

    Copy & paste β€” that's it
    mcp validate  # Check all tools independently
  2. Test your server:

    Copy & paste β€” that's it
    node dist/index.js  # Server validates tools on startup
  3. Add to MCP Client (see Claude Desktop example below)

Pro Tips:

  • Use defineSchema() during development for immediate feedback
  • Build process automatically catches missing descriptions
  • Server startup validates all tools before accepting connections
  • Use TypeScript's autocomplete with MCPInput<this> for better DX

Using with Claude Desktop

Local Development

Add this configuration to your Claude Desktop config file:

MacOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%/Claude/claude_desktop_config.json

Copy & paste β€” that's it
{
"mcpServers": {
"${projectName}": {
      "command": "node",
      "args":["/absolute/path/to/${projectName}/dist/index.js"]
}
}
}

After Publishing

Add this configuration to your Claude Desktop config file:

MacOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%/Claude/claude_desktop_config.json

Copy & paste β€” that's it
{
"mcpServers": {
"${projectName}": {
      "command": "npx",
      "args": ["${projectName}"]
}
}
}

Building and Testing

  1. Make changes to your tools
  2. Run npm run build to compile
  3. The server will automatically load your tools on startup

Environment Variables

The framework supports the following environment variables for configuration:

VariableDescriptionDefault
MCP_ENABLE_FILE_LOGGINGEnable logging to files (true/false)false
MCP_LOG_DIRECTORYDirectory where log files will be storedlogs
MCP_DEBUG_CONSOLEDisplay debug level messages in console (true/false)false

Example usage:

Copy & paste β€” that's it
# Enable file logging
MCP_ENABLE_FILE_LOGGING=true node dist/index.js

# Specify a custom log directory
MCP_ENABLE_FILE_LOGGING=true MCP_LOG_DIRECTORY=my-logs node dist/index.js

# Enable debug messages in console
MCP_DEBUG_CONSOLE=true node dist/index.js

Authentication

MCP Framework provides optional authentication for SSE endpoints. You can choose between JWT, API Key, OAuth 2.1 authentication, or implement your own custom authentication provider.

JWT Authentication

Copy & paste β€” that's it
import { MCPServer, JWTAuthProvider } from "mcp-framework";
import { Algorithm } from "jsonwebtoken";

const server = new MCPServer({
  transport: {
    type: "sse",
    options: {
      auth: {
        provider: new JWTAuthProvider({
          secret: process.env.JWT_SECRET,
          algorithms: ["HS256" as Algorithm], // Optional (default: ["HS256"])
          headerName: "Authorization"         // Optional (default: "Authorization")
        }),
        endpoints: {
          sse: true,      // Protect SSE endpoint (default: false)
          messages: true  // Protect message endpoint (default: true)
        }
      }
    }
  }
});

Clients must include a valid JWT token in the Authorization header:

Copy & paste β€” that's it
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

API Key Authentication

Copy & paste β€” that's it
import { MCPServer, APIKeyAuthProvider } from "mcp-framework";

const server = new MCPServer({
  transport: {
    type: "sse",
    options: {
      auth: {
        provider: new APIKeyAuthProvider({
          keys: [process.env.API_KEY],
          headerName: "X-API-Key" // Optional (default: "X-API-Key")
        })
      }
    }
  }
});

Clients must include a valid API key in the X-API-Key header:

Copy & paste β€” that's it
X-API-Key: your-api-key

OAuth 2.1 Authentication

MCP Framework supports OAuth 2.1 authentication per the MCP specification (2025-06-18), including Protected Resource Metadata (RFC 9728) and proper token validation with JWKS support.

OAuth authentication works with both SSE and HTTP Stream transports and supports two validation strategies:

JWT Validation (Recommended for Performance)

JWT validation fetches public keys from your authorization server's JWKS endpoint and validates tokens locally. This is the fastest option as it doesn't require a round-trip to the auth server for each request.

Copy & paste β€” that's it
import { MCPServer, OAuthAuthProvider } from "mcp-framework";

const server = new MCPServer({
  transport: {
    type: "http-stream",
    options: {
      port: 8080,
      auth: {
        provider: new OAuthAuthProvider({
          authorizationServers: [
            process.env.OAUTH_AUTHORIZATION_SERVER
          ],
          resource: process.env.OAUTH_RESOURCE,
          validation: {
            type: 'jwt',
            jwksUri: process.env.OAUTH_JWKS_URI,
            audience: process.env.OAUTH_AUDIENCE,
            issuer: process.env.OAUTH_ISSUER,
            algorithms: ['RS256', 'ES256'] // Optional (default: ['RS256', 'ES256'])
          }
        }),
        endpoints: {
          initialize: true,  // Protect session initialization
          messages: true     // Protect MCP messages
        }
      }
    }
  }
});

Environment Variables:

Copy & paste β€” that's it
OAUTH_AUTHORIZATION_SERVER=https://auth.example.com
OAUTH_RESOURCE=https://mcp.example.com
OAUTH_JWKS_URI=https://auth.example.com/.well-known/jwks.json
OAUTH_AUDIENCE=https://mcp.example.com
OAUTH_ISSUER=https://auth.example.com

Token Introspection (Recommended for Centralized Control)

Token introspection validates tokens by calling your authorization server's introspection endpoint. This provides centralized control and is useful when you need real-time token revocation.

Copy & paste β€” that's it
import { MCPServer, OAuthAuthProvider } from "mcp-framework";

const server = new MCPServer({
  transport: {
    type: "sse",
    options: {
      auth: {
        provider: new OAuthAuthProvider({
          authorizationServers: [
            process.env.OAUTH_AUTHORIZATION_SERVER
          ],
          resource: process.env.OAUTH_RESOURCE,
          validation: {
            type: 'introspection',
            audience: process.env.OAUTH_AUDIENCE,
            issuer: process.env.OAUTH_ISSUER,
            introspection: {
              endpoint: process.env.OAUTH_INTROSPECTION_ENDPOINT,
              clientId: process.env.OAUTH_CLIENT_ID,
              clientSecret: process.env.OAUTH_CLIENT_SECRET
            }
          }
        })
      }
    }
  }
});

Environment Variables:

Copy & paste β€” that's it
OAUTH_AUTHORIZATION_SERVER=https://auth.example.com
OAUTH_RESOURCE=https://mcp.example.com
OAUTH_AUDIENCE=https://mcp.example.com
OAUTH_ISSUER=https://auth.example.com
OAUTH_INTROSPECTION_ENDPOINT=https://auth.example.com/oauth/introspect
OAUTH_CLIENT_ID=mcp-server
OAUTH_CLIENT_SECRET=your-client-secret

OAuth Features

  • RFC 9728 Compliance: Automatic Protected Resource Metadata endpoint at /.well-known/oauth-protected-resource
  • RFC 6750 WWW-Authenticate Headers: Proper OAuth error responses with challenge headers
  • JWKS Key Caching: Public keys cached for 15 minutes (configurable)
  • Token Introspection Caching: Introspection results cached for 5 minutes (configurable)
  • Security: Tokens in query strings are automatically rejected
  • Claims Extraction: Access token claims in your tool handlers via AuthResult

Popular OAuth Providers

The OAuth provider works with any RFC-compliant OAuth 2.1 authorization server:

  • Auth0: Use your Auth0 tenant's JWKS URI and issuer
  • Okta: Use your Okta authorization server configuration
  • AWS Cognito: Use your Cognito user pool's JWKS endpoint
  • Azure AD / Entra ID: Use Microsoft Entra ID endpoints
  • Custom: Any OAuth 2.1 compliant authorization server

For detailed setup guides with specific providers, see the OAuth Setup Guide.

Client Usage

Clients must include a valid OAuth access token in the Authorization header:

Copy & paste β€” that's it
# Make a request with OAuth token
curl -X POST http://localhost:8080/mcp \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}'

# Discover OAuth configuration
curl http://localhost:8080/.well-known/oauth-protected-resource

Security Best Practices

  • Always use HTTPS in production - OAuth tokens should never be transmitted over unencrypted connections
  • Validate audience claims - Prevents token reuse across different services
  • Use short-lived tokens - Reduces risk if tokens are compromised
  • Enable token introspection caching - Reduces load on authorization server while maintaining security
  • Monitor token errors - Track failed authentication attempts for security insights

Custom Authentication

You can implement your own authentication provider by implementing the AuthProvider interface:

Copy & paste β€” that's it
import { AuthProvider, AuthResult } from "mcp-framework";
import { IncomingMessage } from "node:http";

class CustomAuthProvider implements AuthProvider {
  async authenticate(req: IncomingMessage): Promise<boolean | AuthResult> {
    // Implement your custom authentication logic
    return true;
  }

  getAuthError() {
    return {
      status: 401,
      message: "Authentication failed"
    };
  }
}

Documentation MCP Servers (@mcpframework/docs)

Spin up an MCP documentation server from any Fumadocs site or any site with llms.txt β€” AI agents get tools to search, browse, and retrieve your docs.

Quick Start (CLI)

Copy & paste β€” that's it
# Scaffold a new docs MCP server project
npx create-docs-mcp my-api-docs
cd my-api-docs

# Configure your docs site URL
cp .env.example .env
# Edit .env β†’ set DOCS_BASE_URL=https://docs.myapi.com

# Build and run
npm run build
npm start

Quick Start (Programmatic)

Copy & paste β€” that's it
import { DocsServer, FumadocsRemoteSource } from "@mcpframework/docs";

const source = new FumadocsRemoteSource({
  baseUrl: "https://docs.myapi.com",
});

const server = new DocsServer({
  source,
  name: "my-api-docs",
  version: "1.0.0",
});

server.start();

Source Adapters

AdapterBest ForSearch
FumadocsRemoteSourceFumadocs sitesNative Orama search with fallback
LlmsTxtSourceAny site with llms.txtLocal text matching
Custom DocSourceAny documentation backendYour implementation

Built-in MCP Tools

ToolDescription
search_docsSearch documentation by keyword or phrase
get_pageRetrieve full markdown content of a page
list_sectionsBrowse the documentation tree structure

Add to Your MCP Client

Copy & paste β€” that's it
# Claude Code
claude mcp add my-api-docs -- node /path/to/my-api-docs/dist/index.js

# Or with environment variable
claude mcp add my-api-docs -e DOCS_BASE_URL=https://docs.myapi.com -- node /path/to/my-api-docs/dist/index.js

For Claude Desktop / Cursor configuration and full documentation, see the @mcpframework/docs README.

License

MIT