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

cobasaja

v1.0.0

Published

Deterministic MCP testing framework — just try it. Spawns MCP servers over stdio, runs Pest-like describe/it tests with snapshot support, and keeps you stress-free.

Readme

cobasaja

Just try it — a deterministic MCP testing framework for TypeScript.

cobasaja spawns MCP servers over stdio and runs Pest-like describe/it tests against them. Built for AI-agent tooling where reliability matters.

v1.0.0 What's New

  • toThrowAsync() — test async error handling with error class or message matching
  • Numeric matcherstoBeGreaterThan, toBeLessThan, toBeGreaterThanOrEqual, toBeLessThanOrEqual, toBeCloseTo
  • Smart snapshots — snapshot keys now use test names instead of a hardcoded fallback (multiple snapshots per test work correctly)
  • Cleaner errors — assertion stack traces stripped of cobasaja internals
  • --verbose — detailed per-file test output flag

Install

npm install --save-dev cobasaja

Quick Start

Create a test file and run it:

// tests/my-server.test.ts
import { defineServer, describe, it, expect } from 'cobasaja';

defineServer({
  command: 'node',
  args: ['dist/index.js'],
  timeout: 10000,
});

it('lists expected tools', async ({ tools }) => {
  expect(tools).toHaveTool('my_tool');
  expect(tools.length).toBe(1);
});

describe('my_tool', () => {
  it('returns a successful result', async ({ call }) => {
    const result = await call('my_tool', { foo: 'bar' });
    expect(result).toBeSuccessful();
  });
});
# Run tests
npx cobasaja

Test Runner

cobasaja auto-discovers test files matching **/*.test.ts in the project root. Results are reported with pass/fail counts and timing.

API

defineServer(config)

Configure the MCP server under test. Must be called once before any tests.

| Option | Type | Default | Description | |---|---|---|---| | command | string | — | Server binary/command | | args | string[] | [] | CLI arguments | | timeout | number | 10000 | Per-call timeout (ms) |

describe(name, fn)

Group tests into a named block. Supports nested describe. Runs beforeEach/afterEach hooks scoped to the block, and beforeAll/afterAll hooks scoped to the block.

it(name, fn)

Define a test case. The async callback receives a context object:

({ tools, call }) => {
  // tools — the full listTools() response array
  // call(name, args) — call a tool and return the MCP result
}

expect(value)

Matchers:

| Matcher | Description | |---|---| | .toBe(value) | Strict equality (===) | | .toEqual(value) | Deep equality | | .toContain(value) | String or array containment | | .toMatchObject(obj) | Partial object match | | .toHaveLength(n) | Length check | | .toBeGreaterThan(n) | Numeric: actual > expected | | .toBeGreaterThanOrEqual(n) | Numeric: actual >= expected | | .toBeLessThan(n) | Numeric: actual < expected | | .toBeLessThanOrEqual(n) | Numeric: actual <= expected | | .toBeCloseTo(n, digits?) | Floating-point comparison within precision | | .toBeDefined() | Not undefined | | .toBeUndefined() | undefined | | .toBeNull() | null | | .toBeTruthy() | Truthy | | .toBeFalsy() | Falsy | | .toHaveTool(name) | Tool exists in MCP tools array | | .toBeSuccessful() | MCP result has no error | | .toHaveErrored() | MCP result has error flag |

Assertions on functions:

| Matcher | Description | |---|---| | .toThrow() | Function throws | | .toThrow(ErrorClass) | Throws specific error type | | .toThrowAsync() | Async function rejects | | .toThrowAsync(ErrorClass) | Async function rejects specific error type | | .toThrowAsync(msg) | Async function rejects with matching message |

.not — inverts any matcher: expect(x).not.toBe(y)

beforeAll(fn) / afterAll(fn) / beforeEach(fn) / afterEach(fn)

Lifecycle hooks, scoped to the enclosing describe block.

Snapshots

Use toMatchSnapshot() for golden-file testing. Snapshots are stored in __snapshots__/ alongside the test file and should be committed to version control.

it('produces expected output', async ({ call }) => {
  const result = await call('my_tool', {});
  expect(result).toMatchSnapshot();
});

License

MIT