npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@askable-ui/mcp

v0.14.0

Published

MCP bridge for exposing Context packets to agents

Downloads

2,326

Readme

@askable-ui/mcp

MCP bridge for exposing structured Context packets to AI agents.

Host applications provide a context provider. The package registers MCP tools that return the current packet, the packet schema, and a prompt-ready text rendering.

import { createAskableContext } from '@askable-ui/core';
import { createAskableMcpContextProvider, createAskableMcpServer } from '@askable-ui/mcp';

const ctx = createAskableContext({ viewport: true });
ctx.observe(document);

const server = createAskableMcpServer({
  provider: createAskableMcpContextProvider(ctx, {
    history: 3,
    includeViewport: true,
    source: { app: 'analytics-dashboard' },
  }),
});

The built-in provider adapts ctx.toContextPacket() and ctx.toContext() to the MCP tools. When available, it uses ctx.toContextPacketAsync() and ctx.toContextAsync() so registered app-owned sources are included in structured packets and prompt renderings. Tool callers can request prompt shaping options such as scope, preset, format, includeText, maxTextLength, maxTokens, history, includeViewport, and sources.

import { createAskableCollectionSource } from '@askable-ui/core';

ctx.registerSource('accounts', createAskableCollectionSource({
  describe: 'Accounts matching active filters',
  getState: () => ({ filters, sort, totalCount }),
  getVisibleItems: () => table.getVisibleRows(),
  getItems: () => accountStore.getAllMatching({ filters, sort }),
  getSummary: ({ maxItems }) => summarizeAccounts({ filters, sort, maxItems }),
  sanitizeItem: redactAccountFields,
}));

const server = createAskableMcpServer({
  provider: createAskableMcpContextProvider(ctx, {
    history: 3,
    includeViewport: true,
    sources: [{ id: 'accounts', mode: 'all', maxItems: 25, timeoutMs: 750 }],
    sourceErrorMode: 'include',
  }),
});

Use createAskableMcpServer() when you want to attach your own MCP transport. For web runtimes, createAskableMcpWebHandler() creates a stateless Streamable HTTP Request -> Response handler.

Web MCP for Claude and ChatGPT

To make Askable context available to user-owned Claude or ChatGPT clients, host the MCP server behind a public HTTPS endpoint such as https://your-app.com/mcp. Keep authentication, rate limits, tenancy checks, and consent handling in the host app.

import { createAskableMcpContextProvider, createAskableMcpWebHandler } from '@askable-ui/mcp';

const handler = createAskableMcpWebHandler({
  authorize: async (request) => {
    const token = await verifyMcpToken(request);
    if (!token) return false;
    return {
      authInfo: {
        token: token.value,
        clientId: token.clientId,
        scopes: token.scopes,
      },
    };
  },
  cors: {
    origin: ['https://app.example'],
    headers: ['Authorization', 'Content-Type', 'MCP-Protocol-Version'],
  },
  maxRequestBodyBytes: 256 * 1024,
  telemetry: (event) => {
    metrics.timing('askable.mcp.duration', event.durationMs, {
      outcome: event.outcome,
      status: event.status,
    });
  },
  provider: createAskableMcpContextProvider(ctx, {
    history: 3,
    includeViewport: true,
    sources: ['accounts'],
  }),
});

export const GET = handler;
export const POST = handler;
export const DELETE = handler;

authorize runs before context is read. Return false for the built-in 401 JSON-RPC response, return a custom Response when the host app owns the error shape, or return MCP request options such as authInfo.

cors handles browser preflight requests before context is read. Web responses also receive Cache-Control: no-store and X-Content-Type-Options: nosniff unless the response already set those headers.

maxRequestBodyBytes rejects oversized MCP requests with a JSON-RPC 413 before authorization, server setup, or MCP body parsing runs. The default is 1 MiB. Pass false to disable the built-in guard when another layer already enforces request limits.

telemetry receives sanitized request metadata such as method, path, status, outcome, duration, origin, user agent, and request ID. It does not include MCP request bodies, Context packets, or prompt text.

Claude clients can connect to the public MCP URL as a remote MCP server. The Anthropic Messages API MCP connector uses an object like:

{
  "type": "url",
  "name": "askable-context",
  "url": "https://your-app.com/mcp"
}

ChatGPT developer mode can create an app from a remote MCP server. OpenAI API calls can also pass the same endpoint as a remote MCP server:

{
  "type": "mcp",
  "server_label": "askable",
  "server_url": "https://your-app.com/mcp"
}

Browser-local MCP bridge

Hosted Web MCP is the server-side path. For local browser workflows, a page cannot expose MCP directly to Claude or ChatGPT by itself. It needs a trusted browser extension or local companion process. createAskableMcpPageBridge() adds the page-side handoff: the page listens for approved bridge requests and returns the current packet, prompt-ready text, or a resource-shaped askable://current payload through window.postMessage(). The extension or companion can then expose that data through its own local MCP server.

import { createAskableMcpContextProvider, createAskableMcpPageBridge } from '@askable-ui/mcp';

const bridge = createAskableMcpPageBridge({
  provider: createAskableMcpContextProvider(ctx, {
    history: 3,
    includeViewport: true,
    sources: ['accounts'],
  }),
  allowedOrigins: [window.location.origin],
  onError: (error) => console.error(error),
});

// Later, when the page no longer wants to expose context:
bridge.dispose();

A trusted extension or local bridge can request context with the versioned message shape:

window.postMessage({
  protocol: 'askable.mcp.page_bridge',
  version: '0.1',
  channel: 'askable:mcp',
  type: 'get_current_context',
  requestId: crypto.randomUUID(),
  options: { sources: ['accounts'], history: 3 },
}, window.location.origin);

Use type: 'format_context_for_prompt' when the bridge needs prompt-ready text instead of the structured packet.

Use type: 'read_current_resource' when the extension or companion wants a resource-shaped response that can map directly to MCP resources/read output:

window.postMessage({
  protocol: 'askable.mcp.page_bridge',
  version: '0.1',
  channel: 'askable:mcp',
  type: 'read_current_resource',
  requestId: crypto.randomUUID(),
  options: {
    sources: ['accounts'],
    resource: {
      uri: 'askable://current',
      format: 'packet',
    },
  },
}, window.location.origin);

Set resource.format to prompt to receive text/plain prompt context at a URI such as askable://current.txt. Keep user consent and installation trust in the extension or companion, and enable the page bridge only when the app wants to participate in local browser MCP workflows.