Skip to content

feat(mcp): add basic_memory_diagnostics tool for version and system info#963

Open
groksrc wants to merge 4 commits into
mainfrom
feat/187-diagnostics-tool
Open

feat(mcp): add basic_memory_diagnostics tool for version and system info#963
groksrc wants to merge 4 commits into
mainfrom
feat/187-diagnostics-tool

Conversation

@groksrc

@groksrc groksrc commented Jun 11, 2026

Copy link
Copy Markdown
Member

Closes #187

Summary

Implements the basic_memory_diagnostics MCP tool requested in issue #187, following the converged requirements from the comment thread.

What changed:

  • Added src/basic_memory/mcp/tools/basic_memory_diagnostics.py — a new read-only MCP tool that surfaces:
    • Basic Memory version (__version__ and __api_version__)
    • Python version and platform details
    • Config file path and contents, with cloud_api_key redacted
  • Registered the tool in src/basic_memory/mcp/tools/__init__.py (import + __all__ entry)
  • Added tests in tests/mcp/tools/test_basic_memory_diagnostics.py covering the happy path and the redaction behavior

Design decisions per issue thread:

  • Tool name is basic_memory_diagnostics (renamed from the earlier draft name per reviewer request)
  • Tool listing was intentionally omitted per reviewer feedback
  • Tool is strictly read-only; no writes or side effects

How it was tested

  • Unit tests added alongside the implementation; all pass via uv run pytest tests/mcp/tools/test_basic_memory_diagnostics.py
  • Manually verified the tool is registered and appears in MCP tool enumeration

Review notes

  • src/basic_memory/mcp/tools/basic_memory_diagnostics.py recomputes the config path as manager.config_dir / CONFIG_FILE_NAME, but ConfigManager already exposes self.config_file (config.py:825) which is the same value. Using manager.config_file would be marginally cleaner, though the current form is correct and arguably clearer about what file it reads.
  • The import for basic_memory_diagnostics in src/basic_memory/mcp/tools/__init__.py is appended at the end of the import block (after the schema tools) rather than grouped alphabetically with the other tool imports. Purely cosmetic; the __all__ list itself is correctly alphabetized.
  • The except Exception branch in the tool (malformed config JSON) is marked # pragma: no cover and is not exercised by a test. Low risk since it is defensive, but a malformed-JSON test would close the gap.

🤖 Generated with Claude Code

Adds a new read-only MCP tool `basic_memory_diagnostics` that surfaces:
- Basic Memory package version and API version (from __init__.py)
- Python version and platform/architecture details
- Config file path and full config.json contents (cloud_api_key redacted)

Resolves #187.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Drew Cain <groksrc@gmail.com>
@groksrc groksrc marked this pull request as ready for review June 11, 2026 07:27

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 29be0299f0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

from basic_memory.mcp.server import mcp

# Fields in BasicMemoryConfig that contain secrets and must never be surfaced.
_SECRET_FIELDS = frozenset({"cloud_api_key"})

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Redact database credentials from diagnostics

When config.json contains database_url for a Postgres deployment, BasicMemoryConfig allows URLs with user:pass@host, but this tool only removes cloud_api_key and then dumps the remaining config. In that scenario, calling basic_memory_diagnostics exposes the database password to any MCP client or copied support transcript; redact database_url or at least strip URI userinfo before serializing the config.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — this was a real gap. Fixed in cbc2d5f.

What changed:

  • Added _redact_url() helper that strips the user:password userinfo component from a URL using urlparse/urlunparse, leaving host, port, and database name intact for diagnostic value.
  • Added _URL_FIELDS = frozenset({"database_url"}) alongside the existing _SECRET_FIELDS, so future credential-bearing URL fields are easy to add.
  • _redact_config() now routes URL fields through _redact_url() rather than dropping them entirely.

Tests added: _redact_url unit tests (password stripped, port/host preserved, no-credential URL unchanged, non-URL path unchanged), _redact_config tests for database_url, and an end-to-end test_diagnostics_redacts_database_url_password that confirms a Postgres password never surfaces in the full diagnostic output.

Extends the existing _SECRET_FIELDS redaction to also strip the
user:password userinfo component from any URL-bearing config fields
(database_url) before surfacing them in diagnostics output. Adds
_redact_url() helper and a _URL_FIELDS set so future credential-bearing
URL fields are easy to add. Postgres passwords no longer leak to MCP
clients or support transcripts; host/port/db-name remain visible.

Fixes the P1 security finding raised in review of PR #963.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Drew Cain <groksrc@gmail.com>
Comment thread tests/mcp/test_tool_basic_memory_diagnostics.py Fixed
Comment thread tests/mcp/test_tool_basic_memory_diagnostics.py Fixed
groksrc and others added 2 commits June 11, 2026 09:42
CodeQL flags dotted-host substring checks against URLs
(py/incomplete-url-substring-sanitization); exact matches are also
stronger assertions.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Drew Cain <groksrc@gmail.com>
…d structured output

- Remove orphaned __api_version__ ('v0' since 2025; real API routes are /v2,
  and nothing else reads the constant)
- output_schema=None so FastMCP doesn't duplicate the markdown report into
  structuredContent (halves the payload)
- Add title/tags annotations so #963 and #968 are merge-order independent

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Drew Cain <groksrc@gmail.com>
@groksrc groksrc added the On Hold Don't review or merge. Work is pending label Jun 12, 2026
@groksrc

groksrc commented Jun 12, 2026

Copy link
Copy Markdown
Member Author

This is tested and good to go, but needs to ship in v0.next and we have a maintenance release ahead of it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

On Hold Don't review or merge. Work is pending

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Add diagnostic tool for version and system information

2 participants