Skip to main content
Glama

Kelp

Security scanner for vibe-coded apps. Finds the doors AI code generators leave open — hardcoded secrets, permissive RLS, unauthenticated edge functions — and gates them out of your pull requests.

License: MIT CI PRs Welcome Deploy

Live app · Docs · CLI · MCP server · GitHub Action · Architecture


What it does

Kelp scans an app's backend surface — Supabase (managed backends included), edge functions, RLS policies, source tree — the way an attacker would. Every finding is evidence-gated: a reviewer re-runs the reproduction before it lands in your report, so what you see is what an attacker would actually get.

Four surfaces, one detection engine:

Surface

For

How you use it

CLI kelp

Local scans, CI shells, scripts

npx @kelp-security/cli scan ./my-app

MCP server kelp mcp

Claude Code, Claude Desktop, Cursor, any MCP client

npx @kelp-security/cli mcp

GitHub Action kelp/check

Pull-request gating

uses: kelp-security/kelp-action@v1

Hosted app kelp.build

Continuous scanning, dashboard, PR fixes

Connect a repo, sign in with GitHub

Zero configuration in the common case. The Action reads the workflow's GITHUB_TOKEN, the hosted app installs a GitHub App, the CLI walks the filesystem, the MCP server speaks stdio JSON-RPC to the LLM client.

Related MCP server: guardvibe

Quickstart — CLI

npx @kelp-security/cli scan ./my-app
kelp v0.1.0  ·  scanning ./my-app  ·  214 files walked

CRITICAL  src/lib/db.ts:14   VITE_SERVICE_ROLE — Supabase service_role JWT
HIGH      src/api/orders.ts  hardcoded Stripe secret (sk_live_…)
MEDIUM    supabase/config.toml  verify_jwt=false on get-order

3 findings · 8s · report at ./kelp-report.json

Add --json for machine-readable output, --severity high to filter, or see docs/CLI.md for the full reference.

Quickstart, MCP server

Kelp implements the Model Context Protocol so an LLM client (Claude Code, Claude Desktop, Cursor, or any MCP-compatible client) can call Kelp mid-conversation, while it is writing code, instead of scanning after the fact. Same static engine as the CLI, exposed as MCP tools, resources, and slash commands over stdio. Runs locally, offline. No file content ever leaves the machine.

Add to your client's MCP config (~/.claude.json, Claude Desktop config, or the Cursor MCP settings):

{
  "mcpServers": {
    "kelp": {
      "command": "npx",
      "args": ["-y", "@kelp-security/cli", "mcp"]
    }
  }
}

Restart the client, then ask the assistant to scan the repo, or use the /kelp:review-repo slash command.

MCP tools: scan_path, scan_snippet, list_rules, explain_finding, explain_rule. Resources: kelp://rules, kelp://rules/{ruleId}. Prompts (slash commands): /kelp:review-repo, /kelp:harden-file. Full guide, with per-client install snippets, in docs/MCP.md.

Quickstart — GitHub Action

Add .github/workflows/kelp-check.yml:

name: kelp/check
on:
  pull_request:
    branches: [main]
permissions:
  contents: read
  pull-requests: read
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: kelp-security/kelp-action@v1

Kelp will run on every PR, comment the verdict on the PR, and fail the check when new critical or high findings are introduced against the base branch. See the action docs for inputs and required-status-check setup.

What Kelp checks today

Class

How

Output

Secrets in source

Provider patterns (AWS/GCP/Stripe/Supabase/…) + entropy fallback

Masked preview + line + severity

Supabase RLS

Reads schema + policies, flags tables open to anon

Proposed migration snippet

Edge functions

Replays without a JWT to detect verify_jwt=false

Function name + reproduction curl

CORS + auth flows

Reads config + auth callbacks for permissive defaults

Config diff

BOLA (opt-in, hosted only)

Active test with two user-provided test accounts

Human-review only, never auto-fix

New detections land in packages/core/src/scanners/. See docs/ADAPTERS.md for extending Kelp to other backends (Firebase, Convex, PocketBase — see the north-star issue).

Architecture

Monorepo (npm workspaces). Three surfaces share one engine:

apps/
├─ web/           Next.js — hosted app at kelp.build
└─ cli/           kelp binary — standalone Node CLI
packages/
├─ core/          detection engine (pure, no I/O)
├─ worker/        scan pipeline + integrations (GitHub, Supabase, queue)
└─ db/            SQL migrations

The core is intentionally I/O-free: it takes SourceFile[] and returns Finding[]. The CLI shells file-reads to it; the worker adds the GitHub App plumbing; the web app adds auth, storage, and the reviewer loop.

Full breakdown: docs/ARCHITECTURE.md.

Evidence-gating

Kelp's most important invariant: the model never decides a finding is real. Every agent-produced lead requires a reproduction (probe + expected observable, or a source citation). The executor re-runs it and records the finding only if the observable holds. Autonomy in reasoning, zero fabrication.

Read the full principle at docs/EVIDENCE-GATING.md.

Contributing

PRs, bug reports, and new detection classes are welcome — see CONTRIBUTING.md for the dev setup and the review checklist. Security vulnerabilities go through SECURITY.md, not the public issue tracker.

Good first contributions:

License

MIT — see LICENSE.

Acknowledgements

Kelp exists because vibe-code tools ship a lot of the same footguns, and the people using them shouldn't need a security team to catch them. Built by @Mic52M — solo, in the open.

Available Tools

5 tools
explain_findingExplain a specific finding and how to fix itA
Read-only

Given a ruleId (and optionally the finding's path + preview), returns the reasoning ('why this matters') and a concrete remediation you can turn into a code change or an instruction to the user.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoThe file path where the finding fired. Optional, used for context in the response.
ruleIdYesThe rule id from a scan finding, e.g. 'stripe-secret-live'.
previewNoThe masked preview from the finding. Optional, used verbatim in the response.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations mark this as read-only and not open-world, so the bar is lower. The description adds useful behavioral detail by specifying that the output includes reasoning and remediation, and that the result can be turned into a code change or instruction. It does not contradict the annotations and offers more behavioral context than the minimal read-only hint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single well-structured sentence. It front-loads the required input (ruleId), notes optional parameters, and states the two-part output. No filler or redundant phrasing; every clause contributes to understanding how to use the tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only tool with three parameters and no output schema, the description covers the main call details: required and optional inputs, and the nature of the return value. It does not address invalid ruleId behavior or how to choose between explain_finding and explain_rule, but these are relatively minor gaps given the tool's simple purpose.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The tool description only mentions that path and preview are optional, which is already fully documented in the schema. It does not add semantic meaning beyond what the parameter descriptions provide.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear action: given a ruleId, it returns reasoning and a concrete remediation. This is specific and understandable, but it does not explicitly differentiate from the sibling explain_rule, which likely covers general rule explanations. The title adds the 'specific finding' framing, but the description itself could be clearer about the distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is used after a scan produces a finding, since it asks for a ruleId and optionally the finding's path and preview. However, it does not explicitly state when to prefer this tool over explain_rule or any other sibling, nor does it mention when not to use it. Usage guidance is present but remains implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

explain_ruleExplain a rule by idA
Read-only

Given a ruleId, returns the rule's title, class, severity, why-it-matters, and remediation pattern. Use before or after a scan to understand a rule without an active finding.

ParametersJSON Schema
NameRequiredDescriptionDefault
ruleIdYesThe rule id, e.g. 'supabase-service-role'.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The readOnlyHint annotation already declares this is a read-only operation, so the description doesn't need to state that. The description adds context by noting that it works 'without an active finding', which is a behavioral trait beyond the annotation. However, it doesn't discuss error conditions (e.g., invalid ruleId) or response details beyond listing fields, so it falls short of richer behavioral disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences with no filler. The first sentence front-loads the purpose and output; the second gives usage timing. Every word earns its place, and the structure is optimally scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a single parameter, no output schema, and readOnlyHint annotations, the description covers the essential behavior (what it returns, when to use it). It doesn't mention error handling for invalid ruleIds, but that's a minor gap for such a simple tool. The listed output fields are explicit, making it self-contained enough for an agent to call correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description for ruleId already provides an example and type. The description mentions ruleId in context and clarifies its purpose (to identify a rule), but adds no new semantic detail beyond what the schema offers. With 100% schema coverage, the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('returns'), a resource ('rule'), and enumerates the exact fields returned (title, class, severity, why-it-matters, remediation pattern). It distinguishes itself from siblings by clarifying that it works 'without an active finding', setting it apart from explain_finding which presumably requires a finding. This is unambiguous and clearly scoped.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'Use before or after a scan to understand a rule without an active finding.' This gives clear timing context and implies that if you have an active finding, you should use explain_finding instead, though it doesn't name the sibling explicitly. It provides solid usage guidance without full exclusion criteria.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_rulesList Kelp detection rulesA
Read-only

Returns the catalog of rules Kelp can fire on. Use this to introspect coverage before scanning, or to answer 'does Kelp check X?' without running a scan.

ParametersJSON Schema
NameRequiredDescriptionDefault
classNoOptional filter to a single rule class.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The readOnlyHint annotation already flags this as a safe read operation, so the description does not need to repeat that. The description adds a small behavioral nuance by implying it is lightweight ('without running a scan'), but it does not describe the return format, pagination, or any error conditions. Given the annotation coverage, a 3 is appropriate – it adds minimal behavioral context beyond the annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with zero redundancy. The main function is stated first ('Returns the catalog...'), followed by the usage guidance. Every word contributes value. It is an exemplary model of concise, front-loaded documentation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple listing tool with one optional parameter and no output schema, the description provides sufficient information: it states what is returned and when to use it. It does not describe the structure of the returned catalog, but for a list of rules that is probably self-evident. It is complete for an agent to decide when to invoke it, though a more detailed return format would push it to a 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema fully documents the single optional 'class' parameter with an enum and a description ('Optional filter to a single rule class.'). The description does not mention this parameter at all. Since schema coverage is 100%, the baseline for parameter semantics is 3 – the schema carries the weight, and the description adds no additional meaning beyond that.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a clear verb and resource: 'Returns the catalog of rules Kelp can fire on.' This precisely identifies what the tool does. It also distinguishes itself from the sibling scan/explain tools by framing it as an introspection tool for coverage checks, so an agent can tell it apart without reading other definitions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit use cases: 'Use this to introspect coverage before scanning, or to answer 'does Kelp check X?' without running a scan.' This tells the agent when to call it. It does not explicitly name alternative tools or state when not to use it, but the context makes the intent clear given the sibling names (scan_path, scan_snippet, explain_rule, explain_finding). A slightly higher score would require naming the alternative explicitly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

scan_pathScan a repository or directoryA
Read-only

Runs Kelp's static engine over a filesystem path. Detects hardcoded secrets (Stripe, AWS, GitHub, OpenAI, Anthropic, Supabase service_role, private keys, and more), Supabase edge functions that skip JWT verification, and recons Supabase edge-fn deployables. Fast, offline, deterministic. Returns findings sorted by severity.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesAbsolute or relative filesystem path to scan. Should be the repo root or a subdirectory of it.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the description adds valuable behavioral traits: 'fast, offline, deterministic' and 'returns findings sorted by severity.' These go beyond the annotation and help the agent anticipate behavior. No contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: it starts with the action, then lists detection targets, and ends with performance and output traits. Every sentence earns its place; no fluff or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter, no output schema), the description covers the core behavior and mentions output sorting. It doesn't detail the finding structure, but sibling tools like explain_finding likely cover that. The description is sufficient for an agent to call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% for the single parameter, so the schema fully documents the 'path' parameter. The description adds no extra parameter-level detail beyond confirming it's a filesystem path, which matches the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('runs'), a concrete resource ('Kelp's static engine over a filesystem path'), and enumerates exactly what it detects (hardcoded secrets, Supabase edge functions, etc.). It clearly distinguishes from siblings by the 'path' scope, even though it doesn't name alternatives explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes it clear that this tool scans a filesystem path and what it finds, but it does not explicitly state when to prefer this over scan_snippet or when not to use it. The usage is implied but not contrasted with alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

scan_snippetScan a single code snippetA
Read-only

Runs the static engine on one in-memory string as if it were a file. Use this after generating code, before showing it to the user or committing it. Cheaper than scan_path when only a diff is at stake.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesThe path this snippet would live at, e.g. src/api/orders.ts. Used to make client-side heuristics work (files under public/, src/components/, *.tsx, etc. are treated as shipped to the browser).
contentYesThe full source text of the file/snippet.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, and the description adds useful behavioral context beyond that: it operates on an in-memory string, simulates file-based scanning, and is cheaper than a full path scan. It does not describe the return shape, but the read-only, in-memory behavior is clearly conveyed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with no filler: the first states the core behavior, the second gives the intended use case and cost comparison. All information is front-loaded and useful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter, read-only tool with thorough schema descriptions, the description covers purpose, usage timing, and trade-offs versus scan_path. The only minor gap is that it never explicitly says what the scan returns, but the 'scan' semantics and sibling explain_finding make the outcome reasonably inferable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with detailed descriptions for both path and content, including why path matters for client-side heuristics. The description itself adds little parameter-level meaning beyond 'one in-memory string,' so it meets the baseline but does not exceed what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Runs the static engine on one in-memory string as if it were a file.' It clearly distinguishes itself from the sibling scan_path by operating on an in-memory string rather than a filesystem path.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit usage context: 'Use this after generating code, before showing it to the user or committing it.' It also names the alternative (scan_path) and the selection condition ('Cheaper than scan_path when only a diff is at stake'), so an agent knows when to pick this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv0.1.0
    • First observedexplain_finding
    • First observedexplain_rule
    • First observedlist_rules
    • First observedscan_path
    • First observedscan_snippet

TDQS

A4.2/5.0

Scored across 5 tools

Disambiguation4/5

Each tool has a distinct core purpose: scanning paths vs snippets, listing rules, and explaining rules vs findings. The pairings scan_path/scan_snippet and explain_rule/explain_finding have some surface similarity, but descriptions clarify their boundaries.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case: scan_path, scan_snippet, list_rules, explain_rule, explain_finding. The naming is predictable and makes the toolset easy to navigate.

Tool Count5/5

Five tools is well-scoped for a security scanning server: two scan entry points, one rule catalog query, and two explanation helpers. Each tool serves a clear, non-redundant role in the workflow.

Completeness5/5

The toolset covers the full lifecycle expected of a static analysis scanner: discover rules, scan a path or snippet, retrieve rule details, and explain findings with remediation. There are no obvious missing operations for the stated domain.

Maintenance

ActivityActive
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Security MCP server with 300+ rules for AI-generated code. Scans Next.js, Supabase, Clerk, Stripe, Prisma, Hono, GraphQL and 20+ modules. Zero config, runs locally.
    39
    331 npm
    5
    Apache 2.0
  • A
    license
    A
    quality
    C
    maintenance
    MCP server that lets AI coding agents (Claude Code, Cursor, Cline) audit Supabase projects for security misconfigurations AND apply the fixes — without leaving the agent. Tools: audit_project, list_findings, preview_fix (BEGIN/ROLLBACK safety), apply_fix (with confirmation), apply_all_fixes (transactional bulk). Closes the audit-fix loop entirely in the agent — other Supabase scanners only report.
    5
    2 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    F
    maintenance
    Predeploy security scanner for AI-generated code. 80+ vulnerability patterns across secrets, auth, injection, config, Supabase, and logging. Runs locally, code never leaves your machine. Optional x402 witnessed attestation.
    46 npm
    Apache 2.0