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 AI SDK provider for your selected model (OpenAI, Anthropic, Google, etc.)
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 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 AI SDK provider for your selected model (OpenAI, Anthropic, Google, etc.)
import { anthropic } from '@ai-sdk/anthropic';
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',
});
🤖

AI Agents

Create custom AI assistants with multi-provider support, tool integration, and persistent conversations. Agents have their own dedicated documentation.

🔗

Sharing & URLs

Learn how to share your agents, collections, and profile using human-readable URLs. Clone public agents and collections to customize them.

📚

Platform Guide

Complete guide to TPMJS platform features: user accounts, collections, agents, forking, and API keys. Everything you need to know in one place.

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 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"],
  "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 the tool 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.

MCP Overview

The Model Context Protocol (MCP) allows AI assistants like Claude Desktop, Cursor, and other clients to connect directly to your TPMJS tool collections. Instead of using the SDK, MCP clients can call your tools natively through the protocol.

🔗

Direct Connection

Connect Claude Desktop or Cursor directly to your tools via MCP

📦

Curated Collections

Group related tools into collections for focused use cases

Native Integration

No SDK needed—tools appear as native capabilities in your AI client

Each collection gets a unique MCP endpoint URL that any MCP-compatible client can connect to. Tools in your collection are automatically exposed with proper schemas and descriptions.

Creating Collections

Collections let you group related tools together. Create a collection in the dashboard, then add tools from the registry.

1. Sign In

Sign in to tpmjs.com using GitHub authentication. This allows you to create and manage collections.

2. Create a Collection

Navigate to your dashboard and click "Create Collection". Give it a descriptive name like "Web Scraping Tools" or "Content Creation".

3. Add Tools

Browse the tool registry and add tools to your collection. You can add any published TPMJS tool. Each collection can contain multiple tools from different packages.

4. Get Your MCP URL

Once your collection has tools, you'll see an MCP endpoint URL in the format:

https://tpmjs.com/api/mcp/<username>/<collection-slug>/http

This URL is what you'll use to connect MCP clients to your collection. You'll also need your TPMJS API key for authentication.

Connecting Clients

Connect your TPMJS collection to any MCP-compatible client. Below are examples for popular clients.

Claude Desktop

Add your collection to Claude Desktop's configuration file:

{
  "mcpServers": {
    "tpmjs-my-collection": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://tpmjs.com/api/mcp/<username>/<collection-slug>/http",
        "--header",
        "Authorization: Bearer YOUR_TPMJS_API_KEY"
      ]
    }
  }
}

Config file location:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Claude Code CLI

Add an MCP server directly from the command line:

claude mcp add tpmjs-my-collection \
  https://tpmjs.com/api/mcp/<username>/<collection-slug>/http \
  -t http -H "Authorization: Bearer YOUR_TPMJS_API_KEY"

This automatically adds the server to your Claude Code configuration.

Cursor

Cursor supports MCP servers through its settings. Add your collection URL in the MCP configuration section of Cursor's preferences.

Other Clients

Any client that supports the Model Context Protocol can connect using your collection's HTTP endpoint. Use the mcp-remote package to bridge HTTP MCP servers to clients that expect stdio-based servers.

MCP Protocol

TPMJS implements the Model Context Protocol (MCP) using JSON-RPC 2.0 over HTTP. This section covers the technical details for advanced users and client developers.

Endpoint Format

POST https://tpmjs.com/api/mcp/<username>/<collection-slug>/http

Request Headers

Content-Type: application/json

Accept: application/json, text/event-stream

Authorization: Bearer YOUR_TPMJS_API_KEY

Supported Methods

tools/list

Returns all tools in the collection with their schemas and descriptions.

tools/call

Executes a tool with the provided arguments. Supports streaming responses.

Example: List Tools

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {}
}

Example: Call Tool

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "webSearch",
    "arguments": {
      "query": "TPMJS documentation"
    }
  }
}

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" 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 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

View the full changelog for version history, new features, and updates.

Ready to Get Started?

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