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

@harryy/ai-tools

v2.11.1

Published

Reusable AI tools with strict schemas and model-facing contracts. Define once; project to Node, edge, Mastra, AI SDK, TanStack AI, Cloudflare Workers AI, or MCP.

Readme

@harryy/ai-tools

Reusable AI tools with strict Zod schemas and model-facing contracts. Define once in the kernel; project to Mastra, Vercel AI SDK, TanStack AI, Cloudflare Workers AI, MCP, or call via class clients / runTool.

ci release

Docs: docs/README.md · Changelog: CHANGELOG.md · Release: docs/versioning.md

Why

  • One authoring pathdefineTool / defineModule only; adapters never re-implement business logic.
  • Host-owned secrets — auth schemas + withAuth; model inputs never carry API keys.
  • Two product rootsmodules/ (our seams) vs vendors/ (3rd-party packs); flat public imports.
  • Class clients + tools — host uses new ResendClient(auth); agents use the same implementation via tools.
  • Subpath imports — tree-shake friendly; no root mega-barrel.
  • Honest runtimesnode | edge | both.
  • Stable tool ids — kebab-case, vendor- or capability-prefixed.

Install

bun add @harryy/ai-tools

# optional peers for adapters you use:
bun add @mastra/core
bun add ai
bun add @tanstack/ai
bun add @modelcontextprotocol/sdk   # registerMcpTools only

Requires Bun ≥ 1.3.14 or Node ≥ 24.

Quick start

import { withAuth } from '@harryy/ai-tools/core'
import { resendModule, ResendClient } from '@harryy/ai-tools/resend'
import { createMastraTools } from '@harryy/ai-tools/mastra'

// Host DX (class client)
const resend = new ResendClient({ api_key: process.env.RESEND_API_KEY! })
await resend.send({ to: '[email protected]', from: '[email protected]', subject: 'Hi', text: 'Hello' })

// Agent tools (same implementation)
const bound = withAuth(resendModule, { api_key: process.env.RESEND_API_KEY! })
export const tools = createMastraTools(bound)

Multi-provider seam (host picks provider on auth):

import { withAuth } from '@harryy/ai-tools/core'
import { emailModule } from '@harryy/ai-tools/email'

const bound = withAuth(emailModule, {
  provider: 'resend',
  api_key: process.env.RESEND_API_KEY!,
  sender: { email: '[email protected]', name: 'Product' },
})

No-auth pure helpers:

import { emailMessageModule } from '@harryy/ai-tools/email-message'
import { createAiSdkTools } from '@harryy/ai-tools/ai-sdk'

export const tools = createAiSdkTools(emailMessageModule)

Architecture

src/
  core/          kernel (defineTool, withAuth, runTool, …)
  transport/     HttpService / AwsService  →  @harryy/ai-tools/http
  adapters/      mastra · ai-sdk · tanstack · cloudflare · mcp
  modules/       our seams (email, messaging, files, …)
  vendors/       3rd-party packs (resend, telegram, s3, …)
                 + vertical kits: _email · _storage · _messaging · _vector (not published)
  shared/        bytes, batch, artifact, content-type, pagination

| Root | Role | | --- | --- | | modules/ | Capability seams we own; usually multi-provider, with explicit product-locked host or single-provider seams | | vendors/ | Full first-party API of one product; grow tools over time | | vendors/_… | Vertical kits (codegen-skipped); shared by packs in that category |

Public imports are flat: @harryy/ai-tools/resend, not @harryy/ai-tools/vendors/resend.

defineTool / defineModule
        │
        ├─► Host:   Class client  (new ResendClient(auth).send(…))
        ├─► Agent:  withAuth(module) → tools → adapters
        └─► Direct: runTool(tool, input, ctx)

Subpaths

Brain

| Import | Role | Docs | | --- | --- | --- | | @harryy/ai-tools/core | Kernel, contracts, withAuth, runTool | core | | @harryy/ai-tools/http | HttpService / AwsService | http transport | | @harryy/ai-tools/mastra | Mastra projector | mastra | | @harryy/ai-tools/ai-sdk | Vercel AI SDK projector | ai-sdk | | @harryy/ai-tools/tanstack | TanStack AI projector | tanstack | | @harryy/ai-tools/cloudflare | Workers AI tool defs | cloudflare | | @harryy/ai-tools/mcp | MCP list/call + register | mcp |

Seams (modules/)

| Import | Kind | Tools (ids) | Docs | | --- | --- | --- | --- | | @harryy/ai-tools/email | multi-provider | email-send, email-send-batch | email | | @harryy/ai-tools/messaging | multi-provider | messaging-send-text, edit, media, reactions, … (telegram/slack/teams/imessage) | messaging | | @harryy/ai-tools/files | path root over nested S3 | files-* | files | | @harryy/ai-tools/artifacts | object + host providers | artifacts-create, -read-range, -read-lines | artifacts | | @harryy/ai-tools/vector-store | qdrant, pinecone, supabase, mastra | vector-store-* | vector-store | | @harryy/ai-tools/rag | embed + nested vector-store | rag-* | rag | | @harryy/ai-tools/document-extract | multi-provider | document-extract-text, -status, -text-batch | document-extract | | @harryy/ai-tools/document-render | multi-provider | document-render-pdf, -screenshot, batches | document-render | | @harryy/ai-tools/file-convert | gotenberg LO | file-convert (office-to-pdf), batch | file-convert | | @harryy/ai-tools/document | core reader/builder/editor | read text/PDF/DOCX/XLSX/images; build text/DOCX/XLSX; edit text/DOCX/XLSX/CSV | document | | @harryy/ai-tools/presentation | PPTX reader/builder/editor | read, build, and edit PPTX presentations; Node ESM only | presentation | | @harryy/ai-tools/web-fetch | host policy | web-fetch-get, web-fetch-request | web-fetch | | @harryy/ai-tools/email-message | pure (no auth) | email-message-parse, email-message-build | email-message | | @harryy/ai-tools/content-type | pure (no auth) | content-type-get, -extension, -extensions | content-type | | @harryy/ai-tools/skills | host-bound catalog | skills-list, skills-get, skills-search | skills | | @harryy/ai-tools/tasks | host-backed definitions | tasks-create, -get, -list, -update, -delete | tasks | | @harryy/ai-tools/scheduler | eventbridge provider | scheduler-create, -update, -get, -list, -delete | scheduler | | @harryy/ai-tools/pdf | artifact utilities | inspect, merge, extract, split, rotate | pdf | | @harryy/ai-tools/image | artifact transforms | metadata, resize, crop, thumbnail, convert | image | | @harryy/ai-tools/crypto | Web Crypto | hash, HMAC sign/verify, random bytes | crypto | | @harryy/ai-tools/calendar | pure iCalendar | build and parse ICS | calendar | | @harryy/ai-tools/queue | sqs provider | enqueue, receive, acknowledge, extend visibility | queue | | @harryy/ai-tools/browser | AgentCore + Cloudflare providers | start, get, stop | browser |

Vendors (vendors/)

| Import | Tools (ids) | Docs | | --- | --- | --- | | @harryy/ai-tools/resend | resend-send, resend-send-batch | resend | | @harryy/ai-tools/cloudflare-email | cloudflare-email-send, -send-batch | cloudflare-email | | @harryy/ai-tools/telegram | telegram-send-text, -edit-text, media, reactions, … | telegram | | @harryy/ai-tools/slack | slack-send-text, edit, media, reactions, files, … | slack | | @harryy/ai-tools/teams | teams-send-text, edit, media, Bot Framework activities | teams | | @harryy/ai-tools/imessage | send/edit/react/unsend/read via Photon Advanced iMessage HTTP | imessage | | @harryy/ai-tools/s3 | s3-* (+ signed URL, multipart) | s3 | | @harryy/ai-tools/sqs | sqs-send, -receive, -delete, -change-visibility | sqs | | @harryy/ai-tools/qdrant | qdrant-upsert, -query, -delete | qdrant | | @harryy/ai-tools/pinecone | pinecone-upsert, -query, -delete | pinecone | | @harryy/ai-tools/supabase-vector | supabase-vector-* (pgvector/PostgREST) | supabase-vector | | @harryy/ai-tools/mastra-vector | mastra-vector-* (PgVector, node) | mastra-vector | | @harryy/ai-tools/textract | textract-extract-text, -get-status, -extract-text-batch | textract | | @harryy/ai-tools/eventbridge-scheduler | create/update/get/list/delete (task_ref) | eventbridge-scheduler | | @harryy/ai-tools/bedrock-agentcore-code-interpreter | session + execute + files | bedrock-agentcore-code-interpreter | | @harryy/ai-tools/bedrock-agentcore-browser | start/stop/get session + stream endpoints | bedrock-agentcore-browser |

| @harryy/ai-tools/gotenberg | render PDF/screenshot + office-to-pdf convert | gotenberg | | @harryy/ai-tools/cloudflare-browser | sessions + PDF/screenshot quick actions | cloudflare-browser | | @harryy/ai-tools/woocommerce | orders, notes, refunds, products, variations, customers, coupons, categories | woocommerce | | @harryy/ai-tools/katana | sales/purchase/manufacturing orders, products, materials, customers, suppliers, inventory | katana | | @harryy/ai-tools/amazon-sp-api | orders + items, FBA inventory, reports + documents, catalog search | amazon-sp-api |

Auth fields are snake_case (api_key, bot_token, access_key_id, …).

Guides

| Guide | Purpose | | --- | --- | | Getting started | Install, import map, first bind | | Auth and binding | Host-owned secrets, withAuth | | Adapters | Project kernel tools into frameworks | | Authoring packs | modules vs vendors, layout, codegen | | Errors | ToolError codes and retry | | HTTP / AWS transport | HttpService / AwsService | | Package surface | modules · vendors architecture | | Provider seam | Multi-provider capability modules |

Develop

bun install
bun run hooks:install
oxfmt --write <touched-paths>
bun run check          # format:check + lint + codegen:check + test
bun run codegen
bun run new-module <kebab-key> [--title …] [--description …] [--auth none|custom]
bun run build

Codegen owns package.json exports for packs under src/modules|vendors/<key>/ with index.ts. Underscore kits (_email, _storage, _messaging) are skipped.

Artifacts (extract · convert · render)

  • Objects are S3 keys (ArtifactRef), not base64 in the model. Spec: artifacts-extract-convert.
  • Read / build / edit: text, PDF, DOCX, spreadsheet, and image-metadata work lives in document; PPTX work lives in presentation. Product lock: document plane.
  • Extract: Amazon Textract (object must live in AWS S3 Textract can read).
  • Convert (office→PDF): self-host Gotenberg LibreOffice (file-convert path office-to-pdf).
  • Render (HTML/URL): Gotenberg Chromium or Cloudflare Browser Rendering → storage ArtifactRef.

Release

semantic-release on main from conventional commits. No manual version bump.

| Commit | Version | | --- | --- | | feat: | minor | | fix: / perf: / refactor: | patch | | BREAKING CHANGE / type!: | major |

Details: docs/versioning.md.

License

MIT © harryy