giancarloerra/JanuScope
GitHub: giancarloerra/JanuScope
Stars: 18 | Forks: 4
Kindly sponsored by Altaire Limited. We also offer a commercial license for organisations where AGPL is a blocker.
**Policy enforcement at the MCP threshold.** Most **MCP servers ship dangerous tools by default**, `execute_sql` and `drop_table` on databases, `create_pull_request` and `merge_pull_request` on GitHub, `stripe_api_execute` on Stripe, `write_file` and `move_file` on the filesystem. **None of them log what the LLM asked** yesterday. The **choice today is fork every server or accept the risk**. Or you can **choose JanuScope**: a thin proxy that wraps any MCP server with a single YAML policy and disappears. ## What it looks like in practice
Live GitHub Copilot output against the bundled postgres-crystaldba lens (May 2026). Left: the assistant declines to fetch email addresses because the lens classifies the column as PII, Copilot self-censors before any query is sent. Right: the assistant declines to issue an UPDATE because the lens is read-only, Copilot recognises the policy and reports the refusal cleanly rather than guessing or retrying.
| Service | Upstream MCP | Vanilla config | With JanuScope |
|---|---|---|---|
| PostgreSQL | crystaldba/postgres-mcp | { "command": "uvx", "args": ["postgres-mcp"], "env": { "DATABASE_URI": "postgresql://user:pass@host:5432/db" } } | { "command": "npx", "args": ["-y", "januscope", "--config", "postgres-crystaldba"], "env": { "DATABASE_URI": "postgresql://user:pass@host:5432/db" } } |
| MySQL | benborla/mcp-server-mysql |
{
"command": "npx",
"args": ["-y", "@benborla29/mcp-server-mysql"],
"env": {
"MYSQL_HOST": "localhost",
"MYSQL_PORT": "3306",
"MYSQL_USER": "readonly",
"MYSQL_PASS": " |
{
"command": "npx",
"args": ["-y", "januscope", "--config", "mysql-benborla29"],
"env": {
"MYSQL_HOST": "localhost",
"MYSQL_PORT": "3306",
"MYSQL_USER": "readonly",
"MYSQL_PASS": " |
| MongoDB | mongodb-js/mongodb-mcp-server | { "command": "npx", "args": ["-y", "mongodb-mcp-server"], "env": { "MDB_MCP_CONNECTION_STRING": "mongodb+srv://user:pass@cluster.mongodb.net" } } | { "command": "npx", "args": ["-y", "januscope", "--config", "mongodb-official"], "env": { "MDB_MCP_CONNECTION_STRING": "mongodb+srv://user:pass@cluster.mongodb.net" } } |
| ClickHouse | ClickHouse/mcp-clickhouse |
{
"command": "uvx",
"args": ["mcp-clickhouse"],
"env": {
"CLICKHOUSE_HOST": "myhost.clickhouse.cloud",
"CLICKHOUSE_PORT": "8443",
"CLICKHOUSE_USER": "readonly",
"CLICKHOUSE_PASSWORD": " |
{
"command": "npx",
"args": ["-y", "januscope", "--config", "clickhouse-official"],
"env": {
"CLICKHOUSE_HOST": "myhost.clickhouse.cloud",
"CLICKHOUSE_PORT": "8443",
"CLICKHOUSE_USER": "readonly",
"CLICKHOUSE_PASSWORD": " |
| Redis | redis/mcp-redis | { "command": "uvx", "args": [ "--from", "redis-mcp-server@latest", "redis-mcp-server", "--url", "redis://localhost:6379/0" ] } | { "command": "npx", "args": ["-y", "januscope", "--config", "redis-official"], "env": { "REDIS_URL": "redis://localhost:6379/0" } } |
| SQLite | panasenco/mcp-sqlite | { "command": "uvx", "args": ["mcp-sqlite", "/path/to/your.sqlite"] } | { "command": "npx", "args": ["-y", "januscope", "--config", "sqlite-panasenco"], "env": { "SQLITE_DB_PATH": "/path/to/your.sqlite" } } |
| SQL Server / Azure SQL | Azure/data-api-builder v1.7+ MCP | { "command": "dab", "args": ["start", "--mcp-stdio"], "cwd": "/path/to/your/dab-project" } | { "command": "npx", "args": ["-y", "januscope", "--config", "mssql-azure-dab"], "cwd": "/path/to/your/dab-project" } |
| Oracle Database | Oracle SQLcl 25.4+ MCP | { "command": "sql", "args": ["-mcp"] } | { "command": "npx", "args": ["-y", "januscope", "--config", "oracle-db-sqlcl"] } |
| Supabase (self-host) | Supabase CLI local MCP | { "command": "npx", "args": [ "-y", "mcp-remote", "http://127.0.0.1:54321/mcp", "--allow-http", "--transport", "http-only" ] } | { "command": "npx", "args": ["-y", "januscope", "--config", "supabase-selfhost"] } |
| Supabase (cloud) | Supabase hosted MCP (mcp.supabase.com) | { "command": "npx", "args": [ "-y", "mcp-remote", "https://mcp.supabase.com/mcp?read_only=true", "--header", "Authorization:Bearer YOUR_SBP_TOKEN", "--transport", "http-only" ] } | { "command": "npx", "args": ["-y", "januscope", "--config", "supabase-cloud"], "env": { "SUPABASE_ACCESS_TOKEN": "sbp_your_token_here" } } |
| Snowflake | Snowflake-Labs/mcp (uvx) |
{
"command": "uvx",
"args": ["snowflake-labs-mcp", "--service-config-file", "/path/to/services.yaml"],
"env": {
"SNOWFLAKE_ACCOUNT": "ORG-ACCOUNT",
"SNOWFLAKE_USER": "your_user",
"SNOWFLAKE_PASSWORD": " |
{
"command": "npx",
"args": ["-y", "januscope", "--config", "snowflake-labs"],
"env": {
"SNOWFLAKE_ACCOUNT": "ORG-ACCOUNT",
"SNOWFLAKE_USER": "your_user",
"SNOWFLAKE_PASSWORD": " |
| AWS Aurora DSQL | awslabs.aurora-dsql-mcp-server (uvx) |
{
"command": "uvx",
"args": [
"awslabs.aurora-dsql-mcp-server@latest",
"--cluster_endpoint",
" |
{
"command": "npx",
"args": ["-y", "januscope", "--config", "aurora-dsql"],
"env": {
"DSQL_CLUSTER_ENDPOINT": " |
| AWS Redshift | awslabs.redshift-mcp-server (uvx) | { "command": "uvx", "args": ["awslabs.redshift-mcp-server@latest"], "env": { "AWS_REGION": "eu-west-2", "AWS_PROFILE": "default" } } | { "command": "npx", "args": ["-y", "januscope", "--config", "redshift"], "env": { "AWS_REGION": "eu-west-2", "AWS_PROFILE": "default" } } |
| Neon (hosted Postgres) | Neon hosted MCP (mcp.neon.tech) | { "command": "npx", "args": [ "-y", "mcp-remote", "https://mcp.neon.tech/mcp?readonly=true", "--header", "Authorization:Bearer YOUR_NAPI_TOKEN", "--transport", "http-only" ] } | { "command": "npx", "args": ["-y", "januscope", "--config", "neon-cloud"], "env": { "NEON_API_KEY": "napi_your_token_here" } } |
| Filesystem | modelcontextprotocol/server-filesystem | { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/Desktop"] } | { "command": "npx", "args": ["-y", "januscope", "--config", "filesystem-mcp-official"], "env": { "FILESYSTEM_ALLOWED_DIR": "/Users/you/Desktop" } } |
| GitHub | github/github-mcp-server |
{
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": " |
{
"command": "npx",
"args": ["-y", "januscope", "--config", "github-official"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": " |
| Stripe | @stripe/mcp |
{
"command": "npx",
"args": ["-y", "@stripe/mcp"],
"env": {
"STRIPE_SECRET_KEY": "rk_live_ |
{
"command": "npx",
"args": ["-y", "januscope", "--config", "stripe-official"],
"env": {
"STRIPE_SECRET_KEY": "rk_live_ |
| Notion | Notion MCP (mcp.notion.com/mcp) | { "command": "npx", "args": ["-y", "mcp-remote", "https://mcp.notion.com/mcp"] } | { "command": "npx", "args": ["-y", "januscope", "--config", "notion-official"] } |
| Atlassian (Jira / Confluence) | atlassian/atlassian-mcp-server | { "command": "npx", "args": ["-y", "mcp-remote", "https://mcp.atlassian.com/v1/mcp"] } | { "command": "npx", "args": ["-y", "januscope", "--config", "atlassian-official"] } |
| Linear | Linear MCP (mcp.linear.app) | { "command": "npx", "args": ["-y", "mcp-remote", "https://mcp.linear.app/sse"] } | { "command": "npx", "args": ["-y", "januscope", "--config", "linear-remote"] } |
标签:自动化攻击