Skip to main content
Glama
BerkantACUN

pg-guard-mcp

pg-guard-mcp

PyPI

PostgreSQL MCP 서버로, 프로토콜 및 권한 수준에서 읽기 전용 접근을 강제합니다. 어떤 문자열을 파싱하고 "그냥 대하" 하라는 식이 아닙니다.

설치

pip install pg-guard-mcp
# or, without installing anything permanently:
uvx pg-guard-mcp

Related MCP server: PostgreSQL MCP Server

존재 이유

공식 @modelcontextprotocol/server-postgres에는 COMMIT; 한 개로 우회할 수 있는 읽기 전용 모드가 있었습니다. 이 모드는 에이전트의 쿼리를 BEGIN TRANSACTION READ ONLY로 감싸고 전체를 하나의 문자열로 보냈습니다. Postgres는 해당 모드에서 세미클롴으로 구분된 여러 문을 허용하기 때문에, SELECT 1; COMMIT; DROP SCHEMA public CASCADE; 는 읽기 전용 트랜잭션을 일찍 종료시키고 DROP을 일반 쓰기로 실행할 수 있었습니다. 이 문제로 패키지가 deprecated 되었습니다. (Datadog Security Labs의 글)

pg-guard-mcp는 바로 이 버그 클래스, 즉 "읽기 전용"을 문자열 검사만으로 강하는 접근 방식이 여전히 MCP 생태케에 흔하다는 사실에 기반ㅇ고 있습니다. 세 가지 독립적인 계층으로 대방하기 때문에, 남은 실수하나가 치명적真实 않습니다:

  1. 프로토콜 계층(진정한 경계). 모든 크리는 Postgres의 확장 크지 프로토콜 (Parse/Bind/Execute) 로 처리하며, 단순 크지 프로토[콜은 절대에서 사용하지 않습니다. 확장 프로토콜은 Parse 메시지 하나에 두 개 이상의 문을 구조적으로 거부합니다. Postgres는 우리 코드가 실행되기 전에 자체적으로 이를 거부합니다. 따라서 어떤 문자열이 전송되더라도 Datadog 공격은 여기서 작동할 수 없습니다.

  2. 세션 계층. 모든 연결은 자션의 수준에서 default_transaction_read_only = on을 설정합니다. 그래서 어떻게든 쓰기로 데이터베이스에 도달하는 쿼리라도 Postgres가 거부합니다.

  3. 사전 점검 계층. 쿼리를 실제로 보내기 전에, 문장이 여러 개인지 및 트랜잭션 제어 키워드(COMMIT, ROLLBACK, BEGIN, SAVEPOINT, ...)를 검사하고 그런 경우명확한 오류와 함께 거부합니다. 이것은 1차 방어가 아니라, 빠르고 분명하게 실패하게 하기 위한 계층입니다.

이에 더해, 쓰기 권한이 REVOKE된 데이터베이스 역할로 연결하는 것이 권장(그리고가 시작 시 확인되는) 설정입니다. 권한 계층에도 이중 안전을 더하는 것입니다.

도구

도구

기능

pg_run_query(sql

읽기 전 문장 하나를 실행하고 행을 반환합니다.

pg_explain_query(sql

리를 실행하지 않고 실행 계획을 반환합니다.

pg_list_tables(schema="public")

스크지이 테이블/뷔 담귀.

pg_describe_table(table_name, schema="public")

테이블엳 컬럼 담담.

pg_check_privileges()

연결이된 역할이 실제로 가진 쓰기 혀자를 보고합니다. 항상 비어 있어야 합니다.

설정

pip install pg-guard-mcp
export PG_GUARD_DSN="host=127.0.0.1 dbname=mydb user=myapp_readonly password=..."
pg-guard-mcp

MCP 클라이언트가 환경 설정에 PG_GUARD_DSN을 가지고 상태에서 pg-guard-mcp 명령, 또는 "영구 설치를 건너뛰어고 싶은 경우 uvx pg-guard-mcp"를 하나이게 합니다.

지원되는 모든 환경 변수는 .env.example, 권한 적절하게 제한리된 읽기 전용 역할을 만드는 실제 예시는 scripts/setup_dev_db.sh를 참조하세요 (이 프로젝트의 자체 테스트가 쓰는 설정입니다).

테스트

pip install -e ".[dev]"
pytest tests/ -v

tests/test_safety.py는 순수 Python이며 데이터베이스가 필요 없습니다. tests/test_db.py와 tests/test_server.py는 실제 로컬 PostgreSQL 인스턴스를 대르로실행되며, 공식 Postgres MCP 서버를 deprecated 하게 만든 바로 그 익스프링트 페이르드를 시험합니다. pgguard_test에 연결실 수 없으면 자동으로 건너or십니다. scripts/setup_dev_db.sh를 한 번 실행해 만들면 됩니다.

상태

v0.1.0, PyPI에서 운영 중입니다. 58개 테스트 통과(공식 server-postgres를 폐기시킨 정확한 익스프링트를 포함한 단위 + 실제 Postgres 통합 테스트로, 패치지 자체를 새로 pip install한 상태로 실행했습니다).

라이선스

MIT

Available Tools

5 tools
pg_check_privilegesA

Report any write privilege (INSERT/UPDATE/DELETE/TRUNCATE) the connected role actually holds on any table. An empty list is the expected, safe result — anything else means the privilege layer of defense is missing and the role should be locked down (see README.md), even though the protocol and session layers still hold on their own.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it discloses the expected safe result ('an empty list'), what a non-empty list means, and extra context that protocol/session layers still hold. It does not mention potential permissions needed to run the check itself, but this is a minor gap.

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 sentences, no filler: the first states the action and scope, the second frames the expected result and next step. Everything earns its place and the most important information is front-loaded.

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 zero-parameter tool with no output schema, the description is functionally complete: it defines the output semantics (list of privileges vs empty), the safety implication, and directs the agent to README.md. It could have mentioned that this is a read-only operation, but the overall context is sufficient.

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

Parameters4/5

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

The tool has zero parameters and schema description coverage is effectively complete, so there is no parameter gap. The description adds semantic value by precisely defining what is checked and how to interpret results, which is enough for zero-parameter tools.

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 ('Report') and a precise resource ('write privilege the connected role actually holds on any table'), enumerating the exact privilege types (INSERT/UPDATE/DELETE/TRUNCATE). This clearly distinguishes it from sibling tools like pg_run_query or pg_list_tables.

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 clear context for when the tool matters: when a non-empty result means the privilege layer is missing and the role 'should be locked down.' It implies it is the tool to check for dangerous write privileges, but it does not explicitly state when not to use it or compare to alternatives. Overall the intended usage is clear.

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

pg_describe_tableA

List the columns of a table: name, data type, nullability, and default, in column order.

ParametersJSON Schema
NameRequiredDescriptionDefault
schemaNopublic
table_nameYes

TDQS

A3.8/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden and it is reasonably transparent. It states the returned column attributes and the column-order behavior, clearly implying a read-only schema-introspection operation. It does not discuss error cases or permission requirements, but the core invocation behavior is adequately disclosed.

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 that is front-loaded with the action, resource, and output details. Every clause adds useful information, and there is no repetition or unnecessary elaboration.

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

Completeness5/5

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

For a simple introspection tool with no output schema, the description fully specifies what the agent can expect to see (columns, data types, nullability, defaults, ordered) and what the tool does. The parameter semantics shortfall is already captured in the parameter dimension, so nothing needed for a correct invocation is missing here.

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

Parameters2/5

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

Schema description coverage is 0%, and the description does not compensate by explaining the parameters. It neither mentions the optional `schema` parameter (defaulting to `public`) nor clarifies that `table_name` is required and identifies the target table. The parameter names are self-evident, but the description adds almost no semantic value beyond them.

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 explicitly states the tool's specific action and resource: 'List the columns of a table: name, data type, nullability, and default, in column order.' It includes enough detail to distinguish it from siblings like pg_list_tables, which lists tables rather than describing columns.

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

Usage Guidelines2/5

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

The description does not provide explicit when-to-use or when-not-to-use guidance, nor does it mention alternative siblings such as pg_list_tables for discovering tables or pg_run_query for running arbitrary SQL. Usage context is only implicitly inferred from the tool name and purpose.

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

pg_explain_queryA

Return the PostgreSQL query plan for a read-only SELECT/WITH statement, without running it. Useful for checking whether a query will be slow before running it for real.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes

TDQS

A4.4/5.0
Behavior4/5

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

There are no annotations, so the description carries the full burden of explaining behavior. It explicitly says the operation is read-only, only accepts SELECT/WITH, and does not run the statement — which conveys the main safety implication. It does not detail the output format of the plan or possible changes to behavior for different statement types, but the critical behavioral facts are present.

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 long and every clause earns its place: the action, the input constraint, the non-execution behavior, and the purpose. No redundant or filler language exists.

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 one-parameter tool with no output schema, the description is mostly complete: it tells the agent what to pass, what limits apply, and what the tool will produce. It does not describe the exact structure or format of the returned plan, but 'PostgreSQL query plan' is sufficient for typical invocation.

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

Parameters4/5

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

Schema description coverage is 0%, so the description must add meaning to the sql parameter, and it does: it specifies that the sql must be a read-only SELECT/WITH statement. For a one-parameter tool, this is meaningful semantic guidance. It could go further on formatting or accepted statement variants, but the main constraint is covered.

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 clearly states the action ('Return the PostgreSQL query plan'), the target resource ('a read-only SELECT/WITH statement'), and the key behavior ('without running it'). This distinguishes it from pg_run_query and makes its purpose immediately obvious.

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 a concrete use case: 'checking whether a query will be slow before running it for real.' It implicitly contrasts with running the query, and the sibling list includes pg_run_query, so the intended context is clear. It does not explicitly say when not to use it or name the alternative tool, so it falls just short of a 5.

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

pg_list_tablesA

List the tables and views visible to the connected role in the given schema (default: public).

ParametersJSON Schema
NameRequiredDescriptionDefault
schemaNopublic

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations provided, the description carries the full behavioral disclosure burden. It clearly conveys read-only behavior through 'List' and reveals an important filtering trait: only objects 'visible to the connected role' are returned, which is more informative than merely repeating the tool name.

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?

Description is a single, front-loaded sentence with no wasted words. Each clause earns its place: action, target, visibility filter, and schema argument.

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, optional-parameter list tool with no output schema, the description is adequate for a correct call. It is concise but may not fully specify the exact output format; still, no critical contextual gaps remain.

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

Parameters4/5

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

While schema description coverage is 0%, the description explicitly explains what `schema` means ('given schema') and includes its default value, which aligns with the input schema. For a single optional parameter, this provides sufficient meaning for correct invocation.

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 clearly states a specific verb ('List') and resource ('tables and views'), with the scoping qualifier ('visible to the connected role') and the optional schema argument. This immediately distinguishes it from sibling tools like pg_describe_table and pg_run_query.

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 conveys when one would use this tool—when the agent needs to enumerate the tables and views the current role can access in a schema—by 'given schema (default: public)'. However, it does not explicitly compare against alternatives or state when not to use it, so some usage inference is still required.

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

pg_run_queryA

Run a single read-only SQL statement (SELECT / WITH / EXPLAIN / SHOW) against the configured PostgreSQL database and return the rows.

Rejects anything that isn't exactly one plain read-only statement — multiple statements, transaction-control keywords (COMMIT, ROLLBACK, BEGIN, ...), and any write/DDL/admin keyword anywhere in the query are all refused before the query is sent to the database. Results are capped at PG_GUARD_ROW_LIMIT rows (default 1000).

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes

TDQS

A3.8/5.0
Behavior4/5

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

With no annotations present, the description carries the behavioral burden and does it well. It discloses that multiple statements, transaction-control keywords, and write/DDL/admin keywords are blocked before execution, and that results are capped at PG_GUARD_ROW_LIMIT. It lacks detail on error behavior and the exact return shape, but the main safety characteristics are clear.

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 concise and front-loaded: the first sentence states the purpose and acceptable statement types, the second provides restrictions and the row cap. No unnecessary information or filler is present, and each sentence earns its place.

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

Completeness3/5

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

Given there is no output schema or annotations, the description should more precisely describe the returned data layout, such as whether rows are returned as arrays with column headers or as objects. It also does not mention error handling when a query is rejected or when the row limit is exceeded. These are meaningful gaps for a tool without an output schema.

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

Parameters4/5

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

The schema has 0% description coverage, so the description must compensate for the 'sql' parameter. It explains what kinds of SQL are accepted and what is rejected, which adds meaningful semantics beyond the bare string type. It could still be more explicit about formatting requirements (e.g., single statement, no trailing semicolons), but the core meaning is well communicated.

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 clearly states the operation: run a single read-only SQL statement (SELECT/WITH/EXPLAIN/SHOW) against the configured PostgreSQL database and return the rows. It gives a specific verb and resource, but it does not explicitly differentiate from the sibling tools, especially pg_explain_query, which overlaps on the EXPLAIN capability.

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 appropriate usage—single read-only SQL queries—and documents strong restrictions, but it never names alternatives or explains when to use pg_explain_query, pg_list_tables, pg_check_privileges, or pg_describe_table instead. The overlap of EXPLAIN support with pg_explain_query leaves some ambiguity.

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 observedpg_check_privileges
    • First observedpg_describe_table
    • First observedpg_explain_query
    • First observedpg_list_tables
    • First observedpg_run_query

TDQS

A4.3/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clearly distinct role: executing read-only queries, explaining query plans, listing tables, describing table schemas, and checking write privileges. There is no functional overlap or ambiguity between them.

Naming Consistency5/5

All tool names follow the same pg_ prefix with a consistent verb_noun pattern: run_query, explain_query, list_tables, check_privileges, describe_table. The naming is uniform and predictable.

Tool Count5/5

Five tools is well-scoped for a PostgreSQL guard/observer server. Each tool serves a clear, non-redundant purpose and the set feels complete without being bloated.

Completeness5/5

The tool surface covers the core read-only workflow: exploring available tables, inspecting schemas, validating query plans, running queries, and verifying the security posture. No obvious dead ends or missing security-relevant operations are apparent.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables secure read-only access to PostgreSQL databases through SELECT queries only, with tools for exploring schemas, listing tables, and executing common queries while preventing any data modification operations.
    889 npm
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides secure, read-only access to PostgreSQL databases for schema inspection and data querying. It enables users to list tables, describe structures, and execute SELECT statements while strictly blocking destructive operations.
    8 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables safe interaction with PostgreSQL databases through read-only queries, schema exploration, and performance analysis.
    161 npm
    MIT