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

@valv/prisma

v0.9.2

Published

Prisma adapter for valv — row-level security and access control for AI agents

Readme

@valv/prisma

Prisma adapter for valv — let an LLM query your relational database (PostgreSQL, MySQL, SQLite, CockroachDB), scoped by policies you write in code. The model emits a structured query; valv validates it, injects your tenant/row filter, and compiles it to SQL.

npm license

Install

npm i @valv/prisma @prisma/client
npm i -D prisma

Requires Prisma 5+.

Usage

import { PrismaClient } from "@prisma/client"
import { createValv } from "@valv/prisma"

const prisma = new PrismaClient()

// Reads the schema from your .prisma datasource on construction — call once.
const valv = await createValv(prisma, { defaultPolicy: "deny-all" })

valv.policy("order", (ctx) => ({
  read:   { tenant_id: ctx.tenant.id },   // every read is scoped to this tenant
  fields: { deny: ["internal_notes"] },   // hide a column from the model
}))

const tools = await valv.tools.aisdk(ctx) // or .anthropic / .openai / .gemini / .neutral

Resource names are inferred from your Prisma client type and converted to snake_case (OrderItemorder_item), so policy keys are type-checked — a typo is a compile error. Pass schemaPath if your schema isn't at ./prisma/schema.prisma.

See the root README for policies, the tool layer, and saved queries.

Databases

One adapter covers every provider Prisma can introspect — the right dialect (identifier quoting, $1 vs ? placeholders) is selected from your datasource:

| Provider | Quoting / placeholders | |---|---| | postgresql, cockroachdb | "col", $1 | | mysql | `col`, ? | | sqlite | "col", ? |

Mark hidden columns in your policy (fields.deny); valv reads structure from Prisma's DMMF, which has no notion of "sensitive".

Writes

All three operations, off until you allow them in policy and expose the tool:

valv.policy("order", (ctx) => ({
  read:   { tenant_id: ctx.tenant.id },
  create: { tenant_id: ctx.tenant.id },   // tenant_id force-set on insert
  update: { tenant_id: ctx.tenant.id },   // AND-injected into the WHERE
  delete: false,                          // never deletable
}))
const tools = await valv.tools.aisdk(ctx, { create: true, update: true })

await valv.create({ from: "order", values: { status: "pending", total: 1200 } }, ctx)

create force-injects owned fields; update/delete AND the scope predicate into a required where, and the model can only set writable columns. See Writes in the root README.

Zero-config from a URL

No client or generated schema? createValvFromUrl(url, { provider? }) infers the provider, runs prisma db pull + generate into a throwaway client under a writable temp dir (os.tmpdir(), so it works on read-only/serverless filesystems), and introspects — all at startup. This is the path the @valv/mcp CLI uses. Requires the prisma CLI available. Call stop() on shutdown.

import { createValvFromUrl } from "@valv/prisma"
const { valv, stop } = await createValvFromUrl("postgres://…", { defaultPolicy: "deny-all" })

License

MIT