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

@finchtoys/minitool-api

v0.2.14

Published

Finch Mini Tool API — type contract for Finch mini tool authors. Zero runtime dependencies.

Downloads

2,280

Readme

@finchtoys/minitool-api

Type definitions for Finch mini tool authors.

This is a type-only package — zero runtime dependencies, zero bundle impact. Use it as the published type package for Finch mini tools, then map the finch module to its declarations in tsconfig.json.

All runtime APIs are accessed through the ctx object injected at activation; the finch module name is only a compile-time type alias.

Installation

npm install --save-dev @finchtoys/minitool-api

Quick Start

import type * as finch from 'finch';

export function activate(ctx: finch.MiniToolContext) {
  ctx.subscriptions.push(
    ctx.tools.register({
      name: 'greet',
      title: 'Greet',
      description: 'Say hello.',
      inputSchema: {
        type: 'object',
        properties: { name: { type: 'string', description: 'Name to greet' } },
        required: ['name'],
      },
      async execute({ name }) {
        return { content: [{ type: 'text', text: `Hello, ${name}!` }] };
      },
    }),
  );
}

export function deactivate() {}

import type — the import is erased at compile time. The finch module name is just a type alias for this package's declarations; runtime APIs still come from ctx.

tsconfig Setup

Add a path alias so TypeScript resolves 'finch' to this package's declarations:

// tsconfig.json
{
  "compilerOptions": {
    "moduleResolution": "Bundler",
    "paths": {
      "finch": ["./node_modules/@finchtoys/minitool-api/finch.d.ts"]
    }
  }
}

API Overview

All APIs are accessed through ctxMiniToolContext is the preferred public type for the single entry point. ExtensionContext remains available as a deprecated compatibility alias.

Lifecycle

| Export | Description | |---|---| | activate(ctx) | Called when the extension is enabled. Register all resources here and push their Disposable handles into ctx.subscriptions. | | deactivate() | Optional. Called before the extension is disabled. In-memory cleanup only — ctx.subscriptions are disposed automatically. |

ctx.tools — Agent Tools

Register functions the AI agent can call. Each tool has a name, description, JSON Schema inputSchema, and an async execute handler.

ctx.tools.register({
  name: 'search_web',
  title: 'Search the Web',
  description: 'Search the web and return results.',
  inputSchema: { type: 'object', properties: { query: { type: 'string' } }, required: ['query'] },
  async execute({ query }, exec) {
    exec.logger.info('searching for', query);
    return { content: [{ type: 'text', text: await search(query) }] };
  },
});

The second argument exec is a ToolExecutionContext providing:

| Member | Type | Description | |---|---|---| | exec.logger | Logger | Prefixed log output | | exec.storage | Storage | Extension-private KV store | | exec.secrets | Secrets | Read-only access to declared secrets | | exec.ui.requestForm(spec) | Promise<ExtensionFormResult> | Pop a user form inline during tool execution | | exec.signal | AbortSignal \| undefined | Set to aborted when the user cancels | | exec.cwd | string \| undefined | Active working directory | | exec.sessionId | string | Current session id |

ctx.composerActions — Composer Toolbar Buttons

Add buttons to the Composer input bar. Declare the button slot in package.json under contributes.composerActions, then register its logic at runtime:

ctx.composerActions.register('git-branch', {
  async getBadge({ cwd }) { return getCurrentBranch(cwd); },
  async getMenu({ cwd })  { return listBranches(cwd).map(b => ({ id: b, label: b })); },
  async execute({ cwd }, itemId, actions) { await checkoutBranch(cwd, itemId); },
});

ctx.ui — UI

| Method | Description | |---|---| | showToast(options) | Non-blocking notification toast | | showConfirmDialog(options) | Confirm / cancel modal | | showModalDialog(options) | Custom-button modal | | showMessage(message, type?) | Inline status message | | createCanvasWindow(options) | Floating transparent window for desktop pets, overlays, etc. |

ctx.app — Finch App Info

Read basic host app information such as version, build number, locale, platform, and User-Agent.

const app = await ctx.app.getInfo();
ctx.logger.info(`Running on Finch ${app.versionDisplay}`);

ctx.storage — Private KV Store

Simple async key–value store scoped to this extension. Data is removed automatically when the extension is uninstalled.

await ctx.storage.set('config', { apiKey: 'sk-…' });
const config = await ctx.storage.get<{ apiKey: string }>('config');
await ctx.storage.delete('config');

ctx.secrets — Secrets

Encrypted, extension-scoped secrets declared in package.json → permissions.secrets. Finch refuses the operation when OS secure storage is unavailable and never falls back to plaintext. Declare exact names or a trailing prefix wildcard such as mcp.*; bare * is rejected.

await ctx.secrets.set('MY_API_KEY', apiKeyFromSecureForm);
const apiKey = await ctx.secrets.get('MY_API_KEY');
await ctx.secrets.delete('MY_API_KEY');

ctx.settings — User Settings

Read declared settings (defined by package.json → settings JSON Schema, rendered natively by Finch). Read-only; extension reloads after the user saves.

const theme = ctx.settings.get<string>('theme'); // returns T | undefined

ctx.capabilities — Cross-Extension Communication

Extensions can provide and consume named capability APIs without importing each other directly. Calls are routed across the extension host boundary, so every method returns a Promise.

// Consumer
interface McpClient {
  listTools(server: string): Promise<{ name: string }[]>;
}
const mcp = ctx.capabilities.get<McpClient>('mcp.client');
const tools = await mcp.listTools('filesystem');

ctx.i18n — Internationalization

Reads i18n/<locale>.json files from your extension directory. Automatically follows the Finch app language.

ctx.i18n.t('toast.saved', { name: 'config' });
ctx.i18n.onDidChangeLocale(locale => console.log('language changed to', locale));

ctx.logger — Logging

ctx.logger.info('extension activated');
ctx.logger.error('something went wrong', err);

ctx.icons — Runtime Icon Packs

Register SVG icons at runtime (declared in package.json → contributes.iconPacks):

ctx.icons.register('my-icons', {
  rocket: { svg: '<svg viewBox="0 0 24 24">…</svg>' },
});

ctx.session / ctx.workspace — Read-only Context

ctx.session.id        // current session id
ctx.session.cwd       // active working directory
ctx.workspace.spaceId // active Space id (undefined in default session)

Manifest (package.json)

All mini tool metadata lives under the finch key in package.json. Use MiniToolManifest for type hints:

{
  "name": "my-finch-extension",
  "version": "0.1.0",
  "main": "dist/index.js",
  "finch": {
    "manifestVersion": 1,
    "id": "my-extension",
    "name": "My Mini Tool",
    "description": "Does something useful.",
    "miniToolType": "community",
    "activationEvents": ["onStartup"],
    "contributes": {
      "tools": true,
      "composerActions": [
        { "id": "my-btn", "icon": "Star", "tooltip": "My Button" }
      ]
    },
    "permissions": {
      "filesystem": "read",
      "network": true,
      "shell": false,
      "secrets": ["MY_API_KEY"]
    }
  }
}

Localization

Put locale overrides in i18n/zh-CN.json (or i18n/en-US.json). The name, description, systemPrompt, and promptGuides fields are looked up automatically.

// i18n/zh-CN.json
{
  "name": "我的扩展",
  "description": "做些有用的事。",
  "toast.saved": "已保存 {name}"
}

MCP Server Contributions

Declare an MCP stdio server that Finch's MCP Bridge will start when your extension is enabled:

"contributes": {
  "mcpServers": [
    {
      "name": "my-server",
      "command": "npx",
      "args": ["-y", "my-mcp-server@latest"],
      "env": { "API_KEY": "" },
      "description": "My MCP server. Run setup_my_extension before use."
    }
  ]
}

Links

License

MIT