@getcordon/policy
v0.2.10
Published
TypeScript SDK for configuring Cordon for MCP — the security gateway for MCP tool calls.
Downloads
1,052
Readme
@getcordon/policy
TypeScript SDK for configuring Cordon for MCP — the security gateway for MCP tool calls.
This package exports defineConfig and the config type surface. You only need it if you're writing a cordon.config.ts file.
Install
npm install @getcordon/policycordon init (from the @getcordon/cli package) installs this automatically into your project.
Usage
import { defineConfig } from '@getcordon/policy';
export default defineConfig({
servers: [
{
name: 'database',
transport: 'stdio',
command: 'npx',
args: ['-y', '@modelcontextprotocol/server-postgres', process.env.POSTGRES_URL!],
policy: 'read-only',
},
{
name: 'github',
transport: 'stdio',
command: 'npx',
args: ['-y', '@modelcontextprotocol/server-github'],
policy: 'approve-writes',
tools: {
delete_repository: 'block',
create_pull_request: 'approve',
},
},
],
audit: {
enabled: true,
output: 'file',
},
approvals: {
channel: 'terminal',
timeoutMs: 60_000,
},
rateLimit: {
perServerPerMinute: 60,
},
});Policy actions
| Policy | Behavior |
|---|---|
| allow | Pass through immediately |
| block | Reject with an error |
| approve | Pause the agent, prompt for human approval |
| approve-writes | Reads pass through, writes require approval |
| read-only | Writes are blocked, reads pass through |
| log-only | Pass through, flagged in audit log |
| hidden | Filtered from tools/list — the model never sees it |
| sql-read-only | Parse the SQL arg; allow SELECT, block everything else (fail-closed on unparseable) |
| sql-approve-writes | Parse the SQL arg; allow reads, pause writes for approval, block unparseable |
Policies can be set at the server level or per-tool. Per-tool overrides the server default.
SQL-aware policies
For database MCP servers where a single tool takes arbitrary SQL, Cordon can parse the statement and decide based on type rather than tool name:
tools: {
query: 'sql-read-only', // default: inspects arg named 'sql'
execute: 'sql-approve-writes',
run: { action: 'sql-read-only', sqlArg: 'statement' }, // custom arg name
}- Uses PostgreSQL dialect. Other dialects: future release.
- Fail-closed: unparseable SQL (malformed, non-string, missing arg) is blocked rather than allowed.
- Classified as reads:
SELECT,WITH ... SELECTCTEs,SHOW, bareEXPLAIN SELECT/...(the leading EXPLAIN is stripped before classifying the inner statement). - Classified as writes: everything else — INSERT/UPDATE/DELETE/DROP/ALTER/TRUNCATE/CREATE/SET/BEGIN/COMMIT/ROLLBACK etc.
EXPLAIN ANALYZEis deliberately NOT stripped (ANALYZE actually executes the query) and falls through to unknown. - Multi-statement input classifies as write if any statement is non-read.
Known parser limitations (PostgreSQL dialect)
The underlying node-sql-parser doesn't parse these in PG mode, so they fall through to 'unknown' and get blocked under sql-read-only (you'd need to switch to sql-approve-writes, add a tool-level override, or wrap the intent in a supported form):
DESCRIBE users/DESC users(MySQL-style; useSELECT * FROM information_schema.columns WHERE table_name = 'users'instead)- Standalone
VALUES (1, 2), (3, 4)(wrap inSELECT * FROM (VALUES ...) AS t(a,b)) PRAGMA foreign_keys = ON(SQLite-specific)EXPLAIN ANALYZE ...(deliberately not supported — ANALYZE runs the query)
Source
https://github.com/marras0914/cordon
