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

@supershaneski/tool-registry

v0.3.3

Published

Lightweight Tool Registry for LLM Function Calling.

Readme

tool-registry

Lightweight Tool Registry for LLM Function Calling

A minimal, zero-overhead alternative to the full Model Context Protocol (MCP). Perfect when you just need clean tool registration + execution without the complexity of servers, network hops, or heavy protocol layers.


LLM向けの軽量なFunction Calling用ツールレジストリ

Model Context Protocol(MCP) のミニマルな代替実装。サーバーやネットワーク通信、複雑なプロトコルを必要とせず、ツールの登録と実行だけをシンプルに提供します。

Motivation

I created this package while learning about the Model Context Protocol (MCP). After exploring numerous projects that use MCP, I found that some of them don’t actually require the full protocol. In many cases, the core requirement is simply registering tools and executing them in a structured way.

This package is not intended to replace MCP when its features are needed. Instead, it offers a lightweight alternative for projects that only need tool registration and execution, without the added complexity of servers, network communication, and protocol layers that often accompany MCP adoption for simple use cases.

Why This Instead of Full MCP?

  • Much simpler — No extra servers or protocol overhead
  • Faster — Direct in-process function calls
  • Flexible — Easy to use different toolsets per context

Use full MCP when you need true distributed tool discovery across multiple applications.

Features

  • Simple register → execute workflow
  • Optional metadata (categories, tags) during registration for categorization
  • Custom querying capability with findTools(predicate)
  • Sandboxed tool execution by combining metadata queries with execution access control
  • Built-in support for include/exclude tool filtering (great for context-aware agents)
  • Runtime access control (allowed) to prevent unauthorized/hallucinated tool execution
  • Works with Gemini, OpenAI, Anthropic, and other LLM tool-calling APIs
  • Tiny footprint — no dependencies

Installation

npm install @supershaneski/tool-registry

Quick Start

import ToolRegistry from '@supershaneski/tool-registry';

const registry = new ToolRegistry();

// Register tools
registry.register('get_weather', {
  name: 'get_weather',
  description: 'Get current weather for a city',
  parameters: {
    type: 'object',
    properties: { city: { type: 'string' } },
    required: ['city']
  }
}, async (args) => {
  // Your implementation here
  return { temperature: 28, condition: 'sunny' };
});

// Get tool schemas for LLM
const toolSchemas = registry.getTools();
// or with filtering:
const limitedTools = registry.getTools({
  include: ['get_weather', 'search_web']
});

// Execute tool
const toolCall = { name: 'get_weather', args: { city: 'Sapporo' } }; // from LLM
const result = await registry.execute(toolCall.name, toolCall.args);

Examples

For a complete example demonstrating actual LLM integration (e.g., Gemini SDK), check out the examples/gemini-integration.js file.

[!NOTE] You will need actual Gemini API Key to run the example. Create or view a Gemini API Key.

API

register(name, schema, handler, metadata?)

Registers a new tool, optionally specifying a metadata object (e.g. for categories, tags, etc.).

registry.register(
  'get_weather',
  weatherSchema,
  weatherHandler,
  { category: 'weather', tags: ['api', 'env'] }
);

getTools(options?)

Returns tool schemas with optional filtering.

registry.getTools({ include: ['tool1', 'tool2'] });   // whitelist
registry.getTools({ exclude: ['admin_tool'] });       // blacklist

execute(name, args?, options?)

Executes a tool with optional runtime access control.

await registry.execute('get_weather', { city: 'Tokyo' });

// With runtime whitelist (recommended when using filtered schemas)
await registry.execute('get_weather', { city: 'Tokyo' }, {
  allowed: ['get_weather', 'search_web']
});

findTools(predicate)

Finds registered tools matching a predicate function. Each tool entry passed to the predicate is of the form { name, schema, handler, metadata }.

// Find tools in the 'weather' category
const weatherTools = registry.findTools(t => t.metadata.category === 'weather');

// Find tools that have a specific tag
const mathTools = registry.findTools(t => t.metadata.tags?.includes('math'));

Example: Context-Aware / Sandboxed Execution

You can combine findTools and execute({ allowed }) to create context-aware execution filters (e.g., dynamically sandbox a request to only run non-administrative tools):

// Find all tools that do not require administrative privileges
const safeTools = registry.findTools(t => t.metadata.role !== 'admin');
const allowedNames = safeTools.map(t => t.name); // ['get_weather', 'search_web']

// Safely execute tools based on LLM output
const toolCall = { name: 'restart_server', args: {} };

try {
  await registry.execute(toolCall.name, toolCall.args, { allowed: allowedNames });
} catch (error) {
  console.error(error.message); // "Tool access denied: restart_server"
}

Other Methods

  • has(name) → boolean
  • list() → string[] of tool names

License

MIT © supershaneski