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

unifai-sdk

v1.0.6

Published

unifai-sdk-js is the Javascript/Typescript SDK for UnifAI, an AI native platform for dynamic tools and agent to agent communication.

Readme

MseeP.ai Security Assessment Badge

unifai-sdk-js

unifai-sdk-js is the JavaScript/TypeScript SDK for UnifAI, an AI native platform for dynamic tools and agent to agent communication.

Installation

npm install unifai-sdk

Getting your UnifAI API key

You can get your API key for free from UnifAI Console.

There are two types of API keys:

  • Agent API key: for using toolkits in your own agents.
  • Toolkit API key: for creating toolkits that can be used by other agents.

Using tools

To use tools in your agents, you need an agent API key. You can get an agent API key for free at UnifAI Console.

import { Tools } from 'unifai-sdk';

const tools = new Tools({ apiKey: 'xxx' });

Tool Types

UnifAI provides a flexible system for integrating AI tools in your applications:

Dynamic Tools

Dynamic tools are enabled by default, allowing agents to discover and use tools on-the-fly based on the task at hand. Tools will not be visible to agents directly. Instead, agents will see two functions only: one to search tools, one to use tools. Agents will be able to search for tools based on semantic query, get a list of relevant tools, and use tools dynamically.

// Enable dynamic tools (default behavior)
const dynamicTools = await tools.getTools({ dynamicTools: true });

Static Toolkits

Static toolkits allow you to specify entire toolkits to be exposed to agents so they can be used without search.

const staticTools = await tools.getTools({
  dynamicTools: false,  // Optional: disable dynamic tools
  staticToolkits: ["1", "2"]
});

You can find available toolkits at https://console.unifai.network/toolkits.

Static Actions

Static actions provide granular control, allowing you to specify individual actions (tools) to be exposed to agents.

const staticTools = await tools.getTools({
  dynamicTools: false,  // Optional: disable dynamic tools
  staticActions: ["action_id_1", "action_id_2"]
});

You can find available actions at https://console.unifai.network/actions.

Mixed Tools

You can combine these approaches for a customized tool setup:

const combinedTools = await tools.getTools({
  dynamicTools: true,
  staticToolkits: ["essential_toolkit_id"],
  staticActions: ["critical_action_id"]
});

Unverified Tools

By default, only verified tools are returned in dynamic tool search results. You can include unverified tools by setting the unverified option:

const toolsIncludingUnverified = await tools.getTools({
  dynamicTools: true,
  unverified: true
});

Note: This option only affects dynamic tools. Static tools (specified via staticToolkits or staticActions) will always be returned regardless of the unverified setting.

Passing Tools to LLMs

You can pass the tools to any OpenAI compatible API. Popular options include:

  • Model providers' native API
  • OpenRouter: A service that gives you access to most LLMs through a single OpenAI compatible API

The tools will work with any API that follows the OpenAI function calling format. This gives you the flexibility to choose the best LLM for your needs while keeping your tools working consistently.

const messages = [{ content: "Can you tell me what is trending on Google today?", role: "user" }];
const response = await openai.chat.completions.create({
  model: "gpt-4o",
  messages,
  tools: await tools.getTools(),
});

If the response contains tool calls, you can pass them to the tools.callTools method to get the results. The output will be a list of messages containing the results of the tool calls that can be concatenated to the original messages and passed to the LLM again.

const results = await tools.callTools(response.choices[0].message.tool_calls);
messages.push(...results);
// messages can be passed to the LLM again now

Passing the tool calls results back to the LLM might get you more function calls, and you can keep calling the tools until you get a response that doesn't contain any tool calls. For example:

const messages = [{ content: "Can you tell me what is trending on Google today?", role: "user" }];
while (true) {
  const response = await openai.chat.completions.create({
    model: "gpt-4o",
    messages,
    tools: await tools.getTools(),
  });
  messages.push(response.choices[0].message);
  const results = await tools.callTools(response.choices[0].message.tool_calls);
  if (results.length === 0) break;
  messages.push(...results);
}

Using tools in MCP clients

We provide a MCP server to access tools in any MCP clients such as Claude Desktop.

Make sure you have npm installed. Then in your MCP client config:

{
  "mcpServers": {
    "unifai": {
      "command": "npx",
      "args": [
        "-y",
        "-p",
        "unifai-sdk",
        "unifai-tools-mcp"
      ],
      "env": {
        "UNIFAI_AGENT_API_KEY": ""
      }
    }
  }
}

Now your MCP client will be able to access all the tools in UnifAI automatically through dynamic tools.

You can use environment variables to choose dynamic/static tools exposed by the MCP server, for example:

{
  "mcpServers": {
    "unifai": {
      "command": "npx",
      "args": [
        "-y",
        "-p",
        "unifai-sdk",
        "unifai-tools-mcp"
      ],
      "env": {
        "UNIFAI_AGENT_API_KEY": "",
        "UNIFAI_DYNAMIC_TOOLS": "true",
        "UNIFAI_STATIC_TOOLKITS": "1,2,3",
        "UNIFAI_STATIC_ACTIONS": "ACTION_A,ACTION_B",
        "UNIFAI_UNVERIFIED_TOOLS": "false"
      }
    }
  }
}

Using the CLI

The unifai CLI lets you search, invoke, and sign transactions directly from the command line. It's designed for both interactive use and AI agent integration.

# Install globally
npm install -g unifai-sdk

# Or use via npx
npx -p unifai-sdk unifai --help

Set your API key:

export UNIFAI_AGENT_API_KEY="your-api-key"

Search for tools:

unifai search --query "solana swap"

Invoke a tool:

unifai invoke --action "Solana--7--getBalance" --payload '{"walletAddress": "..."}'

Invoke with automatic transaction signing:

export SOLANA_PRIVATE_KEY="your-key"

unifai invoke --action "Solana--7--transfer" \
  --payload '{"walletAddress": "...", "toWalletAddress": "...", "amount": "0.001"}' \
  --sign

Sign a transaction by ID:

unifai tx sign <txId>

Manage configuration:

unifai config init          # Create config file (~/.config/unifai-cli/config.yaml)
unifai config show          # Show current configuration

The CLI supports Solana, Ethereum, Base, BSC, Polygon, Polymarket, and Hyperliquid chains for transaction signing. Private keys are configured via environment variables or the config file — never passed as CLI flags.

RPC URLs are optional — public endpoints are used by default. Public RPCs are typically rate-limited, so setting your own RPC URLs is recommended for production use (e.g. SOLANA_RPC_URL, ETHEREUM_RPC_URL, POLYGON_RPC_URL, etc.).

Creating tools

Anyone can create dynamic tools in UnifAI by creating a toolkit.

A toolkit is a collection of tools that are connected to the UnifAI infrastructure, and can be searched and used by agents dynamically.

Initialize a toolkit client with your toolkit API key. You can get a toolkit API key for free at UnifAI Console.

import { Toolkit } from 'unifai-sdk';

const toolkit = new Toolkit({ apiKey: 'xxx' });

Update the toolkit name and/or description if you need:

await toolkit.updateToolkit({ 
  name: "EchoChamber", 
  description: "What's in, what's out." 
});

Register action handlers:

toolkit.action(
  {
    action: "echo",
    actionDescription: "Echo the message",
    payloadDescription: {
      content: { type: "string" }
    }
  },
  async (ctx, payload) => {
    return ctx.result(`You are agent <${ctx.agentId}>, you said "${payload?.content}".`);
  }
);

Note that payloadDescription can be any string or a dict that contains enough information for agents to understand the payload format. It doesn't have to be in a certain format, as long as agents can understand it as natural language and generate the correct payload. Think of it as the comments and docs for your API, agents read it and decide what parameters to use. In practice we recommend using JSON schema to match the format of training data.

Start the toolkit:

await toolkit.run();

Examples

You can find examples in the examples directory.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.