Jetski MCP Analytics and Authentication Platform

repository·main·Indexed 42 days ago

https://github.com/hyprmcp/jetski

An open-source platform for the Model Context Protocol (MCP) that provides a proxy layer (mcp-gateway) to handle user authentication, generate client setup instructions, and capture deep visibility into tool usage and prompt analytics without requiring changes to underlying MCP server code.

Tokens
17.9K
Snippets
88
Records
93
Agent score
52%

What's inside Jetski

  1. What is Jetski?

    main

    Jetski is an open-source MCP (Model Context Protocol) Analytics and Authentication Platform, part of the HyprMCP ecosystem. It acts as a management layer for MCP servers by deploying instances of mcp-gateway that sit in front of your existing MCP server.

    Key capabilities include:

    • Installation & Setup: Automatically generates step-by-step instructions for supported MCP clients to reduce user churn.
    • Authentication: Provides zero-code user identification and management via a proxy, allowing for personalized tools and responses.
    • Analytics & Visibility: Captures comprehensive prompt analytics (which prompts trigger which tools), real-time debug logs, and usage metrics without requiring changes to your original MCP server code.
  2. How Jetski works: Architecture and Request Flow

    main

    Jetski operates as a proxy layer between MCP Clients (like Claude Desktop or ChatGPT) and your MCP Server.

    The Request Lifecycle:

    1. Client Request: The MCP Client sends a request to the HyprMCP Proxy (the mcp-gateway) instead of directly to your server.
    2. Authentication & Validation: The Proxy authenticates the user and validates their permissions.
    3. Forwarding: The Proxy forwards the request to your unchanged MCP server.
    4. Response & Capture: The Proxy receives the response from your server and automatically captures logs, analytics, and monitoring data.
    5. Visibility: All captured data is sent to the Jetski Platform, where it is visualized in real-time dashboards.
  3. Setup Jetski MCP Gateway Orchestration (Optional)

    main

    If you want to use Kubernetes orchestration for your MCP gateways, use Minikube. This requires the metacontroller to be deployed within your current kubectl context.

    1. Start Minikube using the provided mise command.
    2. Deploy metacontroller using the serve command with the --install-controller flag.
    # Start Minikube
    mise run minikube-start
    
    # Deploy metacontroller
    mise run serve -- --install-controller
  4. Install and run the Jetski Analytics Platform

    main

    To run the Jetski Analytics Platform locally, you need mise, pnpm, and docker installed. This setup includes the backend, frontend, and a local database via Docker Compose.

    1. Clone and prepare the environment:
      • Clone the repository.
      • Use mise to trust and install dependencies.
      • Install node dependencies with pnpm.
      • Set up the environment file from the example.
      • Start the required services via Docker Compose.
    2. Configure host file:
      • Add host.minikube.internal to your /etc/hosts to allow local communication with Minikube.
    3. Run the services:
      • Start the backend in one terminal.
      • Start the frontend in another terminal.
    4. Populate data:
      • Run the generate command to create demo data.
    5. Access the dashboard:
      • Navigate to http://localhost:4200.
      • Default credentials: admin@example.com / password.
    # Clone and setup
    git clone https://github.com/hyprmcp/jetski.git
    cd jetski
    mise trust
    mise install
    pnpm i
    cp .dex.secret.env.example .dex.secret.env
    docker compose up -d
    
    # Configure host
    echo -e "\n127.0.0.1    host.minikube.internal\n" | sudo tee -a /etc/hosts
    
    # Start backend (Terminal 1)
    mise run serve
    
    # Start frontend (Terminal 2)
    pnpm run start
    
    # Generate demo data
    mise run generate
  5. The Organization data model

    main

    An Organization represents a tenant within the system. It extends a Base interface and contains identity information, creation timestamps, and a settings object which is a combination of domain and authentication settings.

    Settings Structure:

    • OrganizationDomainSettings: Includes optional customDomain (string).
    • OrganizationAuthSettings: Includes authorization which contains dcrPublicClient (boolean).
    export interface Organization {
      id: string;
      createdAt: string;
      name: string;
      settings: OrganizationSettings;
    }
    
    export type OrganizationSettings = OrganizationDomainSettings & OrganizationAuthSettings;
  6. Use HlmTable directives in templates

    main

    To apply Shadcn-like styling to a table, use the hlmTable attribute on the <table> element and the corresponding directive attributes on its child elements.

    Each child directive (like hlmTHead, hlmTr, etc.) accepts a class input to allow for additional local styling via userClass.

    <table hlmTable>
      <thead hlmTHead>
        <tr hlmTr>
          <th hlmTh>Header</th>
        </tr>
      </thead>
      <tbody hlmTBody>
        <tr hlmTr>
          <td hlmTd>Data</td>
        </tr>
      </tbody>
    </table>
  7. Configure global HlmTable styling

    main

    You can provide a global configuration for all table components using provideHlmTableConfig. This allows you to override default Shadcn-like styles for all table elements (table, thead, tbody, tfoot, tr, th, td, caption) across your application.

    Pass a Partial<HlmTableVariant> to the provider. Any properties not specified in your config will fall back to the HlmTableVariantDefault values.

    // In your application config or component providers
    providers: [
      provideHlmTableConfig({
        table: 'my-custom-table-class',
        tr: 'custom-row-class'
      })
    ]
  8. Configure the Postgres database service

    main

    The postgres service is used for persistent data storage. It can be configured using the following environment variables:

    • POSTGRES_USER: The database user (default: local).
    • POSTGRES_PASSWORD: The database password (default: local).
    • POSTGRES_DB: The name of the database to create (default: jetski).

    Data is persisted in the postgres volume mapped to /var/lib/postgresql/data/.

    postgres:
        image: "postgres:17.5-alpine3.20"
        environment:
          POSTGRES_USER: local
          POSTGRES_PASSWORD: local
          POSTGRES_DB: jetski
        volumes:
          - "postgres:/var/lib/postgresql/data/"
        ports:
          - "127.0.0.1:5432:5432"
  9. Configure HTTP Client with Auth Interceptors

    main

    The application's HttpClient is configured to use withFetch() and includes a custom authInterceptor to handle authentication headers. It also supports interceptors provided via Dependency Injection (DI).

    provideHttpClient(
      withInterceptors([authInterceptor]),
      withInterceptorsFromDi(),
      withFetch(),
    ),
  10. Configure OAuth2/OIDC Authentication

    main

    The Jetski UI uses angular-oauth2-oidc for authentication. The configuration is initialized via an asynchronous initializeOAuth function that sets up the OAuthService.

    Key configuration parameters include:

    • issuer: The OIDC provider URL (sourced from environment.oidc.issuer).
    • clientId: The client identifier (sourced from environment.oidc.clientId).
    • redirectUri: Set to location.origin to handle callbacks.
    • scope: Defaults to 'openid profile email offline_access'.
    • responseType: Set to 'code' (Authorization Code Flow).
    • showDebugInformation: Enabled when not in production.
    • requireHttps: Set to false (use with caution in production).

    Automatic silent refresh is enabled via oauthService.setupAutomaticSilentRefresh(). The application uses localStorage as the OAuthStorage implementation.

    // OAuth configuration logic used in appConfig
    async function initializeOAuth() {
      const oauthService = inject(OAuthService);
      oauthService.configure({
        issuer: environment.oidc.issuer,
        redirectUri: location.origin,
        clientId: environment.oidc.clientId,
        scope: 'openid profile email offline_access',
        responseType: 'code',
        showDebugInformation: !environment.production,
        clockSkewInSec: 0,
        requireHttps: false,
      });
      oauthService.setupAutomaticSilentRefresh();
      return await oauthService.loadDiscoveryDocumentAndLogin();
    }
  11. Configure Dex via config.yaml

    main

    The dex service uses a config.yaml file to define identity provider settings. Key configuration areas include:

    • issuer: The URL of the Dex issuer (e.g., http://host.minikube.internal:5556).
    • web: Configures the HTTP server, including the http address and allowedOrigins (CORS).
    • grpc: Configures the gRPC server address.
    • storage: Defines the storage backend (e.g., type: sqlite3).
    • oauth2: Settings for OAuth2 flows, such as skipApprovalScreen.
    • staticClients: A list of pre-registered OAuth2 clients. Each client requires an id, name, public status, and redirectURIs.
    • enablePasswordDB: Boolean to enable/disable the password database.
    • staticPasswords: A list of hardcoded user credentials. Each entry requires an email, hash (bcrypt), username, and userID.
    • connectors: External identity providers like github. GitHub connectors require clientID, clientSecret, and a redirectURI.
    • expiry: Defines token lifetimes, such as idTokens (e.g., 5m).
    issuer: http://host.minikube.internal:5556
    web:
      http: 0.0.0.0:5556
      allowedOrigins: ['*']
    grpc:
      addr: 0.0.0.0:5557
    storage:
      type: sqlite3
    oauth2:
      skipApprovalScreen: true
    staticClients:
      - id: ui
        name: 'Jetski Development'
        public: true
        redirectURIs:
        - 'http://localhost:4200'
    connectors:
      - type: github
        id: github
        name: GitHub
        config:
          clientID: {{ .Env.GITHUB_CLIENT_ID }}
          clientSecret: {{ .Env.GITHUB_CLIENT_SECRET }}
          redirectURI: http://localhost:5556/callback
  12. Configure Mailpit for email testing

    main

    The mailpit service provides an SMTP server and a web UI for inspecting outgoing emails during development.

    • SMTP Port: 1025
    • Web UI Port: 8025
    mailpit:
        image: "axllent/mailpit:v1.27.10"
        ports:
          - "1025:1025"
          - "8025:8025"