@absolutejs/mcp

@absolutejs/mcp

Enables serving a remote Model Context Protocol endpoint by exposing tools, prompts, and resources with customizable authorization and hooks, allowing AI models to interact with your application through a standardized JSON-RPC interface.

Category
Visit Server

README

@absolutejs/mcp

Serve a remote Model Context Protocol endpoint — streamable HTTP, stateless — from a tool/prompt/resource registry. You supply which tools to expose and how to authorize a request into a caller; the package owns the JSON-RPC protocol, protocol-version negotiation, RFC 9728 discovery metadata, and the 401 challenge that lets a client find your authorization server.

Nothing here depends on a model. The tool shape is structurally compatible with @absolutejs/ai's AIToolMap, so an AI tool registry serves over MCP without conversion — but any typed tool registry works.

bun add @absolutejs/mcp

Peer dependency: elysia.

Define an endpoint

import { Elysia } from "elysia";
import { mcpServer, verifyBearer } from "@absolutejs/mcp";
import { verifyJwt } from "@absolutejs/auth"; // or any JWT verifier

type Caller = { userId: string };

const server = new Elysia().use(
  mcpServer<Caller>({
    path: "/mcp",
    issuer: "https://your.app",
    serverInfo: { name: "your-app", title: "Your App", version: "1.0.0" },
    instructions: "What the model should know about this server.",
    scopesSupported: ["openid", "mcp"],
    serveRootMetadata: true,

    // You decide who is allowed in. verifyBearer does the standard OAuth
    // access-token checks; add your own (billing, role, MFA) on top.
    authorize: async (request) => {
      const token = await verifyBearer({
        request,
        issuer: "https://your.app",
        requiredScope: "mcp",
        verify: (jwt) => verifyJwt(jwt, publicJwk),
      });
      if ("error" in token) return { ok: false, reason: token.error };
      return { ok: true, caller: { userId: token.subject } };
    },

    // Called once per request; build the tools for this caller.
    tools: ({ caller }) => buildToolsFor(caller.userId),
  }),
);

That is a complete member endpoint. GET /mcp returns 405, POST /mcp speaks JSON-RPC, and GET /.well-known/oauth-protected-resource[/mcp] serves the discovery metadata.

Guards, prompts, resources

Everything beyond tools is a hook — the package ships no opinion about billing, storage, or auditing.

mcpServer<Caller>({
  // ...as above

  // Refuse a single call before it runs (credits, rate limit). The message
  // comes back as an isError tool result the model can relay — not a crash.
  beforeCall: async ({ caller }) =>
    (await outOfCredits(caller))
      ? { block: "Out of credits this cycle." }
      : undefined,

  // Audit every call. `meta` carries whatever the tool handler wrote.
  onCall: ({ caller, name, ok, meta }) =>
    recordCall({ caller, name, ok, touched: meta.touched }),

  // Server-side prompts: recipes the client shows in its picker.
  prompts: {
    definitions: {
      daily_briefing: { title: "Daily briefing", description: "..." },
    },
    get: async ({ name, args, caller }) => buildPromptText(name, args, caller),
  },

  // Readable resources.
  resources: {
    list: ({ caller }) => listResources(caller),
    read: ({ caller, uri }) => readResource(caller, uri), // string | null
  },
});

The meta scratchpad

Each tools/call gets a fresh meta object shared between tools, beforeCall, and onCall. A tool handler can record what it touched, and your audit hook can read it back:

tools: ({ caller, meta }) =>
  buildAdminTools(caller, (memberId) => { meta.touched = memberId; }),
onCall: ({ meta, name, ok }) =>
  ledger.write({ tool: name, ok, member: meta.touched }),

A second, stricter endpoint

mcpServer is per-endpoint, so an admin console is the same call with a different scope, a stricter authorize (role + MFA + a kill switch, re-checked live), a rate-limit beforeCall, and an audit onCall:

app.use(mcpServer({ path: "/mcp" /* member */ })).use(
  mcpServer({
    path: "/mcp/admin",
    scopesSupported: ["openid", "mcp:admin"] /* stricter */,
  }),
);

Only one endpoint per app should set serveRootMetadata (the un-suffixed alias).

License

Business Source License 1.1 — see LICENSE. Converts to Apache 2.0 on the Change Date.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured