TPMJS Documentation

The complete guide to using TPMJS - the registry for AI tools.

Introduction

TPMJS (Tool Package Manager for JavaScript) is a registry and execution platform for AI tools. It enables AI agents to dynamically discover, load, and execute tools from npm packages at runtime.

🔍

Discover

Search thousands of AI tools from the npm ecosystem

Execute

Run any tool in a secure sandbox - no installation needed

📦

Publish

Share your tools with the AI community via npm

TPMJS works with Vercel AI SDK, LangChain, LlamaIndex, and any framework that supports the AI SDK tool format.

Quick Start

Get up and running with TPMJS in under 2 minutes.

1. Install the SDK packages

npm install @tpmjs/registry-search @tpmjs/registry-execute

2. Add to your agent

import { streamText } from 'ai';
import { anthropic } from '@ai-sdk/anthropic';
import { registrySearchTool } from '@tpmjs/registry-search';
import { registryExecuteTool } from '@tpmjs/registry-execute';

const result = await streamText({
  model: anthropic('claude-sonnet-4-20250514'),
  tools: {
    registrySearch: registrySearchTool,
    registryExecute: registryExecuteTool,
  },
  system: `You have access to thousands of tools via the TPMJS registry.
Use registrySearch to find tools, then registryExecute to run them.`,
  prompt: 'Search for web scraping tools and scrape example.com',
});

3. That's it!

Your agent can now discover and execute any tool from the TPMJS registry. The agent will automatically search for relevant tools and execute them as needed.

Core Concepts

Tool Discovery

TPMJS automatically discovers tools from npm packages that have the tpmjs-tool keyword. Tools are indexed every 2-15 minutes.

Sandboxed Execution

All tools run in an isolated Deno runtime on Railway. They cannot access your local filesystem or environment. API keys are passed per-request and never stored.

Quality Scoring

Every tool receives a quality score (0.00-1.00) based on metadata completeness, npm downloads, and GitHub stars. Higher scores mean better visibility in search results.

Health Monitoring

Tools are continuously health-checked to ensure they can be imported and executed. Broken tools are flagged and can be filtered from search results.

Installation

Install the TPMJS SDK packages to give your AI agent access to the tool registry.

npm install @tpmjs/registry-search @tpmjs/registry-execute
pnpm add @tpmjs/registry-search @tpmjs/registry-execute
yarn add @tpmjs/registry-search @tpmjs/registry-execute

Peer Dependencies: Both packages require ai and zod as peer dependencies. Make sure you have them installed.

registryExecuteTool

Execute any tool from the registry by its toolId. Tools run in a secure sandbox—no local installation required.

Import

import { registryExecuteTool } from '@tpmjs/registry-execute';

Parameters

ParameterTypeRequiredDescription
toolIdstring
Yes
Tool identifier (format: package::name)
paramsobject
Yes
Parameters to pass to the tool
envobjectNoEnvironment variables (API keys)

Example

// Execute a web search tool
const result = await registryExecuteTool.execute({
  toolId: '@exalabs/ai-sdk::webSearch',
  params: { query: 'latest AI news' },
  env: { EXA_API_KEY: 'your-api-key' },
});

// Result:
// {
//   toolId: '@exalabs/ai-sdk::webSearch',
//   executionTimeMs: 1234,
//   output: { results: [...] }
// }

Passing API Keys

Many tools require API keys (e.g., Firecrawl, Exa). The recommended approach is to wrap registryExecuteTool with your pre-configured keys.

Create a Wrapper

import { tool } from 'ai';
import { registryExecuteTool } from '@tpmjs/registry-execute';

// Pre-configure your API keys
const API_KEYS: Record<string, string> = {
  FIRECRAWL_API_KEY: process.env.FIRECRAWL_API_KEY!,
  EXA_API_KEY: process.env.EXA_API_KEY!,
};

// Create a wrapped version that auto-injects keys
export const registryExecute = tool({
  description: registryExecuteTool.description,
  parameters: registryExecuteTool.parameters,
  execute: async ({ toolId, params }) => {
    return registryExecuteTool.execute({ toolId, params, env: API_KEYS });
  },
});

Use the Wrapped Tool

import { streamText } from 'ai';
import { registrySearchTool } from '@tpmjs/registry-search';
import { registryExecute } from './tools';  // Your wrapped version

const result = streamText({
  model: anthropic('claude-sonnet-4-20250514'),
  tools: {
    registrySearch: registrySearchTool,
    registryExecute,  // Keys are auto-injected
  },
  prompt: 'Scrape https://example.com and summarize the content',
});

API Overview

The TPMJS API is a REST API that provides access to the tool registry. All endpoints return JSON and are publicly accessible without authentication.

Base URL: https://tpmjs.com/api

GET /api/tools

List all tools with optional filtering and pagination.

Query Parameters

ParameterTypeRequiredDescription
qstringNoSearch query
categorystringNoFilter by category
officialbooleanNoFilter to official tools only
limitnumberNoMax results (default 20, max 50)
offsetnumberNoPagination offset

Example Request

curl https://tpmjs.com/api/tools?q=web+scraping&limit=5

GET /api/tools/[id]

Get detailed information about a specific tool.

Path Parameters

ParameterTypeRequiredDescription
idstring
Yes
Tool ID (npm package name)

Example Request

curl https://tpmjs.com/api/tools/@tpmjs/hello

POST /api/tools/execute/[...slug]

Execute a tool with an AI agent and receive streaming results via Server-Sent Events (SSE). This endpoint allows you to run any TPMJS tool remotely without installing it.

URL Formats

By tool ID: /api/tools/execute/clx123abc

By package and export: /api/tools/execute/@tpmjs/hello/helloWorldTool

Request Body

ParameterTypeRequiredDescription
promptstring
Yes
Natural language prompt for the AI agent (max 2000 chars)
parametersobjectNoOptional tool parameters to pass directly

SSE Events

chunk

Streaming text chunks from the AI agent response

tokens

Token usage updates during execution

complete

Final result with output, token breakdown, and execution time

error

Error message if execution fails

Example Request

curl -X POST https://tpmjs.com/api/tools/execute/@tpmjs/hello/helloWorldTool \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Say hello to the world"}'

JavaScript Example

const response = await fetch(
  'https://tpmjs.com/api/tools/execute/@tpmjs/hello/helloWorldTool',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ prompt: 'Say hello to the world' }),
  }
);

const reader = response.body?.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  const chunk = decoder.decode(value);
  const lines = chunk.split('\n');

  for (const line of lines) {
    if (line.startsWith('event: ')) {
      const event = line.slice(7);
      console.log('Event:', event);
    }
    if (line.startsWith('data: ')) {
      const data = JSON.parse(line.slice(6));
      console.log('Data:', data);
    }
  }
}

Rate Limiting

clock

Rate Limits

The execute endpoint is rate limited to 10 requests per minute per IP address. Rate limit headers are included in the response:X-RateLimit-Limit: 10X-RateLimit-Remaining: 9

Publishing Overview

Publishing a tool to TPMJS is as simple as publishing to npm with standardized metadata.

1

Add tpmjs-tool keyword

2

Add tpmjs field

3

Publish to npm

4

Live in 15 minutes!

TPMJS Specification

The tpmjs field in package.json describes your tool. TPMJS automatically extracts parameter schemas from your tool code, so you only need to provide basic metadata.

✨ Auto Schema Extraction: Parameters are automatically extracted from your tool's Zod inputSchema - no need to document them manually!

{
  "name": "@yourname/my-tool",
  "version": "1.0.0",
  "keywords": ["tpmjs-tool"],
  "tpmjs": {
    "category": "text-analysis",
    "frameworks": ["vercel-ai"],
    "tools": [
      {
        "name": "myTool",
        "description": "What your tool does (20-500 chars)"
      }
    ]
  }
}

🔍 Auto-Discovery: The tools array is optional! If you omit it, TPMJS will automatically discover all exported tools from your package. Each export that has a description and execute property is treated as a valid tool.

Metadata Fields

TPMJS auto-extracts parameter schemas and can auto-discover your tools, simplifying what you need to provide.

Required

category - The only truly required field!

Optional

tools (auto-discovered if omitted), env (API keys), frameworks (compatibility)

Auto-extracted

description, parameters - extracted from your tool code

Auto-discovered

If you omit tools, TPMJS scans your package exports and registers any export with description + execute properties as a tool.

Quality Score

Every tool receives a quality score (0.00-1.00) that affects search ranking.

function calculateQualityScore(params: {
  tier: 'minimal' | 'basic' | 'rich';
  downloads: number;
  githubStars: number;
}): number {
  const tierScore = tier === 'rich' ? 0.6 : tier === 'basic' ? 0.4 : 0.2;
  const downloadsScore = Math.min(0.3, Math.log10(downloads + 1) / 10);
  const starsScore = Math.min(0.1, Math.log10(githubStars + 1) / 10);

  return Math.min(1.0, tierScore + downloadsScore + starsScore);
}

Override Execute

When you import a tool from npm, you can override its execute function before passing it to your AI agent.

Simple Override

import { someTool } from '@tpmjs/some-tool';

const myTool = {
  ...someTool,
  execute: async (args, options) => {
    console.log('Custom execution with args:', args);
    // Your completely custom implementation
    return { result: 'my custom result' };
  },
};

Wrap with Logging

const wrappedTool = {
  ...someTool,
  execute: async (args, options) => {
    console.log(`[${new Date().toISOString()}] Calling tool with:`, args);
    const start = Date.now();
    const result = await someTool.execute(args, options);
    console.log(`[${Date.now() - start}ms] Tool returned:`, result);
    return result;
  },
};

Custom Wrappers

Create reusable wrapper functions for common patterns like caching, retries, and rate limiting.

Wrapper Factory

function wrapTool<T, R>(
  tool: { description: string; parameters: any; execute: (args: T, opts: any) => Promise<R> },
  options: {
    before?: (args: T) => T | Promise<T>;
    after?: (result: R) => R | Promise<R>;
    timeout?: number;
    retries?: number;
  } = {}
) {
  return {
    ...tool,
    execute: async (args: T, execOptions: any): Promise<R> => {
      let processedArgs = options.before ? await options.before(args) : args;

      let lastError: Error | undefined;
      const maxAttempts = (options.retries ?? 0) + 1;

      for (let attempt = 1; attempt <= maxAttempts; attempt++) {
        try {
          let result = await tool.execute(processedArgs, execOptions);
          if (options.after) result = await options.after(result);
          return result;
        } catch (error) {
          lastError = error as Error;
          if (attempt < maxAttempts) {
            await new Promise(r => setTimeout(r, Math.pow(2, attempt) * 100));
          }
        }
      }
      throw lastError;
    },
  };
}

Self-Hosting

Both SDK packages support self-hosted registries via environment variables.

ParameterTypeRequiredDescription
TPMJS_API_URLstringNoBase URL for registry API (default: https://tpmjs.com)
TPMJS_EXECUTOR_URLstringNoURL for sandbox executor (default: https://executor.tpmjs.com)
# Use your own TPMJS registry
export TPMJS_API_URL=https://registry.mycompany.com
export TPMJS_EXECUTOR_URL=https://executor.mycompany.com

Security

TPMJS is designed with security in mind.

🏝️

Sandboxed Execution

All tools run in an isolated Deno runtime. They cannot access your local filesystem or environment.

🔐

API Key Isolation

API keys are passed per-request and never stored. Each execution is stateless and isolated.

Registry-Only Execution

Only tools registered in TPMJS can be executed. No arbitrary code execution is possible.

🏥

Health Monitoring

Every tool is continuously health-checked. Broken tools are flagged and filtered from search results.

FAQ

How long does it take for my tool to appear?

Tools are discovered within 2-15 minutes of publishing to npm. Make sure you have the "tpmjs-tool" keyword in your package.json.

What is auto-discovery?

If you omit the "tools" array from your tpmjs field, TPMJS will automatically scan your package exports and register any export that looks like an AI SDK tool (has description and execute properties). You can override this by explicitly listing tools.

How does schema extraction work?

TPMJS automatically loads your tool in a sandbox and extracts the inputSchema from your Zod definition. You don't need to manually document parameters.

Is TPMJS free to use?

Yes! TPMJS is free for public tools. We may introduce paid tiers for private registries and enterprise features in the future.

Can I use TPMJS with any AI framework?

TPMJS works with any framework that supports the AI SDK tool format, including Vercel AI SDK, LangChain, and LlamaIndex.

How are tools executed?

Tools are dynamically loaded from esm.sh and executed in a sandboxed Deno runtime on Railway. No local installation is required.

Troubleshooting

Tool not appearing in registry

  • Ensure you have tpmjs-tool in your keywords
  • Verify your tpmjs field is valid JSON
  • Wait 15 minutes after publishing
  • Check the validation errors in the npm package page

Execution failing

  • Check that required environment variables are passed
  • Verify the toolId format is correct (package::name)
  • Check the tool's health status on tpmjs.com

Changelog

v1.0.0
December 2024

Initial release with registrySearchTool and registryExecuteTool

Ready to Get Started?

Give your AI agent access to thousands of tools in minutes.