Ephemeral Buffer MCP Server (ephemeral-buffer)
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:
- Context Pollution: Ingesting megabytes of raw text blows out token limits and degrades model reasoning.
- Blind Bash Filtering: Agents waste multiple turns running
head,tail,grep, andawktrying 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, HTTP502). - 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
OKor25 passedsuppress 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. |
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 usesearch_captureorget_capture_slicefor targeted retrieval instead of repeatedly recapturing the same output. - Use
clear_captures(capture_id)when a capture is no longer needed; useclear_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.
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 -m venv .venv
.venv/bin/python -m pip install -r requirements-dev.txt
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' -m unittest 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 82%; CI enforces an 82% minimum and uploads the coverage reports for inspection.
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.
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 resolves the runtime dependencies through constraints.txt; the direct
pins are updated only after the full test matrix passes.
Pushing a version tag such as v0.1.1 runs the release workflow, which builds
wheel and source distributions, validates their metadata, verifies the
installed package, and uploads the artifacts for review. The tag must match
the version in pyproject.toml.
The workflow also uploads SHA256SUMS; verify a downloaded artifact with
sha256sum --check SHA256SUMS from the directory containing the files.
Release distributions also receive a GitHub build-provenance attestation.
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 regression checks. GitHub Actions runs it as an optional weekly
or manually dispatched job and uploads the results; it is not part of the
required pull-request checks.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ephemeral_buffer_mcp-0.1.1.tar.gz.
File metadata
- Download URL: ephemeral_buffer_mcp-0.1.1.tar.gz
- Upload date:
- Size: 29.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8579b76d85fb29cf73d459ff4ea1680ed80f30ce307847a3ceaae9858db37512
|
|
| MD5 |
9fc4c23dfa9b829185fe35c8aa8a2f6b
|
|
| BLAKE2b-256 |
e834929e39fa7a3d2950a6aad6fa23a48148b67ddae9cd73c57538db36a62c10
|
Provenance
The following attestation bundles were made for ephemeral_buffer_mcp-0.1.1.tar.gz:
Publisher:
release.yml on k-rister/ephemeral-buffer-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ephemeral_buffer_mcp-0.1.1.tar.gz -
Subject digest:
8579b76d85fb29cf73d459ff4ea1680ed80f30ce307847a3ceaae9858db37512 - Sigstore transparency entry: 2727295418
- Sigstore integration time:
-
Permalink:
k-rister/ephemeral-buffer-mcp@dfc307eb845edcf66e38d98228c5347d912d32e7 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/k-rister
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@dfc307eb845edcf66e38d98228c5347d912d32e7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ephemeral_buffer_mcp-0.1.1-py3-none-any.whl.
File metadata
- Download URL: ephemeral_buffer_mcp-0.1.1-py3-none-any.whl
- Upload date:
- Size: 27.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3f0ab07001d4a119b504842dbcec900fd4992bde3ccc8af0c10e1d7f18470a1a
|
|
| MD5 |
4e0475858321084a252ce63f2388ffb6
|
|
| BLAKE2b-256 |
7ba556ef457031620de8df0de363fdad56da9000133c15b91c6f2dde247e3914
|
Provenance
The following attestation bundles were made for ephemeral_buffer_mcp-0.1.1-py3-none-any.whl:
Publisher:
release.yml on k-rister/ephemeral-buffer-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ephemeral_buffer_mcp-0.1.1-py3-none-any.whl -
Subject digest:
3f0ab07001d4a119b504842dbcec900fd4992bde3ccc8af0c10e1d7f18470a1a - Sigstore transparency entry: 2727296582
- Sigstore integration time:
-
Permalink:
k-rister/ephemeral-buffer-mcp@dfc307eb845edcf66e38d98228c5347d912d32e7 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/k-rister
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@dfc307eb845edcf66e38d98228c5347d912d32e7 -
Trigger Event:
push
-
Statement type: