xmcp Framework Documentation

repository·main·Indexed 23 days ago

https://github.com/basementstudio/xmcp

A framework for building Model Context Protocol (MCP) servers with support for various authentication providers including Auth0, Clerk, Better Auth, and Descope. Features include plugins for permission enforcement, RBAC, and deployment guides for Cloudflare Workers.

Tokens
108K
Snippets
308
Records
560
Agent score
79%

What's inside xmcp

  1. Overview of xmcp features

    main

    The xmcp framework provides several core features for building Model Context Protocol (MCP) servers:

    • File System Routing: Tools and prompts are automatically registered based on files located in tools and prompts directories.
    • Hot Reloading: Provides instant feedback during development.
    • Middlewares: A toolkit for implementing authentication and custom logic.
    • Extensible Configuration: Allows for customizable server configuration.
    • Deploy Anywhere: Supports flexible deployment, including zero-configuration deployment on Vercel.
  2. Introduction to xmcp

    main
    xmcp is a TypeScript framework designed for building and shipping Model Context Protocol (MCP) servers. It simplifies the development process by automatically handling the registration of tools, prompts, and resources. The framework is designed to reduce friction in setting up, building, and deploying AI tools within the MCP ecosystem.
  3. Understand the xmcp project structure

    main

    xmcp uses a declarative, file-system based architecture. By default, the framework uses auto-discovery to find and register tools, prompts, and resources based on their location within the src/ directory.

    Default Directory Layout

    • src/tools/: Files in this directory are automatically discovered as Tools.
    • src/prompts/: Files in this directory are automatically discovered as Prompts.
    • src/resources/: Files in this directory are automatically discovered as Resources.
    • src/middleware.ts: An optional file used to process HTTP requests and responses.

    If you need to change these default locations, you can configure custom directory paths in your xmcp.config.ts file.

  4. What is an MCP Server Card and how is it generated?

    main

    An MCP Server Card is a JSON file published at /.well-known/mcp/server-card.json that allows agent discovery tools to automatically find and configure connections to your server.

    In xmcp, the card is automatically generated based on the template fields defined in your xmcp.config.ts file. Specifically, it uses the name, description, and icons properties.

    import type { XmcpConfig } from "xmcp";
    
    const config: XmcpConfig = {
      http: true,
      template: {
        name: "My MCP Server",
        description: "Describe what your server does.",
        icons: [{ src: "https://example.com/icon.png", mimeType: "image/png" }],
      },
    };
    
    export default config;
  5. Configure session settings for Stdio servers

    main

    If your server requires user-provided values (like API keys or configuration settings), you can define a session configuration schema.

    For stdio servers, Smithery automatically translates the fields in your JSON schema into command-line arguments using kebab-case format.

    Constraints:

    • Supported types: string, number, and boolean.
    • Maximum of 20 fields allowed.
    {
      "type": "object",
      "properties": {
        "apiKey": {
          "type": "string",
          "title": "API Key"
        },
        "model": {
          "type": "string",
          "title": "Model",
          "default": "gpt-4"
        }
      },
      "required": ["apiKey"]
    }

    Resulting CLI execution:

    your-server --api-key=sk-xxx --model=gpt-4
  6. How tool permission enforcement works

    main

    The Auth0 plugin uses a specific permission naming convention to protect tools.

    1. Public Tools: By default, all tools are public. Any user with a valid Auth0 token can access them.
    2. Protected Tools: A tool is protected if a permission named tool:<name> (where <name> is the tool's metadata.name) is defined in your Auth0 API settings.
    3. Enforcement Logic:
      • The plugin queries the Auth0 Management API using read:resource_servers to check if tool:<name> exists.
      • If it exists, it queries read:users to verify the user has that specific permission assigned.
      • If the permission does not exist in Auth0, the tool is treated as public.
      • If Management API calls fail, access is denied by default.

    To use protected tools, you must enable RBAC and Add Permissions in the Access Token in your Auth0 API settings, then create roles with the appropriate tool:<name> permissions.

  7. Organize resources using Route Groups

    main

    You can use folder names wrapped in parentheses, e.g., (folder), to organize resources into logical groups without affecting the resulting URI. This is useful for separating (public), (private), or (admin) resources.

    Example structure:

    • src/resources/(public)/docs/api.ts $\rightarrow$ docs://api
    • src/resources/(private)/(users)/me/profile.ts $\rightarrow$ users://me/profile
  8. Use structured content for widget-to-tool communication

    main

    To pass complex data from an MCP tool to a rendered widget, return an object containing structuredContent and content.

    • structuredContent: A custom object containing the data your widget needs (e.g., game URLs, titles, or configuration).
    • content: An array of text objects for the chat interface.

    The widget can then access this data using the useToolOutput() hook.

  9. How Resource URIs are composed

    main

    Each resource is uniquely identified by a URI generated from its file path based on specific folder naming conventions:

    • URI Scheme: Detected from folders wrapped in parentheses. A folder named (users) creates the users:// scheme.
    • Static Segments: Standard folder names become literal path segments.
    • Dynamic Parameters: Folders wrapped in brackets [] indicate dynamic parameters in the URI.

    Example Mapping: File path: src/resources/(users)/[userId]/profile.ts
    Resulting URI: users://{userId}/profile

  10. Select a handler type for your widget

    main

    Decide whether to use React (.tsx) or Template Literals based on the complexity of the widget:

    ScenarioHandlerReason
    User interaction needed (buttons, inputs)React (.tsx)State management with hooks
    Display external widget libraryTemplate literalJust load scripts/styles
    Dynamic content from tool paramsReactProps flow naturally
    Static HTML with no stateTemplate literalSimpler, less overhead

    Rule of thumb: If unsure, start with React. Converting from React to template literals later is harder than starting simple.