How to Check PostgreSQL WAL Status Using the mcp-postgresql-ops Tool

The get_wal_status tool aggregates current WAL position, archiving statistics, and configuration settings from PostgreSQL into a formatted report using three targeted SQL queries.

The call518/mcp-postgresql-ops repository provides a Model Context Protocol (MCP) server for PostgreSQL operational tasks. Its get_wal_status tool offers comprehensive visibility into Write-Ahead Log activity, helping DBAs monitor replication health and disk usage without manual SQL execution.

What WAL Information Does get_wal_status Provide?

The tool, implemented in src/mcp_postgresql_ops/mcp_main.py (lines 37-71), issues three distinct queries against PostgreSQL. It combines the results into a single formatted string with clearly labeled sections.

Current WAL Position and Generation

This query uses pg_current_wal_lsn() to determine the Log Sequence Number (LSN) and calculates megabytes generated since startup. It also determines whether the instance is a primary or standby using pg_is_in_recovery().

Key columns include current_wal_lsn, wal_mb_generated, server_role, and in_recovery.

Archiving Statistics

Data is retrieved from pg_stat_archiver to track WAL file archival success and failures. This reveals whether your archive command is keeping pace with WAL generation.

Key columns include archived_count, last_archived_wal, last_archived_time, failed_count, and last_failed_time.

WAL Configuration Settings

The tool queries pg_settings for critical parameters that control WAL behavior. This includes wal_level, archive_mode, archive_command, max_wal_size, min_wal_size, checkpoint_segments, checkpoint_completion_target, and wal_buffers.

Each setting includes its current value and unit of measurement.

Implementation Architecture

Query Execution and Formatting

The execute_query function in src/mcp_postgresql_ops/functions.py establishes an asyncpg connection, executes the SQL, and converts results to dictionaries. The format_table_data helper then transforms raw bytes and duration columns into human-readable strings (e.g., converting bytes to megabytes).

Version Compatibility

While get_wal_status uses stable PostgreSQL functions, the repository includes a version-aware layer in src/mcp_postgresql_ops/version_compat.py. The VersionAwareQueries.get_wal_receiver_query method adapts to PostgreSQL 16+ columns (written_lsn, flushed_lsn) versus older versions. This is utilized by the separate get_replication_status tool, which complements get_wal_status by providing WAL receiver metrics on standby servers.

Read-Only Design

The tool deliberately performs only read operations. The implementation explicitly excludes write or control actions such as pg_switch_wal(), which are documented as prohibited use cases in the function docstring.

How to Query WAL Status

Direct Python Async Call

from mcp_postgresql_ops.mcp_main import get_wal_status

async def show_wal():
    info = await get_wal_status()
    print(info)

# In an async context:

# await show_wal()

MCP Server HTTP Endpoint


# Assuming the MCP server is running and exposes the tool via HTTP:

curl -X POST http://localhost:8000/tools/get_wal_status

The response contains the formatted text with three labeled sections.

Accessing Raw Data Programmatically

To bypass formatting and access raw rows, reuse the underlying queries through execute_query:

from mcp_postgresql_ops.functions import execute_query

async def wal_raw():
    # Current WAL position

    wal_info = await execute_query("""
        SELECT pg_current_wal_lsn() AS current_wal_lsn,
               pg_wal_lsn_diff(pg_current_wal_lsn(), '0/0')/1024/1024 AS wal_mb_generated,
               CASE WHEN pg_is_in_recovery() THEN 'Recovery (Standby)' ELSE 'Primary' END AS server_role,
               pg_is_in_recovery() AS in_recovery
    """)

    # Archiver stats

    archiver = await execute_query("""
        SELECT archived_count, last_archived_wal, last_archived_time,
               failed_count, last_failed_wal, last_failed_time, stats_reset
        FROM pg_stat_archiver
    """)

    # WAL config

    config = await execute_query("""
        SELECT name, setting, unit
        FROM pg_settings
        WHERE name IN ('wal_level','archive_mode','archive_command',
                       'max_wal_size','min_wal_size','checkpoint_segments',
                       'checkpoint_completion_target','wal_buffers')
        ORDER BY name
    """)
    return wal_info, archiver, config

Combining with Replication Status

For a complete WAL health check including standby receiver statistics:

from mcp_postgresql_ops.mcp_main import get_wal_status, get_replication_status

async def wal_and_replication():
    print(await get_wal_status())
    print("\n---\n")
    print(await get_replication_status())   # includes WAL receiver info on a standby

Summary

  • The get_wal_status tool aggregates three data groups: current WAL position, archiving statistics, and configuration parameters.
  • Implementation resides in src/mcp_postgresql_ops/mcp_main.py (lines 37-71), utilizing execute_query and format_table_data from src/mcp_postgresql_ops/functions.py.
  • The tool is read-only and does not perform write operations like pg_switch_wal().
  • For standby servers, pair this tool with get_replication_status to view WAL receiver progress via version-aware queries in src/mcp_postgresql_ops/version_compat.py.
  • Results are automatically formatted for human readability, converting byte counts and durations into readable units.

Frequently Asked Questions

What is the difference between get_wal_status and get_replication_status?

get_wal_status focuses on the local instance's WAL generation, archival success, and configuration. get_replication_status provides replication connection details and, crucially, WAL receiver statistics on standby servers (using VersionAwareQueries.get_wal_receiver_query to handle PostgreSQL version differences). Use both tools together for complete streaming replication monitoring.

Can I use get_wal_status to force WAL rotation or archiving?

No. The tool is explicitly designed as read-only. According to the docstring in src/mcp_postgresql_ops/mcp_main.py, write or control actions such as executing pg_switch_wal() are prohibited use cases. You must connect to PostgreSQL directly with appropriate privileges to perform manual WAL switches.

Does get_wal_status work with all PostgreSQL versions?

The tool relies on standard PostgreSQL functions like pg_current_wal_lsn() and pg_stat_archiver that are stable across recent versions. The repository specifically handles version differences for advanced features; for example, src/mcp_postgresql_ops/version_compat.py adapts WAL receiver queries for PostgreSQL 16+ column names (written_lsn, flushed_lsn) when used with get_replication_status.

How does the tool format large byte values and timestamps?

The format_table_data function in src/mcp_postgresql_ops/functions.py automatically detects columns ending in _bytes or _size and converts them to human-readable units (MB, GB). It similarly formats duration and timestamp columns for readability, ensuring the output requires no additional post-processing.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →