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

@mcp-b/webmcp-types

v3.0.0

Published

Strict TypeScript type definitions for the WebMCP core API (document.modelContext)

Readme

@mcp-b/webmcp-types

Strict TypeScript type definitions for the WebMCP core API (document.modelContext).

Zero runtime. Zero side effects. Just .d.ts types.

Type Safety First

This package is the type-safety source of truth for WebMCP.

  • Infer tool input args from literal inputSchema
  • Infer structuredContent from literal outputSchema
  • Keep safe fallbacks (Record<string, unknown>) when schemas are widened/runtime-defined
  • Provide name-aware typed registries with TypedModelContext

Why This Package

  • Global Document augmentation for document.modelContext
  • Deprecated global Navigator augmentation for backward-compatible navigator.modelContext
  • Strongly typed tool descriptors and tool responses
  • Literal JSON Schema inference for tool args and structuredContent
  • Name-aware helper types for typed tool registries
  • Runtime-agnostic: works with native implementations, polyfills, or adapters

Package Selection

| Package | Use When | | ------------------------ | ----------------------------------------------------------------------------- | | @mcp-b/webmcp-types | You only need compile-time types | | @mcp-b/webmcp-polyfill | You need strict WebMCP core runtime behavior | | @mcp-b/global | You want core + MCPB bridge extensions (callTool, prompts, resources, etc.) |

Install

pnpm add -D @mcp-b/webmcp-types
# or
npm install --save-dev @mcp-b/webmcp-types

If your published library exposes these types in its public declarations, install as a production dependency instead of a dev dependency.

Activate Global Types

TypeScript may not automatically include global declarations from npm packages. Use one of these:

  1. Add to tsconfig.json:
{
  "compilerOptions": {
    "types": ["@mcp-b/webmcp-types"]
  }
}
  1. Add a triple-slash reference in a global .d.ts file:
/// <reference types="@mcp-b/webmcp-types" />
  1. Add a type-only import:
import type {} from '@mcp-b/webmcp-types';

Quick Start

import type { JsonSchemaForInference } from '@mcp-b/webmcp-types';

const inputSchema = {
  type: 'object',
  properties: {
    query: { type: 'string' },
    limit: { type: 'integer', minimum: 1, maximum: 50 },
  },
  required: ['query'],
  additionalProperties: false,
} as const satisfies JsonSchemaForInference;

const outputSchema = {
  type: 'object',
  properties: {
    total: { type: 'integer' },
    items: { type: 'array', items: { type: 'string' } },
  },
  required: ['total'],
  additionalProperties: false,
} as const satisfies JsonSchemaForInference;

document.modelContext.registerTool({
  name: 'search',
  description: 'Search indexed docs',
  inputSchema,
  outputSchema,
  async execute(args) {
    // args is inferred as: { query: string; limit?: number }
    return {
      content: [{ type: 'text', text: `Searching for ${args.query}` }],
      structuredContent: {
        // inferred from outputSchema
        total: 1,
        items: [args.query],
      },
    };
  },
});

Strict Type Inference Deep Dive

1. Inference works best with literal schemas

Use as const satisfies JsonSchemaForInference so TypeScript preserves literal schema information.

If schema types are widened (for example InputSchema loaded at runtime), inference intentionally falls back to:

Record<string, unknown>;

2. Input inference rules

InferArgsFromInputSchema<T> and schema-driven registerTool(...) inference use a focused subset:

  • type
  • properties
  • required
  • items
  • enum
  • const
  • nullable
  • additionalProperties

Other schema keywords are accepted as metadata but do not add new inferred structure.

3. additionalProperties behavior

| Schema shape | Inferred extras | | ---------------------------------------------------------- | -------------------------------------------------- | | additionalProperties: false | No extra keys | | additionalProperties omitted/true | Extra keys allowed as unknown | | additionalProperties: { ... } with no named properties | Map-like Record<string, ...> | | additionalProperties: { ... } with named properties | Named properties inferred, extras remain unknown |

4. Required keys depend on literal required

If required is widened (for example a runtime string[]), fields are treated as optional by design.

5. Output inference from outputSchema

When outputSchema is a literal object schema, structuredContent is inferred automatically via ToolResultFromOutputSchema.

This catches enum/type mismatches at compile time.

6. Explicit typing is still available

You can always provide explicit generic args/results with ToolDescriptor<TArgs, TResult, TName> when schema inference is not enough for your use case.

Name-Aware Typed Context (Advanced)

TypedModelContext<TTools> gives literal-name-aware callTool(...) typing for known registries.

import type { CallToolResult, ToolDescriptor, TypedModelContext } from '@mcp-b/webmcp-types';

type SearchTool = ToolDescriptor<
  { query: string; limit?: number },
  CallToolResult & { structuredContent: { total: number } },
  'search'
>;

type PingTool = ToolDescriptor<Record<string, never>, CallToolResult, 'ping'>;
type AppModelContext = TypedModelContext<readonly [SearchTool, PingTool]>;

declare const modelContext: AppModelContext;

await modelContext.callTool({
  name: 'search',
  arguments: { query: 'webmcp' },
});

await modelContext.callTool({ name: 'ping' });
// arguments are optional for Record<string, never> tools

Core and Extension Surfaces

Document['modelContext'] is typed as strict core WebMCP methods only. Navigator['modelContext'] remains typed as a deprecated backward-compatible alias.

Extension methods are available via ModelContextExtensions and ModelContextWithExtensions:

import type { ModelContextExtensions } from '@mcp-b/webmcp-types';

const modelContext = document.modelContext as Document['modelContext'] & ModelContextExtensions;
const tools = modelContext.listTools();
const result = await modelContext.callTool({
  name: 'search',
  arguments: { query: 'docs' },
});

void tools;
void result;

Commonly Used Exports

| Export | Purpose | | ------------------------------------ | ------------------------------------------------------------ | | ModelContext | Strict core document.modelContext type | | ToolDescriptor | Explicitly typed tool descriptor | | ToolDescriptorFromSchema | Schema-driven descriptor with inferred args/result | | JsonSchemaForInference | Supported JSON Schema subset for inference | | InferArgsFromInputSchema | Derive args shape from a schema type | | ToolResultFromOutputSchema | Derive structuredContent type from output schema | | TypedModelContext | Name-aware typed callTool/listTools for known registries | | CallToolResult | Tool response type | | ContentBlock / LooseContentBlock | Strict and pragmatic content block typing | | ModelContextClient | Tool execution client (requestUserInteraction) |

Important Notes

  • This package does not install any runtime behavior.
  • Runtime validation/execution behavior depends on your WebMCP runtime package.
  • Prefer document.modelContext for new code. navigator.modelContext is retained as a deprecated backward-compatible alias during the WebMCP migration.
  • provideContext() and clearContext() were removed from the upstream WebMCP spec on March 5, 2026 and are intentionally not typed.
  • unregisterTool(name) is @deprecated. The April 23, 2026 WebMCP draft removed it from the spec in favor of an AbortSignal passed via registerTool(tool, { signal }). The type is retained for compatibility with older native previews and existing MCP-B wrappers; it will be removed in the next major version.
  • registerTool(tool, options?) accepts a ModelContextRegisterToolOptions dictionary with an optional signal: AbortSignal. Aborting the signal unregisters the tool.
  • ToolAnnotations.untrustedContentHint was added to the spec on April 23, 2026 to flag tools whose output may include externally-sourced content.
  • navigator.modelContextTesting is typed as optional for compatibility with Chromium preview/testing surfaces.

License

MIT