sealmyapp
Classifies Firebase web keys as public by design and includes Firebase-specific security notes in the pre-launch checklist.
Classifies Stripe secret keys (sk_live_) as sensitive and publishable keys (pk_) as safe to expose, advising on rotation for secret keys. Also includes payment-related security checks in the pre-launch checklist.
Provides tools to audit Supabase Row Level Security (RLS) with read-only SQL queries and generate safe owner-based RLS policy templates. Also classifies Supabase anon/publishable keys as safe to expose in frontend code.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@sealmyappIs a key starting sk_live_ safe in my frontend?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
SealMyApp tools
Free, open-source security helpers for vibe-coded apps (Lovable, Bolt, Cursor, Replit, v0, and anything on Supabase or Firebase):
An MCP server your AI assistant can call to check whether a key is safe to expose, audit Supabase Row Level Security, generate safe RLS policies and run a pre-launch checklist.
A Cursor rule, an Agent Skill (Claude Code and other skill-aware agents) and an
AGENTS.mdsnippet that stop the AI from leaking secrets or "fixing" empty results withusing (true).
Everything here runs locally and makes no network calls.
Made by SealMyApp, a paid service that finds, fixes and monitors security holes in vibe-coded apps. The tools in this repo are free and MIT-licensed, and you don't need a SealMyApp account to use them.
Install the MCP server
Requires Node.js 20+ and git. The first run downloads and builds the package from GitHub, so it takes a little longer.
Claude Code
claude mcp add sealmyapp -- npx -y github:toby7979/sealmyapp-toolsClaude Desktop (claude_desktop_config.json: Settings → Developer → Edit Config)
{
"mcpServers": {
"sealmyapp": {
"command": "npx",
"args": ["-y", "github:toby7979/sealmyapp-tools"]
}
}
}Cursor (.cursor/mcp.json in your project, or ~/.cursor/mcp.json for all projects)
{
"mcpServers": {
"sealmyapp": {
"command": "npx",
"args": ["-y", "github:toby7979/sealmyapp-tools"]
}
}
}VS Code (.vscode/mcp.json; note the top-level key is servers)
{
"servers": {
"sealmyapp": {
"type": "stdio",
"command": "npx",
"args": ["-y", "github:toby7979/sealmyapp-tools"]
}
}
}Then ask your assistant things like "Is a key starting sk_live_ safe in my frontend?", "Give me SQL to audit RLS in my Supabase project" or "Run the pre-launch security checklist for my Lovable app".
Related MCP server: opzyai
Tools
Tool | Input | What it returns |
|
| Whether the key is public by design (Supabase anon/publishable, Stripe |
| none | Read-only SQL that lists tables without RLS, policies whose USING/WITH CHECK is |
|
| Example owner-based policies (select/insert/update/delete with |
| optional | A pre-launch checklist covering secrets, Supabase, Firebase, auth and payments, with notes for your builder. |
|
| How to run a free, ownership-verified scan of an app you own at sealmyapp.com, and a link to start it. It does not call any API or start a scan. |
Every tool's output ends with a one-line link to SealMyApp's free scan.
Cursor rule
Copy rules/cursor/vibe-security.mdc into your project's .cursor/rules/ folder:
mkdir -p .cursor/rules
curl -fsSL https://raw.githubusercontent.com/toby7979/sealmyapp-tools/main/rules/cursor/vibe-security.mdc -o .cursor/rules/vibe-security.mdcIt's set to alwaysApply: true. Change it to false if you'd rather Cursor pull it in only when the description matches the task.
Agent Skill (Claude Code and other skill-aware agents)
Copy the skills/vibe-security folder into .claude/skills/ in your project (or ~/.claude/skills/ for all projects):
mkdir -p .claude/skills/vibe-security
curl -fsSL https://raw.githubusercontent.com/toby7979/sealmyapp-tools/main/skills/vibe-security/SKILL.md -o .claude/skills/vibe-security/SKILL.mdThe agent loads it automatically when you work on keys, env vars, RLS, Firebase rules, auth or payments.
AGENTS.md
For Codex and other agents that read AGENTS.md, paste the section from AGENTS.md into your project's AGENTS.md.
Privacy
The MCP server runs on your machine over stdio. No tool makes a network call, sends telemetry or reads your files. A test (
test/privacy.test.ts) fails the build if network or file-system APIs appear in the source.check_key_exposureworks from the key's format only and never tests the key against any API. Pass a prefix (for examplesk_live_) rather than a whole key: whatever you type goes into your assistant's conversation, which is handled by your AI provider, not by this tool.scan_my_app_instructionsonly builds a link. Nothing is sent to SealMyApp unless you open it and start a scan yourself.
Development
npm install # also builds via the prepare script
npm test # builds, then runs unit tests and a stdio test that spawns the server and lists its tools
npm run build
npm run list-toolsThe server uses the official MCP TypeScript SDK (@modelcontextprotocol/server, v2) with the stdio transport. It serves both 2025-era clients and the 2026-07-28 protocol.
Contributing
Issues and pull requests are welcome, especially:
new key formats for
check_key_exposure(please link the provider's docs saying whether the key is publishable or secret),policy templates for other common table shapes,
builder-specific checklist notes that you've checked against the builder's current UI.
Please keep the tools offline (no network calls) and add a test for any change. Never paste a real secret into an issue; a prefix is enough. Report security problems in this repo privately to hello@sealmyapp.com.
Licence
MIT. Copyright (c) 2026 Richmond Capital Holdings Ltd. See LICENSE.
Available Tools
5 toolscheck_key_exposureIs this key safe to expose?ARead-onlyIdempotent
Classify an API key as public-by-design (e.g. Supabase anon/publishable, Stripe pk_) or secret (e.g. sk_live_, service_role, sk-ant-), offline from its format, and say what to do next (rotate first if secret). Pass ONLY the prefix (first 8-15 characters), never the whole key. No network calls; the full key is never echoed back.
| Name | Required | Description | Default |
|---|---|---|---|
| key_or_prefix | Yes | The first few characters of the key, e.g. 'sk_live_' or 'sb_publishable_'. A prefix is enough. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/idempotent/closed-world annotations, the description discloses that classification is done offline with no network calls and that the full key is never echoed back — exactly the behavioral traits that matter for a credential-handling tool. It also flags the security-relevant next step (rotate if secret).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no waste. It front-loads the core classification behavior, then the safety instruction about what to pass and what not to send. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with no output schema, the description covers the input contract, the output semantics (public-by-design vs secret, with examples), the recommended action, and the privacy behavior. Nothing needed to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100% and the single parameter's description restates the prefix guidance, so the baseline is 3. The description adds value by tightening the contract — 'Pass ONLY the prefix (first 8-15 characters), never the whole key' — which clarifies intent and privacy constraints beyond the schema's softer 'a prefix is enough'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: classify an API key as public-by-design vs secret, offline from its format. It names concrete examples of each class (Supabase anon/publishable, Stripe pk_ vs sk_live_, service_role, sk-ant-), so the agent knows exactly what this tool returns without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear operational context and a follow-up action ('rotate first if secret'), which is real guidance. It does not, however, contrast itself against the siblings (supabase_rls_audit_sql, rls_policy_template, vibe_security_checklist, scan_my_app_instructions), so an agent choosing among the security tools gets no explicit routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rls_policy_templateSafe RLS policy templateARead-onlyIdempotent
Return example Supabase RLS policies (select/insert/update/delete using auth.uid()) for a common table shape, with caveats. Never uses using (true) on private data.
| Name | Required | Description | Default |
|---|---|---|---|
| table_kind | Yes | The shape of the table. | |
| owner_column | No | Column holding the owner's user id. Defaults: profiles=id, posts/orders=user_id, messages=sender_id. Ignored for files. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly/idempotent/non-destructive/closed-world. The description still adds real value by disclosing the content policy of what it generates: policies use auth.uid() and it 'never uses `using (true)` on private data', plus it returns caveats. It doesn't describe response shape, but the safety guarantee is the more decision-relevant trait.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with zero waste; the return content is front-loaded and the caveat about `using (true)` closes as a useful qualifier rather than filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only, two-parameter template generator with full schema coverage and annotations covering the safety profile, the description tells the agent what comes back (example policies with caveats). No output schema exists, so explaining the returned artifact was the main remaining burden and it is largely handled.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% – table_kind's enum and owner_column's defaults (profiles=id, posts/orders=user_id, messages=sender_id, ignored for files) are already fully documented in the schema. The description adds no parameter detail, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource: 'Return example Supabase RLS policies (select/insert/update/delete using auth.uid())'. This separates it in spirit from the audit-oriented sibling supabase_rls_audit_sql, though it never names an alternative explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'for a common table shape' implies the intended scenario – scaffolding boilerplate policies for standard tables – but there is no explicit when-to-use, when-not-to-use, or pointer to a sibling such as supabase_rls_audit_sql for verifying existing policies. Usage must be inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scan_my_app_instructionsHow to scan my appARead-onlyIdempotent
Explain how to run a free, ownership-verified, read-only security scan of an app you own at sealmyapp.com, and return a link to start it. Does NOT call any API or start a scan.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | The public URL of the app, e.g. https://myapp.lovable.app |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish the read-only, idempotent, non-destructive profile, so the bar is lower. The description adds meaningful context beyond them: the scan is free, ownership-verified, and importantly that this tool performs no API call or scan action itself and only returns a link.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences, front-loaded with the action and outcome, followed by the crucial non-action clarification. Every clause earns its place with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description helpfully states the return is a link to start the scan, and it clearly bounds the behavior for a single-parameter tool. Adequate for the tool's low complexity, though it could name the relevant sibling tools for routing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single 'url' parameter is well documented with an example in the schema. The description adds no format or meaning beyond what the schema already provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: explains how to run a free, ownership-verified, read-only security scan and returns a start link. It implicitly distinguishes itself from action tools by declaring it does not start a scan, though it does not name any of the sibling tools directly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a clear when-not signal: 'Does NOT call any API or start a scan,' telling the agent this is purely informational. It lacks explicit routing to named alternatives among the siblings (e.g. supabase_rls_audit_sql, check_key_exposure), but the context is otherwise clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
supabase_rls_audit_sqlSupabase RLS audit SQLARead-onlyIdempotent
Return read-only SQL to paste into the Supabase SQL editor that lists tables without Row Level Security, policies whose USING/WITH CHECK is true, views that bypass RLS and public storage buckets, plus how to read the results.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already establish the safety profile (readOnly=true, destructive=false, idempotent=true), so the bar is lower. The description adds genuinely non-derivable behavior: the tool returns SQL *text to paste manually* into the Supabase SQL editor rather than executing anything, and it also supplies guidance on interpreting the results — important context the annotations do not convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence: the action and channel ('Return read-only SQL to paste into the Supabase SQL editor') come first, followed by the coverage list. It is slightly run-on with a four-item enumeration plus a trailing clause, but every clause carries distinct payload and nothing is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With zero parameters and no output schema, the description must characterize the return value, and it does: read-only SQL text plus how to read the results. The scope of checks is fully enumerated. Only minor gaps remain, such as whether the output is a single script or multiple named queries.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline of 4 applies; there are no argument semantics to explain. The description correctly omits any parameter talk, wasting no space on nonexistent inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb (return) and a precisely scoped resource (read-only SQL for a Supabase RLS audit), then enumerates exactly what the SQL surfaces: tables without RLS, `true` USING/WITH CHECK policies, RLS-bypassing views, and public storage buckets. It does not name the closest sibling (rls_policy_template), which creates/remediates rather than audits, so an agent can't fully route between the two from this text alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended context is implied by the name and content — you use this to audit an existing Supabase project's RLS posture — but there is no explicit when-to-use, when-not-to-use, or comparison against rls_policy_template or vibe_security_checklist. The agent must infer the boundary between auditing and policy templating.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vibe_security_checklistPre-launch security checklistARead-onlyIdempotent
Return a pre-launch security checklist for an AI-built app (secrets, Supabase RLS, Firebase rules, auth, payments), with notes for the builder used.
| Name | Required | Description | Default |
|---|---|---|---|
| builder | No | Which tool built the app. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and closed-world, so the safety profile is fully covered by structured data. The description adds that the output is a curated checklist with builder-tailored notes rather than live scan results, but says nothing about sizing, ordering, or how the builder value changes coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the action and resource, with the category list and the builder qualifier packed in without filler. The parenthetical list is dense but each item carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description must characterize the return value, and it does: a checklist spanning five security domains plus builder-specific notes. Only the exact shape/format of the checklist is left unspecified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the enum values are self-documenting, so the baseline is 3. 'With notes for the builder used' hints that the parameter changes the returned notes, which is mild added meaning beyond 'Which tool built the app.'
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb ('Return') plus concrete resource ('pre-launch security checklist') and an enumerated scope (secrets, RLS, Firebase rules, auth, payments). An agent can tell it apart from the sibling audit/scan tools, which actually inspect code, though the description never explicitly says it is guidance-only rather than an audit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Pre-launch' implies the timing context, but there is no explicit when-to-use versus the siblings (supabase_rls_audit_sql, check_key_exposure, scan_my_app_instructions). The agent must infer that this is the planning/guidance step rather than the auditing step.
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.
5 tool updates
v0.1.0- First observed
check_key_exposure - First observed
rls_policy_template - First observed
scan_my_app_instructions - First observed
supabase_rls_audit_sql - First observed
vibe_security_checklist
TDQS
Scored across 5 tools
Most tools target clearly distinct outputs: key classification (check_key_exposure), RLS audit SQL, RLS policy templates, a general checklist, and scan instructions. The two RLS tools (supabase_rls_audit_sql vs rls_policy_template) share a domain and could be momentarily confused, but one audits existing tables while the other provides example policies, so the boundary is workable.
All names use snake_case, which is consistent, but the structural convention is mixed: some are verb-led actions (check_key_exposure, scan_my_app_instructions) while others are noun phrases (supabase_rls_audit_sql, rls_policy_template, vibe_security_checklist). Readable but not a single predictable pattern.
Five tools is well-scoped for a lightweight pre-launch security assistant. Each tool covers a distinct advisory function and none feels redundant or padded.
The surface covers key exposure, Supabase RLS auditing, RLS templates, and a generic pre-launch checklist, but it lacks an actual scan execution (scan_my_app_instructions only explains how), no dedicated Firebase rules tool despite the checklist mentioning it, and no secret-rotation guidance beyond advisory text. Usable but with notable gaps for the stated 'secure your AI-built app' purpose.
Maintenance
Related MCP Connectors
Security scanner for AI agents: prompt injection, leaked secrets, PII, and SSRF-risk URL detection.
Deterministic safety, correctness & cost gate that vets Postgres SQL before your AI agent runs it.
Scan a deployed app URL for exposed keys, open Supabase tables and missing security headers.
Zero-config MCP security scanner for AI-generated apps. 25K+ vulnerability patterns.
Related MCP Servers
- AlicenseNot gradedqualityFmaintenancePredeploy 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.51 npmApache 2.0
- AlicenseNot gradedqualityDmaintenanceLocal-first security check for AI coding agents — finds hardcoded secrets, exposed .env files, git-history leaks and vulnerable dependencies (OSV), entirely on your machine. Ask your agent "is this safe to ship?" and get a Launch Readiness score with a fix for every finding.MIT
- FlicenseAqualityDmaintenanceAudits PostgreSQL/Supabase schemas for security issues like missing RLS, permissive policies, and sensitive data exposure during AI conversations.3-

shipsafe-mcpofficial
AlicenseAqualityCmaintenanceEnables AI coding assistants to scan projects for security issues such as leaked API keys, missing Supabase RLS, open Firebase rules, unauthenticated routes, and hallucinated packages, then fix and verify the results.81MIT