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-execute2. 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-executepnpm add @tpmjs/registry-search @tpmjs/registry-executeyarn add @tpmjs/registry-search @tpmjs/registry-executePeer Dependencies: Both packages require ai and zod as peer dependencies. Make sure you have them installed.
registrySearchTool
Search the TPMJS registry to find tools for any task. Returns metadata including the toolId needed for execution.
Import
import { registrySearchTool } from '@tpmjs/registry-search';Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| query | string | Yes | Search query (keywords, tool names, descriptions) |
| category | string | No | Filter by category |
| limit | number | No | Max results (1-20, default 5) |
Return Value
{
"query": "web scraping",
"matchCount": 3,
"tools": [
{
"toolId": "@firecrawl/ai-sdk::scrapeTool",
"name": "scrapeTool",
"package": "@firecrawl/ai-sdk",
"description": "Scrape any website into clean markdown",
"category": "web-scraping",
"requiredEnvVars": ["FIRECRAWL_API_KEY"],
"healthStatus": "HEALTHY",
"qualityScore": 0.9
}
]
}Available Categories
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
| Parameter | Type | Required | Description |
|---|---|---|---|
| toolId | string | Yes | Tool identifier (format: package::name) |
| params | object | Yes | Parameters to pass to the tool |
| env | object | No | Environment 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
| Parameter | Type | Required | Description |
|---|---|---|---|
| q | string | No | Search query |
| category | string | No | Filter by category |
| official | boolean | No | Filter to official tools only |
| limit | number | No | Max results (default 20, max 50) |
| offset | number | No | Pagination offset |
Example Request
curl https://tpmjs.com/api/tools?q=web+scraping&limit=5GET /api/tools/search
BM25-ranked search optimized for AI agent tool discovery.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| q | string | Yes | Search query |
| limit | number | No | Max results (default 5, max 20) |
GET /api/tools/[id]
Get detailed information about a specific tool.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Tool ID (npm package name) |
Example Request
curl https://tpmjs.com/api/tools/@tpmjs/helloPOST /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
| Parameter | Type | Required | Description |
|---|---|---|---|
| prompt | string | Yes | Natural language prompt for the AI agent (max 2000 chars) |
| parameters | object | No | Optional tool parameters to pass directly |
SSE Events
chunkStreaming text chunks from the AI agent response
tokensToken usage updates during execution
completeFinal result with output, token breakdown, and execution time
errorError 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
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.
Add tpmjs-tool keyword
Add tpmjs field
Publish to npm
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.
category - The only truly required field!
tools (auto-discovered if omitted), env (API keys), frameworks (compatibility)
description, parameters - extracted from your tool code
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.
| Parameter | Type | Required | Description |
|---|---|---|---|
| TPMJS_API_URL | string | No | Base URL for registry API (default: https://tpmjs.com) |
| TPMJS_EXECUTOR_URL | string | No | URL 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.comSecurity
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-toolin your keywords - Verify your
tpmjsfield 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
Initial release with registrySearchTool and registryExecuteTool
Ready to Get Started?
Give your AI agent access to thousands of tools in minutes.