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

romcputils

v0.2.3

Published

Utilities for working with the Model Context Protocol in TypeScript

Readme

ROMCPUtils

A utility package for working with the Model Context Protocol (MCP) in TypeScript/JavaScript applications. This library provides builder patterns for creating MCP tools and resources, along with SDK-compatible transports and a comprehensive testing harness.

Installation

npm install romcputils

Features

  • Tool Adder System: A builder pattern for defining MCP tools with a fluent, chainable API
  • Resource Adder System: A builder pattern for defining MCP resources
  • Testing Harness: A comprehensive testing framework for MCP components with:
    • SDK-Compatible Transport: Direct implementation of the MCP SDK Transport interface for in-process communication
    • Schema Validation: Automatic validation of tool parameters using Zod schemas
    • Configuration Validation: Comprehensive validation of test harness configuration
    • Runtime Context Injection: Override context values at tool invocation time
    • Debug Hooks: Customizable hooks for monitoring tool execution
    • Error Recovery: Built-in retry mechanisms and timeout handling

Quick Start Examples

Creating an MCP Tool

import { createTool } from 'romcputils';
import { z } from 'zod';

// Create a tool using the builder pattern
const myTool = createTool('echo')
  .withDescription('Echo back the input text')
  .withParam('text', z.string(), 'Text to echo')
  .withHandler(async ({ text }) => ({
    content: [{ type: 'text', text: `Echo: ${text}` }]
  }));

// Register with MCP server
myTool.build()((name, schema, handler) => {
  mcpServer.tool(name, schema, handler);
});

Testing an MCP Tool

import { createTool, Testing } from 'romcputils';
import { z } from 'zod';

// Testing components are in the Testing namespace to avoid naming conflicts
const { 
  createMcpTestHarness, 
  createTestHarnessConfig, 
  LogLevel,
  ContextInjectionStrategy 
} = Testing;

// Create test harness with configuration
const config = createTestHarnessConfig('test-server', '1.0.0')
  .withLogLevel(LogLevel.INFO)
  .withDefaultContext({ user: 'test-user' })
  .withContextInjectionStrategy(ContextInjectionStrategy.MERGE)
  .withValidateToolInputs(true) // Enable schema validation
  .build();

const harness = await createMcpTestHarness(config);

// Register the tool BEFORE initialization
harness.registerToolBuilder(myTool);

// Initialize harness
await harness.initialize();

// Call the tool (with automatic schema validation)
const result = await harness.callTool('echo', { text: 'Hello world!' });
console.log(result.content[0].text); // Output: Echo: Hello world!

// Call with runtime context override
const contextResult = await harness.callTool(
  'echo', 
  { text: 'Hello' },
  { user: 'alice' } // Runtime context override
);

// Clean up
await harness.shutdown();

New Features

Schema Validation

Tools automatically validate input parameters against their Zod schemas:

import { createTool } from 'romcputils';
import { z } from 'zod';

const tool = createTool('email-sender')
  .withParam('email', z.string().email(), 'Email address')
  .withParam('subject', z.string().min(1), 'Email subject')
  .withHandler(async ({ email, subject }) => ({
    content: [{ type: 'text', text: `Sent to ${email}: ${subject}` }]
  }));

// This will throw a validation error
await harness.callTool('email-sender', { 
  email: 'invalid-email', 
  subject: '' 
});
// Error: Tool input validation failed for "email-sender":
// - email: Invalid email
// - subject: String must contain at least 1 character(s)

Configuration Validation

Test harness configuration is validated to catch errors early:

import { Testing } from 'romcputils';

const { createTestHarnessConfig } = Testing;

// This will throw a validation error
const config = createTestHarnessConfig('', 'invalid-version')
  .withOperationTimeout(-1000)
  .build();
// Error: Configuration validation failed:
// - name: Server name must not be empty
// - version: Version must be in semver format
// - operationTimeout: Number must be greater than 0

Runtime Context Injection

Override context values when calling tools:

import { createTool } from 'romcputils';
import { z } from 'zod';

const tool = createTool('greeter')
  .withParam('message', z.string())
  .withHandler(async ({ message }, context) => ({
    content: [{
      type: 'text',
      text: `${context?.user}: ${message}`
    }]
  }));

// Default context from configuration
const result1 = await harness.callTool('greeter', { message: 'Hello' });
// Output: "test-user: Hello"

// Runtime context override
const result2 = await harness.callTool(
  'greeter',
  { message: 'Hello' },
  { user: 'alice' }
);
// Output: "alice: Hello"

Documentation

For comprehensive documentation of all features and APIs, please see API_DOCUMENTATION.md.

License

MIT