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

@solvapay/mcp-core

v0.2.3

Published

Framework-neutral MCP contracts for the SolvaPay SDK (tool names, descriptors, payable handler, paywall meta, CSP, bootstrap payload, OAuth discovery JSON builders, bearer/JWT helpers).

Readme

@solvapay/mcp-core

Framework-neutral MCP (Model Context Protocol) contracts for the SolvaPay SDK.

This package owns the shapes that cross the SolvaPay server ↔ client ↔ adapter boundary: tool names, descriptor builder (for SolvaPay intent tools, which advertise _meta.ui.resourceUri on tools/list per SEP-1865; merchant payable tools do NOT), the BootstrapPayload shape carried on structuredContent, Stripe CSP baseline, pure OAuth discovery JSON builders, and JWT bearer helpers.

It does not depend on @modelcontextprotocol/sdk, @modelcontextprotocol/ext-apps, or any runtime-specific HTTP plumbing. The official @modelcontextprotocol/* adapter lives in @solvapay/mcp; Node (req, res, next) OAuth middleware ships as the @solvapay/mcp/express subpath export; fetch-first OAuth + the turnkey handler ships as the @solvapay/mcp/fetch subpath export.

Install

pnpm add @solvapay/mcp-core @solvapay/server

What's in the box

| Export | Use when | | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | MCP_TOOL_NAMES, McpToolName | You're implementing a SolvaPay MCP transport tool on any framework and need the canonical tool names | | buildSolvaPayDescriptors(opts) | You're writing an MCP adapter (fastmcp, raw JSON-RPC) and want the full SolvaPay tool surface as descriptor objects | | buildPayableHandler(solvaPay, ctx, handler) | You're hand-rolling a paywall-protected tool and want the pre-check paywall to return a clean text-only narration on content[0].text + the gate on structuredContent | | paywallToolResult(errOrGate) | You have a PaywallError (legacy try/catch) or a PaywallStructuredContent gate from paywall.decide() and want a text-only tool result | | SOLVAPAY_DEFAULT_CSP, mergeCsp(overrides, apiBaseUrl?) | You're registering the SolvaPay UI resource and want the Stripe allow-list baked in. Pass apiBaseUrl to auto-include the configured SolvaPay API origin in resourceDomains + connectDomains so merchant branding images render without a hand-extended csp. | | getOAuthAuthorizationServerResponse(opts), getOAuthProtectedResourceResponse(url) | You're serving the .well-known/* discovery JSON from any runtime | | buildAuthInfoFromBearer(header, opts) | You're plugging a raw Authorization: Bearer … header into an MCP authInfo envelope | | McpBearerAuthError, extractBearerToken, decodeJwtPayload, getCustomerRefFromJwtPayload, getCustomerRefFromBearerAuthHeader | Low-level JWT bearer parsing — no signature verification (validate upstream first) |

How paywalls work

Paywall responses from buildPayableHandler / paywallToolResult are text-only. content[0].text carries a human narration that names the recovery intent tool (upgrade / topup / activate_plan) and inlines gate.checkoutUrl for terminal-first hosts. isError is always false — a gate is a user-actionable signal, not a tool failure. structuredContent = gate is still emitted for programmatic consumers.

The widget iframe is reserved for the three deliberate intent tools (upgrade / manage_account / topup), which advertise _meta.ui.resourceUri on their descriptors. Merchant payable tools don't, so hosts don't open an uninvited iframe on a successful data call or on a paywall — the LLM narrates the recovery and calls the intent tool, which mounts the widget.

Typical usage

If you're starting a new SolvaPay MCP server on the official @modelcontextprotocol/sdk, don't use this package directly — use @solvapay/mcp, which wraps it with one-call ergonomics.

If you need HTTP-level OAuth handlers, pair this package with either @solvapay/mcp/express (Node) or @solvapay/mcp/fetch (Deno / Supabase Edge / Cloudflare Workers / Bun / Next edge).

If you're writing a new adapter (fastmcp, custom JSON-RPC):

import { buildSolvaPayDescriptors } from '@solvapay/mcp-core'

const { tools, resource } = buildSolvaPayDescriptors({
  solvaPay,
  productRef: 'prd_video',
  resourceUri: 'ui://my-app/mcp-app.html',
  readHtml: async () => readFileSync('./dist/mcp-app.html', 'utf-8'),
  publicBaseUrl: 'https://my-app.example.com',
})

for (const tool of tools) {
  myAdapter.registerTool(tool.name, tool)
}
myAdapter.registerResource(resource)

Peer dependencies

| Peer | Why | Optional? | | ------------------ | -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | | @solvapay/server | Runtime *Core helpers + SolvaPay, PaywallError, PaywallStructuredContent types | Yes — only consumed by buildSolvaPayDescriptors, buildPayableHandler, paywallToolResult | | zod | Descriptor inputSchema shape | Yes — descriptor consumers decide whether to use zod |

See also