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

yourindie-mcp

v0.1.0

Published

Production-oriented MCP server toolkit for Supabase OAuth 2.1, RLS, Next.js, and Supabase Edge Functions.

Readme

yourindie-mcp

Build a production-oriented remote MCP server on top of your existing Supabase users, OAuth 2.1 server, and Row Level Security.

npm install yourindie-mcp
npx yourindie-mcp init

The initializer detects Next.js or a Supabase Edge/Vite project and generates:

  • a stateless Streamable HTTP MCP endpoint
  • OAuth protected-resource discovery metadata, including a separate Next.js .well-known route
  • local JWT verification through Supabase JWKS
  • a user-scoped Supabase client that preserves RLS
  • a consent page/component
  • an example authenticated tool
  • an optional strict audience and permission Auth Hook migration
  • a project-specific setup checklist

Why this package exists

Supabase handles the OAuth 2.1 authorization code flow, PKCE, user login, consent handoff, client registration, access tokens, refresh tokens, and JWKS. This package handles the MCP resource server: protocol transport, token verification, authenticated tools, permissions, RLS integration, rate limiting hooks, and audit hooks.

It never uses your Supabase service-role key. Every tool receives a Supabase client carrying the user's bearer token, so existing RLS policies remain active.

Requirements

  • Node.js 20 or newer for Next.js and CLI usage
  • Supabase Auth with OAuth 2.1 Server enabled
  • an asymmetric Supabase JWT signing key, ES256 or RS256
  • HTTPS in production

Supabase OAuth 2.1 Server is currently beta. Pin and test package updates before rolling them into critical production systems.

Quick start

Run this from an existing application:

npx yourindie-mcp init

Or provide everything without prompts:

npx yourindie-mcp init \
  --framework next \
  --name ViewBAIT \
  --resource-url https://viewbait.app/api/mcp \
  --yes

For a Supabase Edge Function:

npx yourindie-mcp init \
  --framework supabase-edge \
  --name ViziVibes \
  --resource-url https://PROJECT_REF.supabase.co/functions/v1/mcp \
  --yes

Open the generated MCP_SETUP.md, complete the Supabase dashboard steps, replace the example tool, and deploy normally.

Define tools

import { defineMcpTool, z } from 'yourindie-mcp';

export const listProjects = defineMcpTool({
  name: 'list_projects',
  description: "List the authenticated user's projects.",
  inputSchema: {
    limit: z.number().int().min(1).max(100).default(25),
  },
  readOnly: true,
  requiredPermissions: ['projects:read'],
  async handler({ limit }, { supabase, userId }) {
    const { data, error } = await supabase
      .from('projects')
      .select('id, name, updated_at')
      .eq('user_id', userId)
      .limit(limit);

    if (error) throw error;
    return { projects: data ?? [] };
  },
});

Create the MCP app

import { createSupabaseMcpApp } from 'yourindie-mcp';
import { listProjects } from './tools';

const resourceUrl = 'https://viewbait.app/api/mcp';
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;

export const mcpApp = createSupabaseMcpApp({
  name: 'ViewBAIT',
  resourceUrl,
  issuer: `${supabaseUrl}/auth/v1`,
  supabaseUrl,
  supabaseAnonKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
  expectedAudience: resourceUrl,
  tools: [listProjects],
  resolvePermissions(context) {
    const claim = context.claims.mcp_permissions;
    return Array.isArray(claim) ? claim.filter((value): value is string => typeof value === 'string') : [];
  },
});

Next.js adapter

import { createNextRouteHandlers } from 'yourindie-mcp/next';
import { mcpApp } from '@/lib/mcp/server';

export const runtime = 'nodejs';
export const dynamic = 'force-dynamic';
export const { GET, POST, DELETE, OPTIONS } = createNextRouteHandlers(mcpApp);

Supabase Edge adapter

import { createSupabaseMcpApp } from 'npm:[email protected]';
import { createEdgeHandler } from 'npm:[email protected]/edge';

const app = createSupabaseMcpApp({ /* configuration */ });
Deno.serve(createEdgeHandler(app));

Permissions are separate from OAuth scopes

Supabase currently supports the standard OIDC scopes openid, email, profile, and phone. Those scopes control identity information, not access to application tables or MCP tools.

Use these layers for application authorization:

  1. RLS for row and operation access.
  2. client_id for client-specific database policies.
  3. mcp_permissions or your own database roles for tool-level permissions.
  4. requiredPermissions, per-tool authorize, and global authorizeTool checks.

The initializer generates a Custom Access Token Hook that binds OAuth tokens to the MCP resource URL and adds an mcp_permissions claim. Strict audience validation is enabled by default in generated examples.

Security defaults

  • locally verifies JWT signatures against Supabase JWKS
  • validates issuer, expiration, role, OAuth client_id, and optional audience
  • does not accept normal browser-session tokens by default
  • uses the user's access token for Supabase requests
  • limits request body size to 1 MB by default
  • returns sanitized tool errors by default
  • supports host/origin allowlists, rate limiting, per-tool authorization, and audit logging
  • uses stateless JSON Streamable HTTP to fit serverless runtimes
  • advertises a function-local metadata fallback when Supabase Edge cannot own the origin-level .well-known route

API

createSupabaseMcpApp(options)

Creates a Hono application containing OAuth discovery, health, authentication, and MCP routes.

Important options include:

  • resourceUrl: exact public MCP URL
  • issuer: Supabase Auth issuer, normally ${SUPABASE_URL}/auth/v1
  • expectedAudience: exact audience expected in OAuth access tokens
  • resolvePermissions: maps claims/database state to application permissions
  • authorizeTool: global authorization hook
  • rateLimit: global rate-limit hook
  • audit: audit event hook
  • allowedHosts and allowedOrigins: optional request allowlists

defineMcpTool(tool)

Type-safe helper for declaring tools.

createSupabaseJwtVerifier(options)

Creates the default Supabase JWKS verifier. Supply your own tokenVerifier to integrate another compliant authorization server later.

Consent helpers

The yourindie-mcp/consent export wraps Supabase's OAuth authorization UI methods:

  • getAuthorizationDetails
  • approveAuthorization
  • denyAuthorization

CLI

npx yourindie-mcp init [options]

--framework <next|supabase-edge>
--name <application name>
--resource-url <public MCP URL>
--cwd <project directory>
--yes
--force
--dry-run

The CLI refuses to replace existing generated files unless --force is supplied.

Production checklist

Before exposing write tools:

  • test every tool against a user who does not own the requested record
  • keep RLS enabled and avoid service-role clients in tool handlers
  • validate exact resource audience
  • require explicit consent and provide revocation controls
  • monitor dynamically registered OAuth clients
  • add durable audit storage and rate limiting
  • keep admin tools in a separate MCP or enforce server-side admin claims
  • pin package versions and run integration tests before upgrades

Development

npm install
npm run typecheck
npm test
npm run build
npm run pack:check

License

MIT