Skip to main content
@mcp-b/webmcp-types provides TypeScript type definitions for the WebMCP API. Zero runtime. Zero side effects. Install as a dev dependency.
npm install --save-dev @mcp-b/webmcp-types

Activation

TypeScript may not automatically include global declarations from npm packages. Use one of these methods:
{
  "compilerOptions": {
    "types": ["@mcp-b/webmcp-types"]
  }
}
After activation, navigator.modelContext is typed as ModelContext and navigator.modelContextTesting as ModelContextTesting | undefined.

Minimal example


PropertyTypeDescription
navigator.modelContextModelContextStrict core WebMCP surface
navigator.modelContextTestingModelContextTesting | undefinedTesting API (optional)

Core interfaces

ModelContext

Alias for ModelContextCore. This is the type of navigator.modelContext.

ModelContextCore

The strict specification surface.
MethodSignature
registerToolMultiple overloads (see below)
unregisterTool(name: string) => void

ModelContextExtensions

MCP-B extension methods. Not part of the WebMCP specification.
MethodSignature
listTools() => ToolListItem[]
callTool(params: { name: string; arguments?: Record<string, unknown> }) => Promise<ToolResponse>
addEventListener(type: 'toolcall' | 'toolschanged', listener, options?) => void
removeEventListener(type: 'toolcall' | 'toolschanged', listener, options?) => void
dispatchEvent(event: Event) => boolean

ModelContextWithExtensions

Combines ModelContextCore & ModelContextExtensions. Use when you need both strict core and extension methods.
import type { ModelContextWithExtensions } from '@mcp-b/webmcp-types';

const ctx = navigator.modelContext as unknown as ModelContextWithExtensions;
const tools = ctx.listTools();

Tool types

ToolDescriptor<TArgs, TResult, TName>

Explicitly typed tool descriptor.
PropertyTypeRequired
nameTNameYes
descriptionstringYes
inputSchemaInputSchemaNo
outputSchemaInputSchemaNo
annotationsToolAnnotationsNo
streambooleanNo
execute(args: TArgs, client: ModelContextClient) => MaybePromise<ToolExecuteResult<TResult>>Yes

StreamedToolDescriptor<TArgs, TResult, TName>

Like ToolDescriptor but stream is true and execute receives a StreamedToolCall<TArgs>.

ToolListItem<TName>

Tool metadata returned by listTools(). Same shape as ToolDescriptor without execute.

ToolAnnotations

PropertyTypeDescription
titlestring?Display title
readOnlyHintboolean | 'true' | 'false'Read-only indicator
destructiveHintboolean | 'true' | 'false'Destructive action indicator
idempotentHintboolean | 'true' | 'false'Idempotent action indicator
openWorldHintboolean | 'true' | 'false'External system access indicator

CallToolResult / ToolResponse

interface CallToolResult {
  content: Array<ContentBlock | LooseContentBlock>;
  structuredContent?: JsonObject;
  isError?: boolean;
}

type ToolResponse = CallToolResult;

Schema inference

JsonSchemaForInference

The supported JSON Schema subset for type inference. Use with as const satisfies JsonSchemaForInference for best results.
import type { JsonSchemaForInference } from '@mcp-b/webmcp-types';

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

InferArgsFromInputSchema<T>

Derives the argument type from a JSON Schema type.
import type { InferArgsFromInputSchema } from '@mcp-b/webmcp-types';

type Args = InferArgsFromInputSchema<typeof schema>;
// { query: string; limit?: number }

Inference rules

Supported JSON Schema keywords for inference:
KeywordEffect
typeDetermines base TypeScript type
propertiesCreates named fields
requiredMarks fields as non-optional
itemsArray element type
enumUnion of literal values
constSingle literal value
nullableAdds null to the type
additionalPropertiesControls extra key acceptance
Other keywords are accepted as metadata but do not affect inferred types.

additionalProperties behavior

Schema ShapeInferred Extras
additionalProperties: falseNo extra keys
additionalProperties omitted or trueExtra keys as unknown
additionalProperties: { ... } with no named propertiesRecord<string, ...>
additionalProperties: { ... } with named propertiesNamed properties inferred, extras as unknown

Widened schemas

If schema types are widened (e.g., InputSchema loaded at runtime instead of a literal as const), inference falls back to Record<string, unknown>. This is by design for safety.

Output schema inference

ToolResultFromOutputSchema<T>

When outputSchema is a literal object schema, structuredContent is narrowed.
import type { JsonSchemaForInference } from '@mcp-b/webmcp-types';

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

navigator.modelContext.registerTool({
  name: 'search',
  description: 'Search docs',
  inputSchema,
  outputSchema,
  async execute(args) {
    return {
      content: [{ type: 'text', text: 'done' }],
      structuredContent: {
        total: 1,            // required, inferred as number
        items: ['result'],   // optional, inferred as string[]
      },
    };
  },
});

ToolDescriptorFromSchema<TInput, TOutput, TName>

Schema-driven descriptor type. Both execute args and structuredContent are inferred from the schemas.

Typed model context

TypedModelContext<TTools>

Provides name-aware callTool and listTools typing for known tool 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 AppContext = TypedModelContext<readonly [SearchTool, PingTool]>;

declare const ctx: AppContext;

// name is narrowed; arguments are inferred
await ctx.callTool({ name: 'search', arguments: { query: 'webmcp' } });

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

Helper types

TypeDescription
InferToolArgs<T>Extract args type from a tool descriptor
InferToolResult<T>Extract result type from a tool descriptor
ToolName<TTools>Union of tool names from a descriptor array
ToolByName<TTools, TName>Extract a descriptor by name
ToolArgsByName<TTools, TName>Args type by tool name
ToolResultByName<TTools, TName>Result type by tool name
ToolCallParams<TName, TArgs>Typed parameters for callTool

Testing types

ModelContextTesting

MethodSignature
listTools() => ModelContextTestingToolInfo[]
executeToolOverloaded: JSON string or streamed source
registerToolsChangedCallback(callback: () => void) => void
getCrossDocumentScriptToolResult() => Promise<string>

ModelContextTestingToolInfo

PropertyType
namestring
descriptionstring
inputSchemastring? (JSON-serialized)
streamboolean?

Other exports

ExportDescription
InputSchemaJSON Schema interface for tool parameters
ContentBlockDiscriminated union of content types
LooseContentBlockPermissive content block type
MaybePromise<T>T | Promise<T>
ModelContextClientExecute callback client with requestUserInteraction
ToolExecutionContextExtended client with elicitInput
ModelContextInputLegacy options type (kept for backwards compatibility)
ModelContextOptionsAlias for ModelContextInput
ElicitationParamsElicitation request parameters
ElicitationResultElicitation response
ToolCallEventEvent dispatched on tool invocation