{"_id":"@carlos.e.alves3/mcp-postgres-server","_rev":"5-e5ee5e06236473fae62e5caaf7882f93","name":"@carlos.e.alves3/mcp-postgres-server","dist-tags":{"latest":"1.4.0"},"versions":{"1.2.1":{"name":"@carlos.e.alves3/mcp-postgres-server","version":"1.2.1","keywords":["mcp","model-context-protocol","postgresql","database","claude","ai","llm"],"author":{"name":"carlos.e.alves2@proton.me"},"license":"MIT","_id":"@carlos.e.alves3/mcp-postgres-server@1.2.1","maintainers":[{"name":"carlos.e.alves3","email":"suportebeloj@gmail.com"}],"homepage":"https://github.com/carlosealves2/mcp-postgres-server#readme","bugs":{"url":"https://github.com/carlosealves2/mcp-postgres-server/issues"},"bin":{"mcp-postgres-server":"dist/index.js"},"dist":{"shasum":"27d7bf7745410230f8c64d694c15868cbafa038c","tarball":"https://registry.npmjs.org/@carlos.e.alves3/mcp-postgres-server/-/mcp-postgres-server-1.2.1.tgz","fileCount":23,"integrity":"sha512-erG3smNaLD7LWGyLXdZ23lFsR2Cr0hLstplKB77sY0NRE3VhRZ66xOQN9Rh6ArVwKMAjA2c0wU0rFZYJP4lPGA==","signatures":[{"sig":"MEUCIQDOLKcxRNx14nQK4E7SO4CabfX4/6pxLX4scnCxpwZhpwIgR494y6if+tVrO/Hs7H3tXz7rcwPvMOGV1dd2ZWPuqiQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@carlos.e.alves3%2fmcp-postgres-server@1.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1711937},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"index.ts","engines":{"node":">=18.0.0"},"gitHead":"ae8c5c6db044fe5de3f55e82a82274ad9acf63f1","scripts":{"dev":"bun --hot index.ts","test":"bun test","build":"bun build index.ts --compile --outfile mcp-database-client","start":"bun index.ts","build:npm":"bun build index.ts --outdir dist --target node --format esm && cp -r src dist/","typecheck":"tsc --noEmit","test:coverage":"bun test --coverage","prepublishOnly":"bun run build:npm"},"_npmUser":{"name":"carlos.e.alves3","email":"suportebeloj@gmail.com"},"repository":{"url":"git+https://github.com/carlosealves2/mcp-postgres-server.git","type":"git"},"_npmVersion":"10.8.2","description":"MCP server for read-only PostgreSQL database access","directories":{},"_nodeVersion":"20.19.5","dependencies":{"ssh2":"^1.17.0","yaml":"^2.8.1","postgres":"^3.4.7","@toon-format/toon":"^1.0.0","@modelcontextprotocol/sdk":"^1.20.2"},"_hasShrinkwrap":false,"devDependencies":{"@types/bun":"latest","@types/ssh2":"^1.15.5"},"peerDependencies":{"typescript":"^5"},"_npmOperationalInternal":{"tmp":"tmp/mcp-postgres-server_1.2.1_1763479341647_0.7816944636582557","host":"s3://npm-registry-packages-npm-production"}},"1.2.2":{"name":"@carlos.e.alves3/mcp-postgres-server","version":"1.2.2","keywords":["mcp","model-context-protocol","postgresql","database","claude","ai","llm"],"author":{"name":"carlos.e.alves2@proton.me"},"license":"MIT","_id":"@carlos.e.alves3/mcp-postgres-server@1.2.2","maintainers":[{"name":"carlos.e.alves3","email":"suportebeloj@gmail.com"}],"homepage":"https://github.com/carlosealves2/mcp-postgres-server#readme","bugs":{"url":"https://github.com/carlosealves2/mcp-postgres-server/issues"},"bin":{"mcp-postgres-server":"dist/index.js"},"dist":{"shasum":"dc4b13e39447f1dac5273a7537aba1fd1256be1a","tarball":"https://registry.npmjs.org/@carlos.e.alves3/mcp-postgres-server/-/mcp-postgres-server-1.2.2.tgz","fileCount":23,"integrity":"sha512-+X1IBT2TfWGgKxqcLsQGJCGuyzGCOAaQkxnTBcDbQ8foayOfAhVzw9fZrUHp/u9YkZRviKrNN/AEGHmhBh77Dg==","signatures":[{"sig":"MEUCIQDsUpmWv26zBGnw6QUmg48mHoBnVCIJT/zEN54BIwREDwIgP+3fEoHHw5+T1ADWNsaPDfbc3t+41FRx6H5+m1xTh5c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@carlos.e.alves3%2fmcp-postgres-server@1.2.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1716118},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"index.ts","engines":{"node":">=18.0.0"},"gitHead":"8bbef3cc7b2ba87117ad445cf0b522506f7d6bb6","scripts":{"dev":"bun --hot index.ts","test":"bun test","build":"bun build index.ts --compile --outfile mcp-database-client","start":"bun index.ts","build:npm":"bun build index.ts --outdir dist --target node --format esm && cp -r src dist/","typecheck":"tsc --noEmit","test:coverage":"bun test --coverage","prepublishOnly":"bun run build:npm"},"_npmUser":{"name":"carlos.e.alves3","email":"suportebeloj@gmail.com"},"repository":{"url":"git+https://github.com/carlosealves2/mcp-postgres-server.git","type":"git"},"_npmVersion":"10.8.2","description":"MCP server for read-only PostgreSQL database access","directories":{},"_nodeVersion":"20.19.5","dependencies":{"ssh2":"^1.17.0","yaml":"^2.8.1","postgres":"^3.4.7","@toon-format/toon":"^1.0.0","@modelcontextprotocol/sdk":"^1.20.2"},"_hasShrinkwrap":false,"devDependencies":{"@types/bun":"latest","@types/ssh2":"^1.15.5"},"peerDependencies":{"typescript":"^5"},"_npmOperationalInternal":{"tmp":"tmp/mcp-postgres-server_1.2.2_1763569670216_0.6163467472901032","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@carlos.e.alves3/mcp-postgres-server","version":"1.3.0","keywords":["mcp","model-context-protocol","postgresql","database","claude","ai","llm"],"author":{"name":"carlos.e.alves2@proton.me"},"license":"MIT","_id":"@carlos.e.alves3/mcp-postgres-server@1.3.0","maintainers":[{"name":"carlos.e.alves3","email":"suportebeloj@gmail.com"}],"homepage":"https://github.com/carlosealves2/mcp-postgres-server#readme","bugs":{"url":"https://github.com/carlosealves2/mcp-postgres-server/issues"},"bin":{"mcp-postgres-server":"dist/index.js"},"dist":{"shasum":"eda4d9095a171a3a8ee1172187f90e1a65f4b316","tarball":"https://registry.npmjs.org/@carlos.e.alves3/mcp-postgres-server/-/mcp-postgres-server-1.3.0.tgz","fileCount":24,"integrity":"sha512-yLfh3eyznEsgA0SdHWFS9EvmPeY4jKwwrmXPPO9DAaO5LZa6EjR2nP/RewJ0IAOfezWaiy95T/CwT4FLms+mBw==","signatures":[{"sig":"MEQCIDQxmmpjD2MrC/eMe8kpZ3gTWfgxwSMlgKA7UuDrlVpqAiAO1lwhRgPQUofmJVuxKmJaCfvjxWm479XvU90uZ68n3A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@carlos.e.alves3%2fmcp-postgres-server@1.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1722412},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"index.ts","engines":{"node":">=18.0.0"},"gitHead":"c87bbf8c2d943259f0f0366a13f455ebb2c545bb","scripts":{"dev":"bun --hot index.ts","test":"bun test","build":"bun build index.ts --compile --outfile mcp-database-client","start":"bun index.ts","build:npm":"bun build index.ts --outdir dist --target node --format esm && cp -r src dist/","typecheck":"tsc --noEmit","test:coverage":"bun test --coverage","prepublishOnly":"bun run build:npm"},"_npmUser":{"name":"carlos.e.alves3","email":"suportebeloj@gmail.com"},"repository":{"url":"git+https://github.com/carlosealves2/mcp-postgres-server.git","type":"git"},"_npmVersion":"10.8.2","description":"MCP server for read-only PostgreSQL database access","directories":{},"_nodeVersion":"20.19.5","dependencies":{"ssh2":"^1.17.0","yaml":"^2.8.1","postgres":"^3.4.7","@toon-format/toon":"^1.0.0","@modelcontextprotocol/sdk":"^1.20.2"},"_hasShrinkwrap":false,"devDependencies":{"@types/bun":"latest","@types/ssh2":"^1.15.5"},"peerDependencies":{"typescript":"^5"},"_npmOperationalInternal":{"tmp":"tmp/mcp-postgres-server_1.3.0_1763570770888_0.8475213840616189","host":"s3://npm-registry-packages-npm-production"}},"1.3.1":{"name":"@carlos.e.alves3/mcp-postgres-server","version":"1.3.1","keywords":["mcp","model-context-protocol","postgresql","database","claude","ai","llm"],"author":{"name":"carlos.e.alves2@proton.me"},"license":"MIT","_id":"@carlos.e.alves3/mcp-postgres-server@1.3.1","maintainers":[{"name":"carlos.e.alves3","email":"suportebeloj@gmail.com"}],"homepage":"https://github.com/carlosealves2/mcp-postgres-server#readme","bugs":{"url":"https://github.com/carlosealves2/mcp-postgres-server/issues"},"bin":{"mcp-postgres-server":"dist/index.js"},"dist":{"shasum":"7bb5e44e74629dda334ed095e17186c4dc03c7e1","tarball":"https://registry.npmjs.org/@carlos.e.alves3/mcp-postgres-server/-/mcp-postgres-server-1.3.1.tgz","fileCount":24,"integrity":"sha512-7+TwJSbZ8mKWd/GFtg0QCwnDZoAxlEcfWPOnJk45Q8upDCWm624T356CvK0Uh8IaFE0IQY2atZltgmZz9FuKrw==","signatures":[{"sig":"MEQCIBSeoyDfwUVpFw1cs9n8dcRyjUuJq2k4FF04Cn4MpIjIAiAU4OxZOEBpcJLWH4PPOFWIGS0ZVPjjGFdCkvuNx1X0gA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@carlos.e.alves3%2fmcp-postgres-server@1.3.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1722435},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"index.ts","engines":{"node":">=18.0.0"},"gitHead":"2bf94396426d326ccbd6e4e56d0966b0423c9f46","scripts":{"dev":"bun --hot index.ts","test":"bun test","build":"bun build index.ts --compile --outfile mcp-database-client","start":"bun index.ts","build:npm":"bun build index.ts --outdir dist --target node --format esm && cp -r src dist/","typecheck":"tsc --noEmit","test:coverage":"bun test --coverage","prepublishOnly":"bun run build:npm"},"_npmUser":{"name":"carlos.e.alves3","email":"suportebeloj@gmail.com"},"repository":{"url":"git+https://github.com/carlosealves2/mcp-postgres-server.git","type":"git"},"_npmVersion":"10.8.2","description":"MCP server for read-only PostgreSQL database access","directories":{},"_nodeVersion":"20.19.5","dependencies":{"ssh2":"^1.17.0","yaml":"^2.8.1","postgres":"^3.4.7","@toon-format/toon":"^1.0.0","@modelcontextprotocol/sdk":"^1.20.2"},"_hasShrinkwrap":false,"devDependencies":{"@types/bun":"latest","@types/ssh2":"^1.15.5"},"peerDependencies":{"typescript":"^5"},"_npmOperationalInternal":{"tmp":"tmp/mcp-postgres-server_1.3.1_1764527651728_0.19025101812555434","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@carlos.e.alves3/mcp-postgres-server","version":"1.4.0","description":"MCP server for read-only PostgreSQL database access","author":{"name":"carlos.e.alves2@proton.me"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/carlosealves2/mcp-postgres-server.git"},"bugs":{"url":"https://github.com/carlosealves2/mcp-postgres-server/issues"},"homepage":"https://github.com/carlosealves2/mcp-postgres-server#readme","keywords":["mcp","model-context-protocol","postgresql","database","claude","ai","llm"],"module":"index.ts","main":"dist/index.js","types":"dist/index.d.ts","type":"module","bin":{"mcp-postgres-server":"dist/index.js"},"scripts":{"start":"bun index.ts","dev":"bun --hot index.ts","build":"bun build index.ts --compile --outfile mcp-database-client","build:npm":"bun build index.ts --outdir dist --target node --format esm && cp -r src dist/","test":"bun test","test:coverage":"bun test --coverage","prepublishOnly":"bun run build:npm","typecheck":"tsc --noEmit"},"engines":{"node":">=18.0.0"},"devDependencies":{"@types/bun":"latest","@types/ssh2":"^1.15.5"},"peerDependencies":{"typescript":"^5"},"dependencies":{"@modelcontextprotocol/sdk":"^1.20.2","@toon-format/toon":"^1.0.0","postgres":"^3.4.7","ssh2":"^1.17.0","yaml":"^2.8.1"},"_id":"@carlos.e.alves3/mcp-postgres-server@1.4.0","gitHead":"749f90daf563668cb8886c2a8d89fcf75adde072","_nodeVersion":"20.19.5","_npmVersion":"10.8.2","dist":{"integrity":"sha512-+T9V3XeQImby9ipbiPnOrnLKecAQFJMrqoJroMRMCuZH5KL7dhlZqGzdNw1dPnReHm7CrBE8Hs1r6gneSbwZAQ==","shasum":"3e141c530dfc2e77b0d2857ee37639c0b970e97f","tarball":"https://registry.npmjs.org/@carlos.e.alves3/mcp-postgres-server/-/mcp-postgres-server-1.4.0.tgz","fileCount":23,"unpackedSize":1635118,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@carlos.e.alves3%2fmcp-postgres-server@1.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIHRn6qtxrVhPq6PeGt6lq3NQ5E2d/TJ3bqSNFVvkK14EAiACg5Np0AwKpwhAydQuvRrJsVa6UUcR6vP9x7M8akA4gA=="}]},"_npmUser":{"name":"carlos.e.alves3","email":"suportebeloj@gmail.com"},"directories":{},"maintainers":[{"name":"carlos.e.alves3","email":"suportebeloj@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-postgres-server_1.4.0_1764530030391_0.2597662407368897"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-18T15:22:21.567Z","modified":"2025-11-30T19:13:51.002Z","1.2.1":"2025-11-18T15:22:21.864Z","1.2.2":"2025-11-19T16:27:50.434Z","1.3.0":"2025-11-19T16:46:11.113Z","1.3.1":"2025-11-30T18:34:11.986Z","1.4.0":"2025-11-30T19:13:50.575Z"},"bugs":{"url":"https://github.com/carlosealves2/mcp-postgres-server/issues"},"author":{"name":"carlos.e.alves2@proton.me"},"license":"MIT","homepage":"https://github.com/carlosealves2/mcp-postgres-server#readme","keywords":["mcp","model-context-protocol","postgresql","database","claude","ai","llm"],"repository":{"type":"git","url":"git+https://github.com/carlosealves2/mcp-postgres-server.git"},"description":"MCP server for read-only PostgreSQL database access","maintainers":[{"name":"carlos.e.alves3","email":"suportebeloj@gmail.com"}],"readme":"# PostgreSQL MCP Server\n\nServidor MCP (Model Context Protocol) para acesso somente-leitura a bancos de dados PostgreSQL. Permite que assistentes de IA como Claude consultem bancos PostgreSQL de forma segura.\n\n## Funcionalidades\n\n- **Acesso Somente-Leitura**: Apenas queries SELECT são permitidas (modo seguro padrão)\n- **Modo Inseguro (Opcional)**: Permite operações de escrita (INSERT, UPDATE, DELETE) para desenvolvimento\n- **Paginação**: Suporte a limit e offset para consultas grandes\n- **Validação de Segurança**: Prevenção de SQL injection, limites de tamanho e timeout\n- **Múltiplos Formatos**: Saída em TEXT, JSON, YAML ou TOON (otimizado para LLMs)\n- **Suporte SSH Tunnel**: Conexão segura via bastion/jump host\n- **Ferramentas MCP**:\n  - `query` - Executar queries SQL (SELECT ou CRUD se insecure=true)\n  - `list_tables` - Listar tabelas de um schema\n  - `describe_table` - Detalhar estrutura de tabela (colunas, índices, foreign keys)\n\n## Requisitos\n\n- [Bun](https://bun.sh) v1.0+\n- PostgreSQL 12+\n\n## Instalação\n\n```bash\nbun install\n```\n\n## Configuração\n\n### Variáveis de Ambiente\n\nCrie um arquivo `.env` baseado no exemplo:\n\n```bash\ncp .env.example .env\n```\n\n**Conexão Direta:**\n\n```env\nPOSTGRES_HOST=localhost\nPOSTGRES_PORT=5432\nPOSTGRES_DATABASE=mydb\nPOSTGRES_USER=postgres\nPOSTGRES_PASSWORD=sua_senha\nPOSTGRES_MAX_CONNECTIONS=10\n\n# Modo inseguro - permite operações de escrita (default: false)\n# ⚠️ ATENÇÃO: Use apenas em ambientes de desenvolvimento/teste\nPOSTGRES_INSECURE=false\n```\n\n**Conexão via SSH Tunnel:**\n\n```env\nPOSTGRES_HOST=db-interno.example.com\nPOSTGRES_PORT=5432\nPOSTGRES_DATABASE=mydb\nPOSTGRES_USER=postgres\nPOSTGRES_PASSWORD=sua_senha\n\nSSH_TUNNEL_ENABLED=true\nSSH_HOST=bastion.example.com\nSSH_PORT=22\nSSH_USERNAME=seu_usuario\nSSH_PASSWORD=sua_senha_ssh\n# ou\nSSH_PRIVATE_KEY_PATH=/home/user/.ssh/id_rsa\n```\n\n### Configuração MCP Client\n\nAdicione ao seu cliente MCP (ex: Claude Desktop, Claude Code):\n\n**Opção 1: Usando pacote npm publicado (Recomendado)**\n\n```json\n{\n  \"mcpServers\": {\n    \"postgres\": {\n      \"command\": \"bunx\",\n      \"args\": [\"@carlos.e.alves3/mcp-postgres-server\"],\n      \"env\": {\n        \"POSTGRES_HOST\": \"localhost\",\n        \"POSTGRES_PORT\": \"5432\",\n        \"POSTGRES_DATABASE\": \"mydb\",\n        \"POSTGRES_USER\": \"postgres\",\n        \"POSTGRES_PASSWORD\": \"sua_senha\",\n        \"POSTGRES_INSECURE\": \"false\"\n      }\n    }\n  }\n}\n```\n\n**Opção 2: Usando repositório local (Desenvolvimento)**\n\n```json\n{\n  \"mcpServers\": {\n    \"postgres\": {\n      \"command\": \"bun\",\n      \"args\": [\"run\", \"/caminho/absoluto/para/mcp-database-client/index.ts\"],\n      \"env\": {\n        \"POSTGRES_HOST\": \"localhost\",\n        \"POSTGRES_PORT\": \"5432\",\n        \"POSTGRES_DATABASE\": \"mydb\",\n        \"POSTGRES_USER\": \"postgres\",\n        \"POSTGRES_PASSWORD\": \"sua_senha\",\n        \"POSTGRES_INSECURE\": \"false\"\n      }\n    }\n  }\n}\n```\n\n## Uso\n\n### Executar Servidor\n\n```bash\n# Produção\nbun start\n\n# Desenvolvimento (hot reload)\nbun dev\n\n# Build executável standalone\nbun run build\n./mcp-database-client\n```\n\n### Ferramentas Disponíveis\n\n**query** - Executar SQL com paginação:\n```json\n{\n  \"sql\": \"SELECT * FROM users WHERE age > 18\",\n  \"limit\": 50,\n  \"offset\": 100,\n  \"format\": \"JSON\"\n}\n```\n\nResposta inclui metadados de paginação:\n```json\n{\n  \"data\": [...],\n  \"rowCount\": 50,\n  \"pagination\": {\n    \"limit\": 50,\n    \"offset\": 100,\n    \"hasMore\": true\n  }\n}\n```\n\n**list_tables** - Listar tabelas:\n```json\n{\n  \"schema\": \"public\",\n  \"format\": \"TEXT\"\n}\n```\n\n**describe_table** - Descrever tabela:\n```json\n{\n  \"table\": \"users\",\n  \"schema\": \"public\",\n  \"format\": \"YAML\"\n}\n```\n\n### Formatos de Saída\n\n- **TEXT** - Formato tabular legível\n- **JSON** - JSON formatado com indentação\n- **YAML** - YAML estruturado\n- **TOON** - Token-Oriented Object Notation (otimizado para LLMs, padrão)\n\n## Segurança\n\n### Validações Implementadas\n\n1. **Query Read-Only** (padrão): Apenas SELECT e WITH (CTEs) permitidos\n2. **Keywords Bloqueadas**: INSERT, UPDATE, DELETE, DROP, ALTER, CREATE, TRUNCATE, GRANT, REVOKE, EXEC, EXECUTE, CALL, COPY, IMPORT\n3. **Padrões Bloqueados**: INTO OUTFILE, LOAD DATA\n4. **Normalização**: Remove comentários SQL para evitar bypass\n5. **Limites**:\n   - Tamanho máximo: 10.000 caracteres\n   - Máximo de linhas retornadas: 1.000 (ajustável via paginação)\n   - Timeout: 30 segundos\n6. **Queries Parametrizadas**: Para list_tables e describe_table\n\n### Modo Inseguro (Desenvolvimento)\n\n⚠️ **ATENÇÃO**: Use apenas em ambientes de desenvolvimento/teste!\n\nQuando `POSTGRES_INSECURE=true`, todas as operações SQL são permitidas:\n\n```env\nPOSTGRES_INSECURE=true\n```\n\nIsso habilita:\n- INSERT, UPDATE, DELETE\n- CREATE, ALTER, DROP\n- TRUNCATE, GRANT, REVOKE\n- Todas as operações DDL e DML\n\n**Avisos de segurança:**\n```\n⚠️  WARNING: INSECURE MODE ENABLED - Write operations are allowed\n[WARN] INSECURE MODE: Query validation bypassed - write operations allowed\n```\n\n### Logging de Segurança\n\nTodas as queries bloqueadas são logadas com detalhes:\n\n```\n[SECURITY] Query blocked: contains blocked keyword {\"keyword\":\"INSERT\"}\n[SECURITY] Query blocked: exceeds maximum length {\"queryLength\":10500}\n```\n\n## Testes\n\nO projeto inclui 174 testes unitários cobrindo segurança, formatação e validação.\n\n```bash\n# Executar todos os testes\nbun test\n\n# Com relatório de cobertura\nbun test --coverage\n\n# Teste específico\nbun test src/security.test.ts\n```\n\n### Cobertura de Testes\n\n| Módulo              | Funções  | Linhas |\n|---------------------|----------|--------|\n| security.ts         | 100%     | 100%   |\n| config.ts           | 100%     | 100%   |\n| query-tool.ts       | 100%     | 100%   |\n| formatter.ts        | 88.89%   | 93.65% |\n| list-tables-tool.ts | 66.67%   | 92.31% |\n\n## Estrutura do Projeto\n\n```\nmcp-database-client/\n├── index.ts                          # Entry point MCP server\n├── src/\n│   ├── config.ts                     # Configuração do banco\n│   ├── database.ts                   # Pool de conexões\n│   ├── security.ts                   # Validação de queries\n│   ├── formatter.ts                  # Formatação de saída\n│   ├── logger.ts                     # Sistema de logging\n│   ├── ssh-tunnel.ts                 # Suporte SSH tunnel\n│   ├── *.test.ts                     # Testes unitários\n│   └── tools/\n│       ├── query-tool.ts             # Ferramenta query\n│       ├── list-tables-tool.ts       # Ferramenta list_tables\n│       ├── describe-table-tool.ts    # Ferramenta describe_table\n│       └── *.test.ts                 # Testes das ferramentas\n├── package.json\n├── tsconfig.json\n└── CLAUDE.md                         # Instruções para Claude Code\n```\n\n## Logging\n\n### Níveis de Log\n\nConfigure via `LOG_LEVEL`:\n\n```env\nLOG_LEVEL=info  # debug | info | warn | error\n```\n\n### Formato\n\n```env\nLOG_FORMAT=json  # ou text (padrão)\n```\n\n### Exemplos\n\n```\n[2025-01-15T10:30:45.123Z] INFO: [QUERY] Executing SQL query {\"queryLength\":45}\n[2025-01-15T10:30:45.234Z] INFO: [QUERY] Query executed successfully {\"rowCount\":150,\"duration\":111}\n[2025-01-15T10:30:50.456Z] WARN: [SECURITY] Query blocked: contains blocked keyword {\"keyword\":\"INSERT\"}\n```\n\n## Troubleshooting\n\n### Erros de Conexão\n\n1. Verifique se PostgreSQL está rodando:\n   ```bash\n   pg_isready -h localhost -p 5432\n   ```\n\n2. Confira credenciais no `.env`\n\n3. Verifique firewall e `pg_hba.conf`\n\n### Query Bloqueada\n\n- Query deve iniciar com SELECT ou WITH\n- Não pode conter keywords de escrita (INSERT, UPDATE, DELETE, etc.)\n- Tamanho máximo: 10.000 caracteres\n\n### Timeout\n\n- Otimize queries com índices\n- Divida queries grandes\n- Verifique performance do banco\n\n## Stack Técnica\n\n- **Runtime**: [Bun](https://bun.sh)\n- **Database**: PostgreSQL via `postgres` library\n- **Protocol**: [Model Context Protocol (MCP)](https://modelcontextprotocol.io)\n- **Transport**: stdio\n\n## Licença\n\nMIT\n\n## Links\n\n- [Model Context Protocol](https://modelcontextprotocol.io)\n- [Bun Documentation](https://bun.sh/docs)\n- [PostgreSQL Documentation](https://www.postgresql.org/docs/)\n","readmeFilename":"README.md"}