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

@neon/tools

v0.2.0

Published

Generated agent tools for every Neon Management API operation, compatible with MCP, Eve, and Mastra.

Readme

@neon/tools

Generated agent tools for every operation in the Neon Management API. Select only the operations an agent needs, then use the canonical descriptors directly or adapt them for MCP, Eve, or Mastra.

npm install @neon/tools

Create tools

apiKey is a Bearer credential: a Neon API key or a Neon OAuth access token. A function is called on every request, which is how short-lived OAuth tokens get refreshed. A credential is required when a tool executes — at construction, on execute(), or from MCP authInfo — and an empty value is rejected rather than ignored.

import { createNeonTools } from "@neon/tools";

const apiKey = process.env.NEON_API_KEY;
if (!apiKey) throw new Error("NEON_API_KEY is required");

const operations = ["listProjects", "createProject"] as const;

const tools = createNeonTools({
	apiKey,
	operations,
});

const result = await tools.listProjects.execute({
	query: { limit: 10 },
});

OAuth access tokens use the same option. Pass a getter when the token can change:

const tools = createNeonTools({
	apiKey: () => oauth.getAccessToken(),
	operations,
});

Or supply the token per call:

const tools = createNeonTools({ operations });

await tools.listProjects.execute(
	{ query: { limit: 10 } },
	{ apiKey: oauthAccessToken },
);

The returned record is keyed by OpenAPI operation ID. Each tool includes its generated Zod 4 inputSchema, snake-case id, title, description, safety annotations, stability metadata, and an execute() function. Inputs group API parameters under path, query, headers, and body.

operationIds exports every valid selector. execute() strictly validates the input, rejects unknown fields instead of dropping them, and returns typed, JSON-safe { data }. Neon SDK errors remain typed and are thrown to the caller.

Optional host add-ons

None of these change the default createNeonTools({ apiKey, operations }) path. They exist so a host can replace hand-written Management API tools without losing descriptions, call tracking, or a grant-scoped project/branch.

Descriptions

Pass a map keyed by OpenAPI operation ID or snake-case tool id, or a function that can append to the generated text:

const tools = createNeonTools({
	apiKey,
	operations,
	descriptions: {
		listProjects:
			"List Neon projects in your account. Do not use for projects shared with you.",
		delete_project:
			"Delete a Neon project and all its data. NEVER run autonomously; always ask the user first.",
	},
});

const noticed = createNeonTools({
	apiKey,
	operations,
	descriptions: (tool) => `${tool.description}\nNotice: scoped to one project.`,
});

Tracking

onExecute wraps the call. The host must call event.execute(). That inner call performs getter resolution, path injection, original schema validation, auth, and the API request, so tracking and spans see those failures:

const tools = createNeonTools({
	apiKey,
	operations,
	onExecute: async ({ id, execute }) => {
		// record `id`, wrap in a span, then:
		return execute();
	},
});

This package does not send analytics. Mutating event.input does not change a grant-locked project or branch id.

Project and branch injection

Generated tools take OpenAPI path parameters (path.project_id, path.branch_id). A host that already knows those values can inject them. Without omitFromSchema, the published field becomes optional and a caller-supplied value wins. With omitFromSchema: true, the field is removed from the published schema and the injector is the only source:

const tools = createNeonTools({
	apiKey,
	operations: ["getProject", "deleteProjectBranch"] as const,
	inject: {
		projectId: "project-id",
		omitFromSchema: true,
	},
});

await tools.getProject.execute({});
await tools.deleteProjectBranch.execute({ path: { branch_id: "br-id" } });

Use a getter when the value is request-scoped. The getter can read the host's own AsyncLocalStorage (this package does not export one):

import { AsyncLocalStorage } from "node:async_hooks";

const grant = new AsyncLocalStorage<{ projectId: string }>();

const tools = createNeonTools({
	operations: ["getProject"] as const,
	inject: {
		projectId: () => grant.getStore()?.projectId,
		omitFromSchema: true,
	},
});

await grant.run({ projectId: "project-id" }, () => tools.getProject.execute({}));

Injectors only apply to tools that have that path key. listProjects is unchanged. Empty inject values fail closed. Invalid ids still fail the original path schema before fetch.

These add-ons do not flatten { path, query, body } into camelCase projectId, do not rename tools (get_project is not describe_project), and do not add host-only behavior such as returning a connection string from createProject. Grant filtering, read-only filtering, and access-control notices stay in the host. branchId injection fills path.branch_id only — query/body branch selectors such as getConnectionURI's query.branch_id are unchanged.

Request schemas

Generated request schemas are available independently:

import {
	zCreateProjectBody,
	zListProjectsQuery,
} from "@neon/tools/schemas";

const query = zListProjectsQuery.parse({ limit: 10 });
const body = zCreateProjectBody.parse({
	project: { name: "agent-project" },
});

These schemas are strict. If a newly added API field is not recognized, upgrade @neon/tools; use @neon/sdk directly until a matching tools release is available.

MCP

Use @neon/tools/mcp with MCP 2.x:

import { McpServer } from "@modelcontextprotocol/server";
import { createNeonTools } from "@neon/tools";
import { registerNeonTools } from "@neon/tools/mcp";

const apiKey = process.env.NEON_API_KEY;
if (!apiKey) throw new Error("NEON_API_KEY is required");

const server = new McpServer({ name: "neon", version: "1.0.0" });
const tools = createNeonTools({
	apiKey,
	operations: ["listProjects", "createProject"] as const,
});

registerNeonTools(server, tools);

For a remote MCP server that already authenticated the client, omit apiKey at construction. registerNeonTools sends authInfo.token as the Bearer credential: MCP 2.x http.authInfo.token, MCP 1.x authInfo.token. The host must put a Neon API key or Neon OAuth access token there. A present authInfo with an empty token is an error, not a fall back to a constructor key.

const tools = createNeonTools({
	operations: ["listProjects", "createProject"] as const,
});
registerNeonTools(server, tools);

This package does not implement an OAuth authorization server. That is mcp-server-neon at mcp.neon.tech.

Existing MCP 1.x servers can use the version-specific entry point:

import { registerNeonTools } from "@neon/tools/mcp-v1";

The adapter returns both text content and object-valued structuredContent. Execution failures use isError: true with structured error data.

MCP annotations are advisory; the protocol does not enforce approval. Tools expose neon/requiresApproval in MCP _meta. Hosts must read that value and enforce their own approval policy before execution.

Eve

Eve requires Node.js 24 or later.

// agent/tools/create_project.ts
import { defineTool } from "eve/tools";
import { createNeonTool } from "@neon/tools";
import { toEveTool } from "@neon/tools/eve";

const apiKey = process.env.NEON_API_KEY;
if (!apiKey) throw new Error("NEON_API_KEY is required");

export default defineTool(
	toEveTool(
		createNeonTool("createProject", {
			apiKey,
		}),
	),
);

Eve uses the filename as the model-facing tool name, so name the file after the tool's snake-case id. The adapter maps approval requirements to Eve's approval hook and forwards its abort signal.

Mastra

Mastra requires Node.js 22.13 or later.

import { createTool } from "@mastra/core/tools";
import { createNeonTools } from "@neon/tools";
import { toMastraTools } from "@neon/tools/mastra";

const apiKey = process.env.NEON_API_KEY;
if (!apiKey) throw new Error("NEON_API_KEY is required");

const neonTools = createNeonTools({
	apiKey,
	operations: ["listProjects", "createProject"] as const,
});
const configs = toMastraTools(neonTools);

const listProjects = createTool(configs.list_projects);
const createProject = createTool(configs.create_project);

The adapter maps approval requirements to Mastra's requireApproval field and forwards its abort signal.

Safety and binary data

Every non-read operation is conservatively marked as potentially destructive and requires approval. Reads that return connection credentials, role passwords, or Neon Auth provider secrets also require approval.

Binary request fields accept base64 strings:

import { createNeonTool } from "@neon/tools";

const apiKey = process.env.NEON_API_KEY;
if (!apiKey) throw new Error("NEON_API_KEY is required");

const deployFunction = createNeonTool(
	"createProjectBranchFunctionDeployment",
	{ apiKey },
);

await deployFunction.execute({
	path: {
		project_id: "project-id",
		branch_id: "branch-id",
		slug: "hello",
	},
	body: { zip: "UEsDBA==" },
});

Binary responses are JSON-safe:

{
	data: {
		base64: "aGVsbG8=",
		contentType: "application/octet-stream",
		size: 5,
	},
}

@neon/tools supports Node.js 20.19 or later. Framework integrations also require the Node.js version supported by that framework.