Skip to main content

Ephemeral Buffer MCP Server (ephemeral-buffer)

CI

An ephemeral in-memory command output capture and hybrid search engine (BM25 + Semantic Embeddings) for AI coding assistants (Claude Code, Antigravity, Cursor, etc.).


🎯 The Problem This Solves

When coding agents run commands that generate large outputs (thousands of lines of build logs, test runs, stack traces, JSON dumps), agents face two failure modes:

  1. Context Pollution: Ingesting megabytes of raw text blows out token limits and degrades model reasoning.
  2. Blind Bash Filtering: Agents waste multiple turns running head, tail, grep, and awk trying to guess error patterns.

💡 The Solution

ephemeral-buffer provides a transient in-memory ring buffer with Dual Hybrid Indexing and Content-Aware Structure Parsing:

  • BM25 Lexical Search (SQLite FTS5): For exact matches on error codes (NullPointerException, ECONNREFUSED, exit 137, HTTP 502).
  • Dense Semantic Vector Search (FastEmbed ONNX): For fuzzy conceptual queries ("Where did the DB connection pool fail?" or "Why did authentication fail?").
  • Unified Diff Structural Mapping: Automatically detects git diffs and PR diffs (gh pr diff, git show, git diff), parses modified files, additions/deletions, and generates a line-indexed file map in the summary.
  • Smart Signal Filtering: Scans command/build/test logs for diagnostic keywords, suppresses false positives in diffs and source code, and accurately captures test runner failures, unhandled exceptions, and merge conflicts. Use content_type='log' when a plain-text capture should be signal-scanned.
  • Successful test-run summaries such as OK or 25 passed suppress fixture-only error and failure keywords while retaining the original output for search.
  • Reciprocal Rank Fusion (RRF): Blends lexical and semantic ranking for high precision retrieval.
  • LRU Capture Eviction: Holds up to 25 captures and 50 MiB of captured content by default, evicting the least recently used captures when either limit is reached.
  • Thread-Safe Shared Engine: Serializes ingestion, search, LRU updates, eviction, and cleanup across MCP requests and CLI socket clients.

🏗 Architecture & Flow

flowchart TD
    subgraph Ingestion["1. Ingestion Paths"]
        A["CLI Pipe: command 2>&1 | ephbuf"] --> D["Unix Socket (platform temp dir)"]
        B["Agent Tool: execute_and_capture(cmd)"] --> E["Ephemeral Ring Buffer Engine"]
        C["Agent Tool: capture_text / capture_file"] --> E
        D --> E
    end

    subgraph Indexing["2. Dual Hybrid Indexing & Classification"]
        E --> F["SQLite FTS5 (BM25 Lexical)"]
        E --> G["FastEmbed ONNX (Dense Vectors)"]
        E --> K["Diff & Signal Parser (File Maps & Conflict Detection)"]
    end

    subgraph Querying["3. Agent Query & Retrieval"]
        F & G --> H["Reciprocal Rank Fusion (RRF)"]
        H --> I["search_capture(query, mode='hybrid')"]
        K --> L["Diff File Map & get_capture_slice"]
        I --> J["Precise Context Chunk + Line Numbers"]
    end

🚀 How to Use It

1. From the Terminal (CLI Pipe via ephbuf)

You can pipe command output directly into the running MCP server:

# Pipe any command output into the buffer
pytest -v 2>&1 | ephbuf --label "pytest run"

# Pipe git diffs directly
git diff HEAD~3 | ephbuf --label "feature diff" --type diff

# Or wrap command execution
ephbuf --label "backend build" -- cargo build --verbose

The optional --type/-t hint accepts auto (the default), diff, log, or text. Use diff for unified patches when automatic detection is ambiguous; otherwise auto classifies diffs, build/test logs, and plain text from the content and label.

ephbuf also bounds wrapped-command and piped-stdin capture with --max-output-bytes; it defaults to EPHEMERAL_MAX_BUFFER_BYTES or 50 MiB and retains the beginning and end of oversized output. Use --timeout-seconds to stop a wrapped command after a bounded runtime; timed out commands retain the output collected so far and exit with status 124. Requested max_output_bytes and capture_file max_bytes values may not exceed the configured buffer byte limit; the tools return a validation error instead of silently clamping them.

2. From the AI Agent via MCP Tools

The agent has access to the following tools:

Tool Purpose
execute_and_capture(command, cwd, label, content_type='auto', max_output_bytes=None, timeout_seconds=None) Executes a shell command with bounded head/tail capture, optional timeout, and a compact diagnostic summary (exit code, diff file map, error signals, and truncation status) to the agent context.
capture_text(content, label, content_type='auto') Ingests text directly into the buffer.
capture_file(file_path, label, content_type='auto', max_bytes=None) Ingests a bounded log/output file from disk; defaults to the configured buffer byte limit.
search_capture(query, mode, top_k, context_lines) Hybrid/BM25/Semantic search over the captured output. Returns matching chunks with surrounding context lines and exact line numbers.
get_capture_slice(start_line, end_line) Retrieves exact line ranges to inspect full stack traces, logs, or specific diff files.
get_capture_summary(capture_id) Diagnostic overview (line counts, diff file maps, error signals, preview).
get_buffer_stats() Reports aggregate capture count, content bytes, lines, chunks, embedding model readiness, embedding bytes, accounted bytes, and process RSS.
get_runtime_diagnostics() Opt-in, content-free report of runtime version, platform, uptime, socket mode, buffer limits, embedding readiness, and process memory.
list_captures() Lists active captures in the ring buffer.
clear_captures(capture_id) Clears buffer.

For diff captures, get_capture_summary reports the detected file map, addition/deletion statistics, line ranges, and merge-conflict signals. Use get_capture_slice with those ranges to retrieve the complete file context.

3. Capture Hygiene

Keep captures focused so search results remain useful and the agent receives only the context it needs:

  • Capture one command or related output stream at a time, using a descriptive label.
  • Start with get_capture_summary, then use search_capture or get_capture_slice for targeted retrieval instead of repeatedly recapturing the same output.
  • Use clear_captures(capture_id) when a capture is no longer needed; use clear_captures("all") between unrelated investigations.

The buffer is intentionally transient and bounded by the LRU capture limit, but explicit cleanup prevents recent investigations from obscuring the active one before automatic eviction occurs. Its memory metrics separate captured content and embedding bytes from process RSS; the unaccounted RSS value includes model, index, and Python object overhead and is approximate.

The server defaults can be overridden with EPHEMERAL_MAX_CAPTURES and EPHEMERAL_MAX_BUFFER_BYTES. Session-aware launchers can set EPHEMERAL_SESSION_ID so each server/CLI pair automatically derives a unique socket path; EPHEMERAL_SOCKET_PATH remains an explicit override. The byte limit accounts for captured UTF-8 content; get_buffer_stats also reports embedding model readiness, embedding/cache settings, and process memory separately. execute_and_capture retains the beginning and end of oversized command output and marks the capture with its original byte count.

Call get_runtime_diagnostics() when reporting a field observation. It is explicitly opt-in and returns operational metadata only; captured content, labels, command arguments, and session ID values are excluded. Sanitize any additional output before sharing it.

Operational events are written as privacy-safe JSON lines to stderr. Warnings and errors are enabled by default; set EPHEMERAL_LOG_LEVEL=INFO to include normal readiness, eviction, and process lifecycle events. Logs never include captured content or command text.

See OPERATIONS.md for deployment settings, troubleshooting, release verification, and repository maintenance procedures.


🛠 Testing the Server

Set up a local development environment from a fresh checkout:

python3.12 -m venv .venv
.venv/bin/python -m pip install --require-hashes -r requirements-dev-lock-py312.txt

The committed requirements-dev-lock-py312.txt file is the reproducible Python 3.12 development and release environment. Python 3.10 remains supported through the direct requirements and tested constraints.txt file; the CI matrix exercises both paths. Keep requirements.txt and requirements-dev.txt as the reviewable dependency inputs, and regenerate the Python 3.12 locks with pip-tools after an intentional dependency update:

.venv/bin/python -m pip install pip-tools
.venv/bin/pip-compile --generate-hashes --output-file=requirements-lock-py312.txt requirements.txt
.venv/bin/pip-compile --generate-hashes --output-file=requirements-dev-lock-py312.txt requirements-dev.txt

Review the resulting changes, run the full test matrix, and run pip-audit before merging. Downstream users install the package normally; its compatible dependency ranges in pyproject.toml are intentionally not replaced by the development locks.

Run the test suite:

.venv/bin/python -m unittest test_engine.py test_capture_utils.py test_config.py test_cli.py test_server.py
.venv/bin/python -m unittest test_e2e_pipe.py

Measure focused-test coverage locally:

.venv/bin/python -m coverage run --source=. --omit='test_*.py,benchmark_concurrency.py,release_checks.py' -m unittest test_benchmark_concurrency.py test_release_checks.py test_engine.py test_capture_utils.py test_config.py test_cli.py test_server.py
.venv/bin/python -m coverage report

The current focused-test baseline is 91%; CI enforces a 91% minimum after adding coverage for defensive command, limit, cleanup, embedding, and socket handling paths. Coverage reports are uploaded for inspection, and future threshold increases should follow similarly targeted test additions. The release guardrail utility is measured separately because it is a workflow utility rather than application runtime code:

COVERAGE_FILE=.coverage.release .venv/bin/python -m coverage run --source=. -m unittest test_release_checks.py
COVERAGE_FILE=.coverage.release .venv/bin/python -m coverage report --include='release_checks.py'

GitHub Actions runs the compile check, focused tests, and end-to-end test on Python 3.10 and 3.12 for pushes to main and pull requests. The FastEmbed model is loaded on the first capture or semantic search rather than during server import. Set EPHEMERAL_EMBEDDING_MODEL to select a compatible model and EPHEMERAL_FASTEMBED_CACHE_DIR to control its cache directory. The model cache is retained between CI runs to reduce startup time. CI unit and end-to-end tests set the internal EPHEMERAL_TEST_EMBEDDINGS=1 flag, which uses a small deterministic embedding substitute so test execution does not depend on a model download; release and benchmark jobs continue to exercise FastEmbed. It also builds the wheel and verifies the installed ephbuf entry point. CI audits the declared dependencies with pip-audit and fails if known vulnerabilities are found. CI installs the hashed Python 3.12 development/runtime locks and uses the tested constraints.txt path for Python 3.10. The direct requirements and constraints are updated only after the full test matrix passes; lock updates must be reviewed together with their resolver output and audit results.

Pushing a version tag such as v0.1.1 runs the release workflow, which first verifies that the tag is valid SemVer, points to a commit contained in the default branch, and starts from a clean checkout. It also requires the tag, pyproject.toml, and a dated matching CHANGELOG.md section to agree. The workflow then builds wheel and source distributions, validates their metadata, verifies the installed package, and uploads the artifacts for review. A failed guardrail reports the mismatched value or source-state problem before building. The workflow creates a GitHub Release using the matching changelog section, attaches the wheel, source distribution, and SHA256SUMS, and links back to the workflow run containing the build-provenance attestation. Verify a downloaded artifact with sha256sum --check SHA256SUMS from the directory containing the files. The same verified distributions are then published to PyPI through trusted publishing. After the repository's pypi environment is configured with a PyPI trusted publisher, the workflow publishes the distributions to PyPI automatically.

Run the concurrency benchmark:

.venv/bin/python benchmark_concurrency.py --captures 32 --workers 8

The benchmark accepts --min-ingest-per-second and --min-reads-per-second thresholds for direct checks. For repeatable regression checks, pass --baseline benchmark_baseline.json --output benchmark-concurrency.json. The checked-in baseline uses a 20% tolerance: a run fails only when ingest or read throughput drops below 80% of its baseline. Each scheduled or manually dispatched GitHub Actions run records the raw JSON result as an artifact and adds the measurements and regression status to the workflow summary. This benchmark remains optional and is not part of the required pull-request checks; update the baseline deliberately when the runner or benchmark workload changes.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ephemeral_buffer_mcp-0.1.2.tar.gz (34.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ephemeral_buffer_mcp-0.1.2-py3-none-any.whl (32.0 kB view details)

Uploaded Python 3

File details

Details for the file ephemeral_buffer_mcp-0.1.2.tar.gz.

File metadata

  • Download URL: ephemeral_buffer_mcp-0.1.2.tar.gz
  • Upload date:
  • Size: 34.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ephemeral_buffer_mcp-0.1.2.tar.gz
Algorithm Hash digest
SHA256 aba55fe5f2b894490df89f25b9295f6a6c17a4bc3e3e521eb8eca40c048e1d5c
MD5 4439161060a0eb19cdea7585019386c3
BLAKE2b-256 0a3eab52eaf0fafbeb5825d093076a59005e93977346cec297ff0366c28b9417

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemeral_buffer_mcp-0.1.2.tar.gz:

Publisher: release.yml on k-rister/ephemeral-buffer-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ephemeral_buffer_mcp-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for ephemeral_buffer_mcp-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 868eb1c3c2a93d4dd7eb526f9384768f927a90fc2fa8e17294c7e390706614bd
MD5 5140a92633b6a73a931b4a7fe41b8344
BLAKE2b-256 82d09a800b6b81094eff5dd2db78e94599a7afe50e4348ae39075be0ff5038ae

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemeral_buffer_mcp-0.1.2-py3-none-any.whl:

Publisher: release.yml on k-rister/ephemeral-buffer-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.2.0

2 files

This release

0.1.2 This release

2 files

0.1.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page