Skip to content

feat(cli): focused command surface, docker convenience commands, and … - #110

Merged
Lyellr88 merged 3 commits into
MARM-mainfrom
release/v2.28.0
Jul 24, 2026
Merged

feat(cli): focused command surface, docker convenience commands, and …#110
Lyellr88 merged 3 commits into
MARM-mainfrom
release/v2.28.0

Conversation

@Lyellr88

@Lyellr88 Lyellr88 commented Jul 24, 2026

Copy link
Copy Markdown
Owner

v2.28.0

Add a complete marm-memory product command surface and split the growing cli.py into focused service modules with no behavior change.

  • Docker convenience commands (pull/run/command/compose/status/logs/stop, embeddings migrate) with a pure planning vs execution split.
  • Complete command and usability pass: fast-start-http, key management, upgrade/uninstall lifecycle, and a hybrid grouped help layout that surfaces common flags inline and separates managed lifecycle from foreground transports.
  • Authenticated Console handoff via console --import-key (single-use fragment bootstrap token, HttpOnly SameSite=strict session cookie).
  • Internal: extract docker_cli, docker_commands, key_management, package_management, product_help, product_logs, product_workflows, projects_cli, and console/auth from cli.py.

Summary by CodeRabbit

  • New Features
    • Added a product Docker command suite (status/run/command/compose/stdio/logs/stop) plus embedding migration, fast-start HTTP, and STDIO/HTTP transport routing/aliases.
    • Added managed key lifecycle with enhanced upgrade/update/uninstall flows and safety/preview options.
    • Added authenticated Console handoff for managed sessions via one-time bootstrap tokens and import-key.
  • Documentation
    • Updated READMEs and install/runtime guides to v2.28.0; expanded runtime CLI and Docker HTTP documentation; removed the roadmap document.
  • Bug Fixes
    • Improved same-origin browser credential behavior for Console API requests and strengthened Console bootstrap/session auth handling.

…authenticated console handoff (v2.28.0)

Add a complete marm-memory product command surface and split the growing
cli.py into focused service modules with no behavior change.

- Docker convenience commands (pull/run/command/compose/status/logs/stop,
  embeddings migrate) with a pure planning vs execution split.
- Complete command and usability pass: fast-start-http, key management,
  upgrade/uninstall lifecycle, and a hybrid grouped help layout that
  surfaces common flags inline and separates managed lifecycle from
  foreground transports.
- Authenticated Console handoff via console --import-key (single-use
  fragment bootstrap token, HttpOnly SameSite=strict session cookie).
- Internal: extract docker_cli, docker_commands, key_management,
  package_management, product_help, product_logs, product_workflows,
  projects_cli, and console/auth from cli.py.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d55f70df-6a2e-41d8-9eb0-5a25d2cf908c

📥 Commits

Reviewing files that changed from the base of the PR and between 075869b and f12db5b.

📒 Files selected for processing (1)
  • scripts/test-scripts/docker-linux-bind-mount-smoke.sh
📜 Recent review details
⚠️ CI failures not shown inline (1)

GitHub Check: GitGuardian Security Checks: 1 secret uncovered!

Conclusion: failure

View job details

#### 1 secret were uncovered from the scan of 3 commits in your pull request. ❌
Please have a look to GitGuardian findings and remediate in order to secure your code.
### 🔎 Detected hardcoded secrets in your pull request
-   Pull request `#110`: `release/v2.28.0` 👉 `MARM-main`
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
| -------------- | ------------------ | ------ | ------ | -------- | ---- |
| [35147140](https://dashboard.gitguardian.com/workspace/716835/incidents/35147140?occurrence=283335286) | Triggered | Generic High Entropy Secret | 075869bffe362e2b0688db30d47989366e492f99 | scripts/test-scripts/docker-linux-bind-mount-smoke.sh | [View secret](https://github.com/Lyellr88/marm-memory/commit/075869bffe362e2b0688db30d47989366e492f99#diff-a15048ee98e09c9f6398f803bab1751cd543f8ca3b20539708493f52c8c1f36cR8) |
### 🛠 Guidelines to remediate hardcoded secrets
1. Understand the implications of revoking this secret by investigating where it is used in your code.
2. Replace and store your secret safely. [Learn here](https://blog.gitguardian.com/secrets-api-management?utm_source=product&amp;utm_medium=GitHub_checks&amp;utm_campaign=check_run) the best practices.
3. Revoke and [rotate this secret](https://docs.gitguardian.com/secrets-detection/secrets-detection-engine/detectors/generics/generic_high_entropy_secret#revoke-the-secret?utm_source=product&amp;utm_medium=GitHub_checks&amp;utm_campaign=check_run).
4. If possible, [rewrite git history](https://blog.gitguardian.com/rewriting-git-history-cheatsheet?utm_source=product&amp;utm_medium=GitHub_checks&amp;utm_campaign=check_run). Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
-   following these [best practices](https://blog.gitguardian.com/secrets-api-management/?utm_source=product&amp;utm_medium=GitHub_checks&amp;utm_campaign=ch...
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: Lyellr88/marm-memory

Timestamp: 2026-07-24T03:40:27.562Z
Learning: Never commit changes without an explicit user request.
Learnt from: CR
Repo: Lyellr88/marm-memory

Timestamp: 2026-07-24T03:40:27.562Z
Learning: Use SemVer: MAJOR for breaking changes, MINOR for new tools, parameters, or features, and PATCH for fixes and documentation updates.
🪛 Shellcheck (0.11.0)
scripts/test-scripts/docker-linux-bind-mount-smoke.sh

[warning] 8-8: Declare and assign separately to avoid masking return values.

(SC2155)

🔇 Additional comments (1)
scripts/test-scripts/docker-linux-bind-mount-smoke.sh (1)

8-8: Preserve API-key generation failures.

readonly api_key="$(...)" masks the command substitution’s exit status. If python3 or key generation fails, the script can continue with an empty key and produce a misleading smoke-test result. Declare and assign separately, as previously reported for this script.

Source: Linters/SAST tools


📝 Walkthrough

Walkthrough

Changes

v2.28.0 product release

Layer / File(s) Summary
Product CLI entrypoints and dispatch
marm-mcp-server/marm_mcp_server/cli.py
Adds grouped help, runtime aliases, key management, Docker, upgrade, uninstall, and Console key-import routing.
CLI service workflows
marm-mcp-server/marm_mcp_server/services/*.py
Adds managed key persistence, package lifecycle handling, stable help rendering, log following, fast startup, upgrade/uninstall workflows, and project indexing.
Managed Docker operations
marm-mcp-server/marm_mcp_server/services/docker_*.py
Adds validated Docker run plans, Compose output, container lifecycle commands, STDIO command generation, status/log handling, and embedding migration checks.
Console bootstrap authentication
marm-mcp-server/marm_mcp_server/console/*, marm-console/artifacts/marm-console/src/*
Adds one-time bootstrap tokens, browser session cookies, managed-key handoff, and frontend bootstrap initialization.
Release documentation and metadata
README.md, marm-mcp-server/README.md, marm-mcp-server/marm-docs/*, docs/*, CHANGELOG.md, marm-mcp-server/*
Updates v2.28.0 references and documents the new CLI, Docker, key, Console, and lifecycle behavior.
Validation and smoke testing
marm-mcp-server/tests/*, scripts/test-scripts/docker-linux-bind-mount-smoke.sh, CONTRIBUTING.md
Adds coverage for Console authentication, Docker safety behavior, CLI workflows, aliases, help output, upgrades, uninstall previews, and bind-mount persistence.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@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

assert (STATIC_DIR / "index.html").exists()

P2 Badge Remove the existence-only Console test assertion

Drop this standalone asset existence assertion: the same test immediately exercises the real FastAPI / response, which already fails through the 503 branch if the asset is absent, so this extra check adds no response-contract coverage and violates the repo guidance against existence-check tests.

AGENTS.md reference: AGENTS.md:L58-L63

ℹ️ 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".

raise RuntimeError(
"No managed MARM API key exists. Run `marm-memory key init` first."
)
if MARM_API_KEY and not secrets.compare_digest(managed_key, MARM_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.

P2 Badge Pass the imported key to the Console backend

When --import-key is run from a CLI process where settings.MARM_API_KEY is empty but the managed runtime requires the key from ~/.marm/.env (for example an exposed runtime started with SERVER_HOST=0.0.0.0, then Console launched later without that env), this check treats the state as valid and only creates a browser session. The Console process is then started/reused without MARM_API_KEY, so console.mcp_client sends no Authorization header and all API calls to the keyed runtime return 401; the managed key needs to be supplied to the Console backend or this state should be refused.

Useful? React with 👍 / 👎.

Comment on lines +117 to +118
if args.as_json:
print_payload(latest, as_json=True)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve JSON-only output for upgrade --json

When marm-memory upgrade --json is run without --check, this emits the JSON status and then falls through to the human preview/upgrade messages below, so stdout is not parseable JSON even though the root help advertises upgrade as machine-readable. Scripts using --json to inspect update state will fail to parse the output; return after the structured status or keep the remaining result messages structured.

Useful? React with 👍 / 👎.

"--label",
f"com.marm.profile={options.profile}",
"--mount",
f"type=bind,src={data_dir},dst={CONTAINER_DATA_DIR}",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Make Docker data mounts writable by the image user

On Linux bind mounts, the new docker run/Compose plan mounts a host-created data directory into an image that runs as the non-root marm user (Dockerfile:66). A fresh ~/.marm or --data-dir created by this CLI is owned by the host user and is not writable by that container UID, so the server cannot create the SQLite DB/WAL under /home/marm/.marm and the convenience command times out waiting for health; the plan needs to run with a writable UID/GID or prepare permissions before starting the container.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
marm-mcp-server/marm_mcp_server/services/product_help.py (1)

1-146: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Ruff format check is failing on this file.

Pipeline logs show ruff format --check failing for this file, which will block CI/merge. Run ruff format marm-mcp-server/marm_mcp_server/services/product_help.py and commit the result.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@marm-mcp-server/marm_mcp_server/services/product_help.py` around lines 1 -
146, Run Ruff formatting on the render_product_help function and the entire
product help module, then commit the formatter’s changes so the file passes ruff
format --check without altering its behavior.

Source: Pipeline failures

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@AGENTS.md`:
- Line 47: Update the release checklist entry in AGENTS.md to include its
“Current Stats (v2.27.0)” version marker alongside the README and install-header
files, ensuring it is audited and updated during the v2.28.0 release bump.

In `@marm-mcp-server/marm_mcp_server/console/auth.py`:
- Around line 41-60: Update consume_bootstrap_token so the bootstrap file is
deleted only after the payload passes token, expiry, and secrets.compare_digest
validation. Keep malformed, expired, and incorrect-token requests from unlinking
the pending handoff, while preserving the existing success behavior of consuming
a valid token.

In `@marm-mcp-server/marm_mcp_server/services/docker_commands.py`:
- Around line 252-259: Update the health-polling loop around the
urllib.request.urlopen call so every unsuccessful health check, including
reachable responses whose status is not "healthy", waits 0.5 seconds before
retrying. Preserve immediate return for a healthy response and the existing
exception handling and deadline behavior.
- Around line 169-172: Update shell_command to avoid subprocess.list2cmdline for
Windows output, since its quoting does not protect cmd.exe metacharacters such
as ampersands in pasteable commands. Implement cmd.exe-compatible escaping for
every argument while preserving shlex.join for non-Windows commands and the
existing windows override behavior; ensure docker/compose/stdio command output
through shell_command remains safe to paste.

In `@marm-mcp-server/marm_mcp_server/services/key_management.py`:
- Around line 60-67: Update initialize_managed_key and the existing-key
validation path so managed key files are created atomically with exclusive
owner-only permissions before writing the credential, rather than using
destination.write_text followed by _protect_key_file. When a parseable existing
key is found, verify its permissions are owner-only before returning success; if
hardening or verification fails, do not report successful initialization.

In `@marm-mcp-server/marm_mcp_server/services/product_workflows.py`:
- Around line 152-179: Preserve the runtime’s existing profile and rate-limit
settings across the upgrade flow. Before stopping components, read the current
runtime state via runtime_manager.read_state(), capture its profile and
rate_limit_rpm values, and pass them as profile= and rate_limit_rpm= arguments
to every runtime_manager.start_background() call in both the upgrade-success and
rollback-on-failure branches.
- Around line 66-75: Update the console-launch block in fast_start_http around
run_console so a RuntimeError caused by a managed-key mismatch is caught instead
of propagating. Print a clear warning, continue to construct console_url and
report the already-started runtime status, while preserving existing console
behavior for successful launches and other workflow steps.

---

Outside diff comments:
In `@marm-mcp-server/marm_mcp_server/services/product_help.py`:
- Around line 1-146: Run Ruff formatting on the render_product_help function and
the entire product help module, then commit the formatter’s changes so the file
passes ruff format --check without altering its behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: fe2e71d9-f21e-4815-ae63-d6296407645a

📥 Commits

Reviewing files that changed from the base of the PR and between 40055ba and 5fca854.

📒 Files selected for processing (39)
  • AGENTS.md
  • CHANGELOG.md
  • README.md
  • docs/INSTALL-DOCKER.md
  • docs/INSTALL-LINUX.md
  • docs/INSTALL-PLATFORMS.md
  • docs/INSTALL-WINDOWS.md
  • docs/TECHNICAL-OVERVIEW.md
  • marm-console/artifacts/marm-console/src/App.tsx
  • marm-console/artifacts/marm-console/src/lib/marm-api.ts
  • marm-mcp-server/Dockerfile
  • marm-mcp-server/README.md
  • marm-mcp-server/docker-compose.yml
  • marm-mcp-server/marm-docs/FAQ.md
  • marm-mcp-server/marm-docs/README.md
  • marm-mcp-server/marm-docs/ROADMAP.md
  • marm-mcp-server/marm_mcp_server/__init__.py
  • marm-mcp-server/marm_mcp_server/cli.py
  • marm-mcp-server/marm_mcp_server/config/settings.py
  • marm-mcp-server/marm_mcp_server/console/app.py
  • marm-mcp-server/marm_mcp_server/console/auth.py
  • marm-mcp-server/marm_mcp_server/console/cli.py
  • marm-mcp-server/marm_mcp_server/console/static/assets/index-D10wAXCq.js
  • marm-mcp-server/marm_mcp_server/console/static/index.html
  • marm-mcp-server/marm_mcp_server/server.py
  • marm-mcp-server/marm_mcp_server/services/docker_cli.py
  • marm-mcp-server/marm_mcp_server/services/docker_commands.py
  • marm-mcp-server/marm_mcp_server/services/key_management.py
  • marm-mcp-server/marm_mcp_server/services/package_management.py
  • marm-mcp-server/marm_mcp_server/services/product_help.py
  • marm-mcp-server/marm_mcp_server/services/product_logs.py
  • marm-mcp-server/marm_mcp_server/services/product_workflows.py
  • marm-mcp-server/marm_mcp_server/services/projects_cli.py
  • marm-mcp-server/pyproject.toml
  • marm-mcp-server/server.json
  • marm-mcp-server/tests/test_bundled_console.py
  • marm-mcp-server/tests/test_docker_commands.py
  • marm-mcp-server/tests/test_runtime_cli.py
  • scripts/make-readme-mirrors.py
💤 Files with no reviewable changes (2)
  • marm-mcp-server/marm-docs/ROADMAP.md
  • scripts/make-readme-mirrors.py
📜 Review details
🧰 Additional context used
📓 Path-based instructions (8)
**/*

📄 CodeRabbit inference engine (AGENTS.md)

**/*: Keep changes surgical: modify only what the task requires, match existing style, and preserve behavior during refactors.
Follow SemVer: MAJOR for breaking changes, MINOR for new tools, parameters, or features, and PATCH for fixes and documentation updates.
Prefer the smallest solution that solves the problem; avoid speculative abstractions, unnecessary configuration flags, and extraction without a real module boundary.
Never commit changes without an explicit user request.

Files:

  • marm-mcp-server/docker-compose.yml
  • docs/TECHNICAL-OVERVIEW.md
  • marm-mcp-server/marm_mcp_server/console/static/index.html
  • marm-mcp-server/marm_mcp_server/services/product_help.py
  • docs/INSTALL-PLATFORMS.md
  • marm-mcp-server/pyproject.toml
  • marm-mcp-server/marm_mcp_server/config/settings.py
  • docs/INSTALL-WINDOWS.md
  • marm-mcp-server/marm_mcp_server/__init__.py
  • marm-mcp-server/marm_mcp_server/server.py
  • marm-mcp-server/Dockerfile
  • marm-mcp-server/marm-docs/FAQ.md
  • marm-mcp-server/marm_mcp_server/services/product_logs.py
  • docs/INSTALL-LINUX.md
  • AGENTS.md
  • marm-console/artifacts/marm-console/src/lib/marm-api.ts
  • docs/INSTALL-DOCKER.md
  • marm-mcp-server/tests/test_bundled_console.py
  • CHANGELOG.md
  • marm-mcp-server/marm_mcp_server/services/product_workflows.py
  • marm-mcp-server/marm_mcp_server/console/auth.py
  • marm-mcp-server/server.json
  • marm-console/artifacts/marm-console/src/App.tsx
  • marm-mcp-server/marm_mcp_server/services/key_management.py
  • marm-mcp-server/marm_mcp_server/services/projects_cli.py
  • marm-mcp-server/marm_mcp_server/console/cli.py
  • marm-mcp-server/marm_mcp_server/services/docker_cli.py
  • marm-mcp-server/marm_mcp_server/services/package_management.py
  • README.md
  • marm-mcp-server/marm_mcp_server/console/app.py
  • marm-mcp-server/README.md
  • marm-mcp-server/marm_mcp_server/console/static/assets/index-D10wAXCq.js
  • marm-mcp-server/marm-docs/README.md
  • marm-mcp-server/tests/test_docker_commands.py
  • marm-mcp-server/tests/test_runtime_cli.py
  • marm-mcp-server/marm_mcp_server/services/docker_commands.py
  • marm-mcp-server/marm_mcp_server/cli.py
**/*.md

⚙️ CodeRabbit configuration file

**/*.md: Only flag documentation issues that are materially wrong, misleading for installation/release behavior, or inconsistent with live MCP behavior. Skip style, phrasing, formatting, and wording preferences.

Files:

  • docs/TECHNICAL-OVERVIEW.md
  • docs/INSTALL-PLATFORMS.md
  • docs/INSTALL-WINDOWS.md
  • marm-mcp-server/marm-docs/FAQ.md
  • docs/INSTALL-LINUX.md
  • AGENTS.md
  • docs/INSTALL-DOCKER.md
  • CHANGELOG.md
  • README.md
  • marm-mcp-server/README.md
  • marm-mcp-server/marm-docs/README.md
marm-mcp-server/marm_mcp_server/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

marm-mcp-server/marm_mcp_server/**/*.py: All memory writes must use the serialized asynchronous write queue; do not bypass it.
A semantic-store failure during marm_log_entry must never fail the log write.
Graph and concept failures must never break the seven core memory tools.
marm_smart_recall must keep primary memory ranking authoritative; graph enrichment is read-only, bounded, fail-open, and must be trimmed before primary results when enforcing response limits.
Use one lazy-loaded, lock-serialized fastembed encoder with 512 dimensions, and ensure writes succeed when the encoder is unavailable.
Do not share database connections between the memory SQLite database and the isolated concept-graph SQLite database.
When adding or removing an MCP tool, implement it in the appropriate endpoint, register and whitelist the HTTP route, and add the matching STDIO wrapper or service path.
Use minimal comments that explain only non-obvious reasons; never add comments narrating the next line.
Keep orchestration in its current owner file and extract modules only at real boundaries, following the existing endpoint split.

Files:

  • marm-mcp-server/marm_mcp_server/services/product_help.py
  • marm-mcp-server/marm_mcp_server/config/settings.py
  • marm-mcp-server/marm_mcp_server/__init__.py
  • marm-mcp-server/marm_mcp_server/server.py
  • marm-mcp-server/marm_mcp_server/services/product_logs.py
  • marm-mcp-server/marm_mcp_server/services/product_workflows.py
  • marm-mcp-server/marm_mcp_server/console/auth.py
  • marm-mcp-server/marm_mcp_server/services/key_management.py
  • marm-mcp-server/marm_mcp_server/services/projects_cli.py
  • marm-mcp-server/marm_mcp_server/console/cli.py
  • marm-mcp-server/marm_mcp_server/services/docker_cli.py
  • marm-mcp-server/marm_mcp_server/services/package_management.py
  • marm-mcp-server/marm_mcp_server/console/app.py
  • marm-mcp-server/marm_mcp_server/services/docker_commands.py
  • marm-mcp-server/marm_mcp_server/cli.py
**/*.py

⚙️ CodeRabbit configuration file

**/*.py: Prioritize runtime correctness, async/concurrency safety, SQLite transaction safety, auth/rate-limit behavior, release-breaking packaging issues, and MCP protocol compatibility.

Files:

  • marm-mcp-server/marm_mcp_server/services/product_help.py
  • marm-mcp-server/marm_mcp_server/config/settings.py
  • marm-mcp-server/marm_mcp_server/__init__.py
  • marm-mcp-server/marm_mcp_server/server.py
  • marm-mcp-server/marm_mcp_server/services/product_logs.py
  • marm-mcp-server/tests/test_bundled_console.py
  • marm-mcp-server/marm_mcp_server/services/product_workflows.py
  • marm-mcp-server/marm_mcp_server/console/auth.py
  • marm-mcp-server/marm_mcp_server/services/key_management.py
  • marm-mcp-server/marm_mcp_server/services/projects_cli.py
  • marm-mcp-server/marm_mcp_server/console/cli.py
  • marm-mcp-server/marm_mcp_server/services/docker_cli.py
  • marm-mcp-server/marm_mcp_server/services/package_management.py
  • marm-mcp-server/marm_mcp_server/console/app.py
  • marm-mcp-server/tests/test_docker_commands.py
  • marm-mcp-server/tests/test_runtime_cli.py
  • marm-mcp-server/marm_mcp_server/services/docker_commands.py
  • marm-mcp-server/marm_mcp_server/cli.py
marm-mcp-server/marm_mcp_server/server.py

📄 CodeRabbit inference engine (AGENTS.md)

HTTP MCP tools must be included in MCP_TOOL_OPERATIONS; tools absent from this whitelist do not exist over HTTP.

Files:

  • marm-mcp-server/marm_mcp_server/server.py
marm-mcp-server/tests/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

marm-mcp-server/tests/**/*.py: Run tests with pytest from marm-mcp-server/; use real FastAPI endpoints and SQLite, mocking only when it materially speeds tests and matches real behavior with at least 95% fidelity.
Every new MARM Console API route must have at least one happy-path FastAPI response-contract test with the MCP adapter stubbed.
Do not write existence-check or coded-to-pass tests; prefer deep tests exercising real paths over broad shallow coverage.
Use pytest.mark.skip only for genuinely unavailable dependencies, never to avoid implementing or running a test.

Files:

  • marm-mcp-server/tests/test_bundled_console.py
  • marm-mcp-server/tests/test_docker_commands.py
  • marm-mcp-server/tests/test_runtime_cli.py
**/tests/**

⚙️ CodeRabbit configuration file

**/tests/**: Focus on tests that are flaky, non-isolated, incorrectly asserting behavior, or missing coverage for a changed high-risk path. Skip minor naming, comments, and layout preferences.

Files:

  • marm-mcp-server/tests/test_bundled_console.py
  • marm-mcp-server/tests/test_docker_commands.py
  • marm-mcp-server/tests/test_runtime_cli.py
marm-mcp-server/server.json

📄 CodeRabbit inference engine (AGENTS.md)

When adding or removing an MCP tool, update the tools array; when bumping the version, update all three version occurrences, including the Docker identifier.

Files:

  • marm-mcp-server/server.json
🪛 ast-grep (0.44.1)
marm-mcp-server/marm_mcp_server/console/auth.py

[info] 28-30: use jsonify instead of json.dumps for JSON output
Context: json.dumps(
{"token": token, "expires_at": time.time() + _BOOTSTRAP_TTL_SECONDS}
)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)

marm-mcp-server/marm_mcp_server/services/key_management.py

[error] 44-54: Command coming from incoming request
Context: subprocess.run(
[
"icacls",
str(path),
"/inheritance:r",
"/grant:r",
f"{getpass.getuser()}:(F)",
],
check=False,
capture_output=True,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)

marm-mcp-server/marm_mcp_server/services/docker_cli.py

[info] 107-107: use jsonify instead of json.dumps for JSON output
Context: json.dumps(payload["document"], indent=2)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)

marm-mcp-server/marm_mcp_server/services/package_management.py

[warning] 77-77: Request-controlled URL passed to urlopen; validate against an allowlist to prevent SSRF.
Context: urllib.request.urlopen(request, timeout=timeout)
Note: [CWE-918] Server-Side Request Forgery (SSRF).

(urlopen-unsanitized-data)


[error] 122-124: Command coming from incoming request
Context: subprocess.call(
[sys.executable, "-m", "pip", "install", "--upgrade", target]
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)


[error] 129-131: Command coming from incoming request
Context: subprocess.call(
[sys.executable, "-m", "pip", "uninstall", "--yes", PACKAGE_NAME]
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)

marm-mcp-server/marm_mcp_server/console/app.py

[error] 161-161: verify should be True
Context: secure=False
Note: [CWE-295] Improper Certificate Validation (TLS verification disabled).

(request-verify)


[info] 161-161: Make sure cookies are safe and secure
Context: secure=False
Note: [CWE-614] Sensitive Cookie in HTTPS Session Without 'Secure' Attribute.

(secure-cookie)

marm-mcp-server/marm_mcp_server/console/static/assets/index-D10wAXCq.js

[warning] 48-48: Avoid SQL injections
Context: prompt(Type DELETE to delete ${ue.length} selected memories.)==="DELETE"&&v.mutate(ue,{onSuccess:ye=>{y(new Set),h(Qx(ye,"Selected memory deleted."))},onError:ye=>h({kind:"error",message:It(ye)})})
Note: [CWE-89] Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). Security best practice.

(variable-sql-statement-injection)


[warning] 48-48: Avoid SQL injections
Context: prompt(Type DELETE to delete ${ue.length} selected memories.)==="DELETE"
Note: [CWE-89] Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). Security best practice.

(variable-sql-statement-injection)


[warning] 48-48: Avoid SQL injections
Context: Type DELETE to delete ${ue.length} selected memories.
Note: [CWE-89] Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). Security best practice.

(variable-sql-statement-injection)


[warning] 50-50: Avoid SQL injections
Context: prompt(Type DELETE to delete session '${b}' and its log-backed memories.)==="DELETE"&&d.mutate(b,{onSuccess:w=>{c({kind:"success",message:Session '${b}' deleted. ${w.deleted_count} log entries and ${w.memories_deleted} semantic log memories removed.})},onError:w=>c({kind:"error",message:It(w)})})
Note: [CWE-89] Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). Security best practice.

(variable-sql-statement-injection)


[warning] 50-50: Avoid SQL injections
Context: prompt(Type DELETE to delete session '${b}' and its log-backed memories.)==="DELETE"
Note: [CWE-89] Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). Security best practice.

(variable-sql-statement-injection)


[warning] 50-50: Avoid SQL injections
Context: Type DELETE to delete session '${b}' and its log-backed memories.
Note: [CWE-89] Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). Security best practice.

(variable-sql-statement-injection)


[warning] 50-50: Avoid SQL injections
Context: prompt("Type DELETE_ALL to delete every session and its log-backed memories.")==="DELETE_ALL"&&h.mutate(void 0,{onSuccess:=>{const w=.failed_sessions?.length??0;c({kind:w?"error":"success",message:w?${_.deleted_sessions} sessions deleted, ${w} failed. ${_.deleted_count} log entries and ${_.memories_deleted} semantic log memories removed.:${_.deleted_sessions} sessions deleted. ${_.deleted_count} log entries and ${_.memories_deleted} semantic log memories removed.})},onError:=>c({kind:"error",message:It()})})
Note: [CWE-89] Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). Security best practice.

(variable-sql-statement-injection)


[warning] 50-50: Avoid SQL injections
Context: prompt("Type DELETE_ALL to delete every session and its log-backed memories.")==="DELETE_ALL"
Note: [CWE-89] Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). Security best practice.

(variable-sql-statement-injection)


[warning] 50-50: Avoid SQL injections
Context: prompt(Type DELETE to delete log entry ${v}.)==="DELETE"&&d.mutate({id:v,sessionName:b},{onSuccess:w=>{f({kind:"success",message:Log ${w.log_id} deleted. ${w.memories_deleted} semantic log memories removed.})},onError:w=>f({kind:"error",message:It(w)})})
Note: [CWE-89] Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). Security best practice.

(variable-sql-statement-injection)


[warning] 50-50: Avoid SQL injections
Context: prompt(Type DELETE to delete log entry ${v}.)==="DELETE"
Note: [CWE-89] Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). Security best practice.

(variable-sql-statement-injection)


[warning] 50-50: Avoid SQL injections
Context: Type DELETE to delete log entry ${v}.
Note: [CWE-89] Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). Security best practice.

(variable-sql-statement-injection)


[warning] 50-50: Avoid SQL injections
Context: prompt("Type DELETE_ALL to delete every log entry.")==="DELETE_ALL"&&h.mutate(void 0,{onSuccess:b=>{f({kind:"success",message:${b.deleted_count} log entries deleted. ${b.memories_deleted} semantic log memories removed.})},onError:b=>f({kind:"error",message:It(b)})})
Note: [CWE-89] Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). Security best practice.

(variable-sql-statement-injection)


[warning] 50-50: Avoid SQL injections
Context: prompt("Type DELETE_ALL to delete every log entry.")==="DELETE_ALL"
Note: [CWE-89] Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). Security best practice.

(variable-sql-statement-injection)


[warning] 50-50: Avoid SQL injections
Context: prompt(Type DELETE to delete notebook entry '${f.name}'.)==="DELETE"&&s.mutate({name:f.name,params:{session_name:f.session_name||void 0,project:f.project||void 0,platform:f.platform||void 0}},{onSuccess:()=>{c({kind:"success",message:Notebook entry '${f.name}' deleted.}),d(null)},onError:v=>c({kind:"error",message:It(v)})})
Note: [CWE-89] Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). Security best practice.

(variable-sql-statement-injection)


[warning] 50-50: Avoid SQL injections
Context: prompt(Type DELETE to delete notebook entry '${f.name}'.)==="DELETE"
Note: [CWE-89] Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). Security best practice.

(variable-sql-statement-injection)


[warning] 50-50: Avoid SQL injections
Context: Type DELETE to delete notebook entry '${f.name}'.
Note: [CWE-89] Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). Security best practice.

(variable-sql-statement-injection)


[warning] 53-53: Do not use variable for regular expressions
Context: new RegExp(r)
Note: [CWE-1333] Inefficient Regular Expression Complexity. Security best practice.

(regexp-non-literal)


[error] 7-7: React's useState should not be directly called
Context: setTimeout(function(){throw u})
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 7-7: React's useState should not be directly called
Context: setTimeout(function(){throw g})
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 8-8: React's useState should not be directly called
Context: setTimeout(function(){throw i})
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 8-8: React's useState should not be directly called
Context: setTimeout(function(){if(i.stylesheets&&ch(i,i.stylesheets),i.unsuspend){var u=i.unsuspend;i.unsuspend=null,u()}},6e4)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 8-8: React's useState should not be directly called
Context: setTimeout(e,0)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 8-8: React's useState should not be directly called
Context: setTimeout(()=>f.abort(),3e4)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 48-48: React's useState should not be directly called
Context: setTimeout(function(){n.current=n.current.filter(function(T){return T!==R})},1)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 48-48: React's useState should not be directly called
Context: setTimeout(()=>{f(!1,1e-7)},1e3)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 52-52: React's useState should not be directly called
Context: setTimeout(function(){s.on("click.drag",null)},0)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 52-52: React's useState should not be directly called
Context: setTimeout(function(){y=null},500)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 52-52: React's useState should not be directly called
Context: setTimeout(e,17)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 52-52: React's useState should not be directly called
Context: setTimeout(cb,e-rl.now()-Wu)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 52-52: React's useState should not be directly called
Context: setInterval(c5,l2)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 52-52: React's useState should not be directly called
Context: setTimeout(k,w)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 52-52: React's useState should not be directly called
Context: setTimeout(function(){y=null},_)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 52-52: React's useState should not be directly called
Context: setTimeout(function(){b=null},_)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 52-52: React's useState should not be directly called
Context: setTimeout(j,n)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 52-52: React's useState should not be directly called
Context: setTimeout(j,S(L))
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 52-52: React's useState should not be directly called
Context: setTimeout(j,n)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[error] 52-52: React's useState should not be directly called
Context: setTimeout(j,n)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(usestate-direct-usage)


[warning] 8-8: Avoid using the initial state variable in setState
Context: setTimeout(e,n)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(setstate-same-var)


[warning] 8-8: Avoid using the initial state variable in setState
Context: setInterval(e,n)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(setstate-same-var)


[warning] 8-8: Avoid using the initial state variable in setState
Context: setTimeout(e,0)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(setstate-same-var)


[warning] 52-52: Avoid using the initial state variable in setState
Context: setTimeout(e,17)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(setstate-same-var)


[warning] 52-52: Avoid using the initial state variable in setState
Context: setTimeout(cb,e-rl.now()-Wu)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(setstate-same-var)


[warning] 52-52: Avoid using the initial state variable in setState
Context: setInterval(c5,l2)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(setstate-same-var)


[warning] 52-52: Avoid using the initial state variable in setState
Context: setTimeout(k,w)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(setstate-same-var)


[warning] 52-52: Avoid using the initial state variable in setState
Context: setTimeout(function(){y=null},_)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(setstate-same-var)


[warning] 52-52: Avoid using the initial state variable in setState
Context: setTimeout(function(){b=null},_)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(setstate-same-var)


[warning] 52-52: Avoid using the initial state variable in setState
Context: setTimeout(j,n)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(setstate-same-var)


[warning] 52-52: Avoid using the initial state variable in setState
Context: setTimeout(j,S(L))
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(setstate-same-var)


[warning] 52-52: Avoid using the initial state variable in setState
Context: setTimeout(j,n)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(setstate-same-var)


[warning] 52-52: Avoid using the initial state variable in setState
Context: setTimeout(j,n)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(setstate-same-var)


[warning] 8-8: Avoid assigning untrusted data to innerHTML/outerHTML or document.write
Context: i.innerHTML=o
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting').

(inner-outer-html)


[warning] 8-8: Avoid assigning untrusted data to innerHTML/outerHTML or document.write
Context: i.innerHTML=o
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting').

(inner-outer-html)


[warning] 52-52: Avoid assigning untrusted data to innerHTML/outerHTML or document.write
Context: this.innerHTML=e
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting').

(inner-outer-html)


[warning] 52-52: Avoid assigning untrusted data to innerHTML/outerHTML or document.write
Context: this.innerHTML=n??""
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting').

(inner-outer-html)


[warning] 54-54: Avoid assigning untrusted data to innerHTML/outerHTML or document.write
Context: e.innerHTML=y.__html
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting').

(inner-outer-html)


[warning] 8-8: Detects non-literal values in regular expressions
Context: new RegExp("^"+d+(n?"(?=$|/)":"/?$"),"i")
Note: [CWE-1333] Inefficient Regular Expression Complexity (ReDoS via non-literal RegExp).

(detect-non-literal-regexp)


[warning] 52-52: Detects non-literal values in regular expressions
Context: new RegExp(^rgb\\(${cs},${cs},${cs}\\)$)
Note: [CWE-1333] Inefficient Regular Expression Complexity (ReDoS via non-literal RegExp).

(detect-non-literal-regexp)


[warning] 52-52: Detects non-literal values in regular expressions
Context: new RegExp(^rgb\\(${sr},${sr},${sr}\\)$)
Note: [CWE-1333] Inefficient Regular Expression Complexity (ReDoS via non-literal RegExp).

(detect-non-literal-regexp)


[warning] 52-52: Detects non-literal values in regular expressions
Context: new RegExp(^rgba\\(${cs},${cs},${cs},${tl}\\)$)
Note: [CWE-1333] Inefficient Regular Expression Complexity (ReDoS via non-literal RegExp).

(detect-non-literal-regexp)


[warning] 52-52: Detects non-literal values in regular expressions
Context: new RegExp(^rgba\\(${sr},${sr},${sr},${tl}\\)$)
Note: [CWE-1333] Inefficient Regular Expression Complexity (ReDoS via non-literal RegExp).

(detect-non-literal-regexp)


[warning] 52-52: Detects non-literal values in regular expressions
Context: new RegExp(^hsl\\(${tl},${sr},${sr}\\)$)
Note: [CWE-1333] Inefficient Regular Expression Complexity (ReDoS via non-literal RegExp).

(detect-non-literal-regexp)


[warning] 52-52: Detects non-literal values in regular expressions
Context: new RegExp(^hsla\\(${tl},${sr},${sr},${tl}\\)$)
Note: [CWE-1333] Inefficient Regular Expression Complexity (ReDoS via non-literal RegExp).

(detect-non-literal-regexp)


[warning] 52-52: Detects non-literal values in regular expressions
Context: new RegExp(ym.source,"g")
Note: [CWE-1333] Inefficient Regular Expression Complexity (ReDoS via non-literal RegExp).

(detect-non-literal-regexp)


[warning] 53-53: Detects non-literal values in regular expressions
Context: new RegExp(r)
Note: [CWE-1333] Inefficient Regular Expression Complexity (ReDoS via non-literal RegExp).

(detect-non-literal-regexp)


[warning] 53-53: Detects non-literal values in regular expressions
Context: new RegExp("rgb"+s)
Note: [CWE-1333] Inefficient Regular Expression Complexity (ReDoS via non-literal RegExp).

(detect-non-literal-regexp)


[warning] 53-53: Detects non-literal values in regular expressions
Context: new RegExp("rgba"+l)
Note: [CWE-1333] Inefficient Regular Expression Complexity (ReDoS via non-literal RegExp).

(detect-non-literal-regexp)


[warning] 53-53: Detects non-literal values in regular expressions
Context: new RegExp("hsl"+s)
Note: [CWE-1333] Inefficient Regular Expression Complexity (ReDoS via non-literal RegExp).

(detect-non-literal-regexp)


[warning] 53-53: Detects non-literal values in regular expressions
Context: new RegExp("hsla"+l)
Note: [CWE-1333] Inefficient Regular Expression Complexity (ReDoS via non-literal RegExp).

(detect-non-literal-regexp)


[warning] 53-53: Detects non-literal values in regular expressions
Context: new RegExp("hsv"+s)
Note: [CWE-1333] Inefficient Regular Expression Complexity (ReDoS via non-literal RegExp).

(detect-non-literal-regexp)


[warning] 53-53: Detects non-literal values in regular expressions
Context: new RegExp("hsva"+l)
Note: [CWE-1333] Inefficient Regular Expression Complexity (ReDoS via non-literal RegExp).

(detect-non-literal-regexp)

marm-mcp-server/tests/test_docker_commands.py

[info] 137-137: use jsonify instead of json.dumps for JSON output
Context: json.dumps(status)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)

marm-mcp-server/marm_mcp_server/services/docker_commands.py

[error] 372-372: Avoid HTML built in strings
Context: render(child, indent + 2)
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting').

(html-string-from-parameters)


[error] 381-381: Avoid HTML built in strings
Context: render(child, indent + 2)
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting').

(html-string-from-parameters)


[error] 387-387: Avoid HTML built in strings
Context: render(document)
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting').

(html-string-from-parameters)


[error] 178-178: Use of unsanitized data to create processes
Context: subprocess.run(arguments, capture_output=True, text=True, check=False)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(os-system-unsanitized-data)


[info] 359-359: use jsonify instead of json.dumps for JSON output
Context: json.dumps(str(value))
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[error] 178-178: Command coming from incoming request
Context: subprocess.run(arguments, capture_output=True, text=True, check=False)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)


[error] 438-438: Command coming from incoming request
Context: subprocess.call(arguments)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)


[error] 451-451: Command coming from incoming request
Context: subprocess.call(arguments)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)


[warning] 253-253: Request-controlled URL passed to urlopen; validate against an allowlist to prevent SSRF.
Context: urllib.request.urlopen(url, timeout=2)
Note: [CWE-918] Server-Side Request Forgery (SSRF).

(urlopen-unsanitized-data)

🪛 Biome (2.5.3)
marm-mcp-server/marm_mcp_server/console/static/assets/index-D10wAXCq.js

[error] 1-1: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 1-1: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 1-1: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 1-1: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: This comparison uses the same expression on both sides.

(lint/suspicious/noSelfCompare)


[error] 8-8: This comparison uses the same expression on both sides.

(lint/suspicious/noSelfCompare)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 8-8: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 9-9: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 9-9: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 9-9: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 9-9: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 9-9: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 9-9: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 9-9: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 9-9: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 9-9: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 9-9: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 9-9: This comparison uses the same expression on both sides.

(lint/suspicious/noSelfCompare)


[error] 9-9: This comparison uses the same expression on both sides.

(lint/suspicious/noSelfCompare)


[error] 49-49: This comparison uses the same expression on both sides.

(lint/suspicious/noSelfCompare)


[error] 49-49: This comparison uses the same expression on both sides.

(lint/suspicious/noSelfCompare)


[error] 51-51: Unsafe usage of 'return'.

(lint/correctness/noUnsafeFinally)


[error] 51-51: Unsafe usage of 'throw'.

(lint/correctness/noUnsafeFinally)


[error] 53-53: This comparison uses the same expression on both sides.

(lint/suspicious/noSelfCompare)


[error] 53-53: This comparison uses the same expression on both sides.

(lint/suspicious/noSelfCompare)


[error] 53-53: This comparison uses the same expression on both sides.

(lint/suspicious/noSelfCompare)


[error] 53-53: This comparison uses the same expression on both sides.

(lint/suspicious/noSelfCompare)


[error] 53-53: Unsafe usage of 'return'.

(lint/correctness/noUnsafeFinally)


[error] 53-53: Unsafe usage of 'throw'.

(lint/correctness/noUnsafeFinally)


[error] 55-55: Unsafe usage of 'return'.

(lint/correctness/noUnsafeFinally)


[error] 55-55: Unsafe usage of 'throw'.

(lint/correctness/noUnsafeFinally)


[error] 67-67: Unsafe usage of 'return'.

(lint/correctness/noUnsafeFinally)


[error] 67-67: Unsafe usage of 'throw'.

(lint/correctness/noUnsafeFinally)


[error] 92-92: Unsafe usage of 'return'.

(lint/correctness/noUnsafeFinally)


[error] 92-92: Unsafe usage of 'throw'.

(lint/correctness/noUnsafeFinally)

🪛 GitHub Actions: Ruff CI / 0_ruff.txt
marm-mcp-server/marm_mcp_server/services/product_help.py

[error] 1-93: ruff format --check failed. Unformatted code detected; file would be reformatted (ruff-format).

🪛 GitHub Actions: Ruff CI / ruff
marm-mcp-server/marm_mcp_server/services/product_help.py

[error] 1-1: ruff format --check failed: file would be reformatted. Run 'ruff format' to apply formatting.

🪛 OpenGrep (1.25.0)
marm-mcp-server/marm_mcp_server/console/static/assets/index-D10wAXCq.js

[ERROR] 67-67: Possible credit card number (PAN) detected in source code. Credit card numbers should never be hardcoded or stored in source files. Use a secrets manager or tokenization service instead.

(coderabbit.pii.credit-card-number)


[ERROR] 67-67: Possible credit card number (PAN) detected in source code. Credit card numbers should never be hardcoded or stored in source files. Use a secrets manager or tokenization service instead.

(coderabbit.pii.credit-card-number)


[ERROR] 67-67: Possible credit card number (PAN) detected in source code. Credit card numbers should never be hardcoded or stored in source files. Use a secrets manager or tokenization service instead.

(coderabbit.pii.credit-card-number)


[ERROR] 67-67: Possible credit card number (PAN) detected in source code. Credit card numbers should never be hardcoded or stored in source files. Use a secrets manager or tokenization service instead.

(coderabbit.pii.credit-card-number)

🔇 Additional comments (34)
AGENTS.md (1)

33-37: LGTM!

CHANGELOG.md (1)

5-29: LGTM!

README.md (1)

8-8: LGTM!

Also applies to: 39-39, 103-161, 256-256, 316-368

docs/INSTALL-DOCKER.md (1)

5-5: LGTM!

docs/INSTALL-LINUX.md (1)

5-5: LGTM!

Also applies to: 323-323

docs/INSTALL-PLATFORMS.md (1)

1-1: LGTM!

docs/INSTALL-WINDOWS.md (1)

5-5: LGTM!

Also applies to: 297-297

docs/TECHNICAL-OVERVIEW.md (1)

3-3: LGTM!

marm-mcp-server/Dockerfile (1)

76-76: LGTM!

marm-mcp-server/README.md (1)

10-10: LGTM!

Also applies to: 41-41, 105-163, 258-258, 318-370

marm-mcp-server/docker-compose.yml (1)

21-21: LGTM!

marm-mcp-server/marm-docs/FAQ.md (1)

74-74: LGTM!

Also applies to: 117-117

marm-mcp-server/marm-docs/README.md (1)

1-17: LGTM!

Also applies to: 73-131, 226-226, 286-338

marm-mcp-server/marm_mcp_server/__init__.py (1)

17-20: LGTM!

marm-mcp-server/marm_mcp_server/config/settings.py (1)

125-125: LGTM!

marm-mcp-server/marm_mcp_server/server.py (1)

8-8: LGTM!

marm-mcp-server/pyproject.toml (1)

7-7: LGTM!

marm-mcp-server/server.json (1)

6-6: LGTM!

Also applies to: 20-25

marm-mcp-server/marm_mcp_server/services/docker_cli.py (1)

12-73: LGTM!

Also applies to: 76-170

marm-mcp-server/marm_mcp_server/services/docker_commands.py (1)

95-166: LGTM!

Also applies to: 265-278, 304-411, 414-466

marm-mcp-server/tests/test_bundled_console.py (1)

70-124: LGTM!

marm-mcp-server/tests/test_docker_commands.py (1)

11-274: LGTM!

marm-mcp-server/tests/test_runtime_cli.py (1)

118-150: LGTM!

Also applies to: 206-483

marm-mcp-server/marm_mcp_server/cli.py (1)

144-292: LGTM!

Also applies to: 480-530, 540-692, 733-760

marm-mcp-server/marm_mcp_server/services/package_management.py (1)

1-133: LGTM!

marm-mcp-server/marm_mcp_server/services/product_logs.py (1)

15-33: 🩺 Stability & Availability

Follow mode may miss rename-based log rotation.

The rotation check only detects truncation-in-place (stat().st_size < tell()); it never reopens by path, so a rename/recreate-style rotation (the file handle now points to an orphaned inode) would silently stop showing new log lines under --follow.

Please confirm start_log_maintenance rotates via truncation rather than rename; if it can rename, this should periodically reopen path and detect via inode change.

marm-mcp-server/marm_mcp_server/services/projects_cli.py (1)

70-72: 🩺 Stability & Availability

RuntimeRequestError is already covered by the CLI error path.

marm-mcp-server/marm_mcp_server/services/key_management.py (1)

60-68: 🗄️ Data Integrity & Integration

No change needed for ~/.marm/.env contents.

The managed key path is only assigned/read for MARM_API_KEY in the code paths under review, so this does not preserve unrelated env settings beyond the current file format.

			> Likely an incorrect or invalid review comment.
marm-mcp-server/marm_mcp_server/console/app.py (1)

156-163: 🔒 Security & Privacy | ⚡ Quick win

Sensitive Data Exposure (CWE-614): Sensitive Cookie in HTTPS Session Without 'Secure' Attribute

Reachability: External
● Entry
  marm-console/artifacts/marm-console/src/App.tsx:49
  fetch /api/auth/bootstrap
│
▼
● Sink
  marm-mcp-server/marm_mcp_server/console/app.py

Session cookie sets secure=False, and Console host is configurable off-loopback.

_host() in console/cli.py lets MARM_CONSOLE_HOST bind to 0.0.0.0/::, not just 127.0.0.1. If an operator does that (e.g. to reach the console from another machine on the LAN), this marm_console_session cookie would travel in plaintext with no Secure flag. Worth confirming this is intentionally scoped to the documented loopback-only use case, or gating secure on the bind host.

marm-mcp-server/marm_mcp_server/console/cli.py (1)

61-86: LGTM!

Also applies to: 134-134

marm-console/artifacts/marm-console/src/App.tsx (1)

37-64: LGTM!

marm-console/artifacts/marm-console/src/lib/marm-api.ts (1)

87-93: LGTM!

marm-mcp-server/marm_mcp_server/console/static/assets/index-D10wAXCq.js (1)

1-94: LGTM! This is generated build output consistent with the App.tsx source changes. The static-analysis hits here (credit-card-number regex, "unsafe setState", non-literal RegExp) are all inside pre-existing bundled vendor code (React/d3/tween.js internals) and are false positives, not issues introduced by this PR.

marm-mcp-server/marm_mcp_server/console/static/index.html (1)

19-19: LGTM!

Comment thread AGENTS.md
Comment thread marm-mcp-server/marm_mcp_server/console/auth.py Outdated
Comment thread marm-mcp-server/marm_mcp_server/services/docker_commands.py
Comment thread marm-mcp-server/marm_mcp_server/services/docker_commands.py Outdated
Comment thread marm-mcp-server/marm_mcp_server/services/key_management.py Outdated
Comment thread marm-mcp-server/marm_mcp_server/services/product_workflows.py Outdated
Comment thread marm-mcp-server/marm_mcp_server/services/product_workflows.py
Lyellr88 and others added 2 commits July 23, 2026 23:31
…test

Resolve CodeRabbit and Codex review findings on the v2.28.0 command surface.

- Docker: map bind-mount writes to the host UID/GID and set HOME plus
  XDG_CACHE_HOME so the SQLite database lands in the mounted, host-owned
  data directory instead of an unwritable container home. Applied to run,
  stdio, and compose. Add a Linux bind-mount smoke test that verifies write
  and persistence across a container restart.
- Console: verify the bootstrap token before consuming it and hold the
  lock across validation and unlink; fall back to the managed key when the
  Console runs without MARM_API_KEY.
- upgrade: emit JSON-only output for --json (rejecting --yes) and preserve
  the active runtime profile and rate limit across restart and rollback.
- fast-start-http: continue when the Console fails, with accurate status.
- key management: create key files atomically with verified owner-only
  permissions.
- Health polling no longer spins on unhealthy responses; drop an
  existence-only test assertion; refresh stale tests and version markers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Repository owner deleted a comment from gitguardian Bot Jul 24, 2026
Repository owner deleted a comment from gitguardian Bot Jul 24, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
marm-mcp-server/marm_mcp_server/services/key_management.py (1)

48-59: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Sensitive Data Exposure (CWE-732): Incorrect Permission Assignment for Critical Resource

Reachability: External
● Entry
  marm-mcp-server/marm_mcp_server/services/docker_commands.py:17
  initialize_managed_key
│
▼
● Sink
  marm-mcp-server/marm_mcp_server/services/key_management.py

Reject files whose post-icacls DACL still contains other principals’ read access

/inheritance:r /grant:r {user}:(F) only disables inheritance and replaces matching existing ACL entries for the current user; it does not remove existing explicit read entries for other principals such as Users or Everyone. initialize_managed_key treats a 0 return code from icacls as owner-only protection, so local accounts granted read access could still read the API key. Inspect the resulting ACL or replace the DACL with an explicit allowlist before accepting the key as secured.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@marm-mcp-server/marm_mcp_server/services/key_management.py` around lines 48 -
59, The icacls result check must verify that the resulting DACL grants access
only to the intended current user, not merely that the command succeeded. Update
the key-protection flow around the visible subprocess invocation and its
returncode check to replace or inspect the DACL, reject files containing read or
broader access for other principals such as Users or Everyone, and accept the
key only when the explicit owner-only allowlist is enforced.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/test-scripts/docker-linux-bind-mount-smoke.sh`:
- Line 6: Separate declaration from command substitution assignment for
smoke_root and port in the script: declare each variable readonly first, then
assign the command result so mktemp or the port-picker failure status is
preserved and triggers set -e. Apply this to the readonly variables in the
affected setup block, including smoke_root and port, without changing their
values or subsequent usage.
- Line 8: Replace the hardcoded value assigned to api_key in the smoke-test
script with a runtime-generated throwaway key, preserving the variable’s use and
ensuring no fixed high-entropy credential-like literal remains in the script.

---

Outside diff comments:
In `@marm-mcp-server/marm_mcp_server/services/key_management.py`:
- Around line 48-59: The icacls result check must verify that the resulting DACL
grants access only to the intended current user, not merely that the command
succeeded. Update the key-protection flow around the visible subprocess
invocation and its returncode check to replace or inspect the DACL, reject files
containing read or broader access for other principals such as Users or
Everyone, and accept the key only when the explicit owner-only allowlist is
enforced.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: bfafe5be-3896-406c-82d4-211da151f591

📥 Commits

Reviewing files that changed from the base of the PR and between 5fca854 and 075869b.

📒 Files selected for processing (13)
  • AGENTS.md
  • CONTRIBUTING.md
  • marm-mcp-server/marm_mcp_server/console/auth.py
  • marm-mcp-server/marm_mcp_server/console/mcp_client.py
  • marm-mcp-server/marm_mcp_server/services/docker_commands.py
  • marm-mcp-server/marm_mcp_server/services/key_management.py
  • marm-mcp-server/marm_mcp_server/services/product_help.py
  • marm-mcp-server/marm_mcp_server/services/product_workflows.py
  • marm-mcp-server/tests/test_bundled_console.py
  • marm-mcp-server/tests/test_cli_entrypoint.py
  • marm-mcp-server/tests/test_docker_commands.py
  • marm-mcp-server/tests/test_runtime_cli.py
  • scripts/test-scripts/docker-linux-bind-mount-smoke.sh
🚧 Files skipped from review as they are similar to previous changes (7)
  • AGENTS.md
  • marm-mcp-server/marm_mcp_server/services/product_help.py
  • marm-mcp-server/tests/test_bundled_console.py
  • marm-mcp-server/marm_mcp_server/console/auth.py
  • marm-mcp-server/marm_mcp_server/services/product_workflows.py
  • marm-mcp-server/marm_mcp_server/services/docker_commands.py
  • marm-mcp-server/tests/test_docker_commands.py
📜 Review details
🧰 Additional context used
📓 Path-based instructions (5)
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

Documentation copies and version headers must be updated consistently when tool lists or versions change, while separately maintained README variants must preserve their intended differences.

Files:

  • CONTRIBUTING.md

⚙️ CodeRabbit configuration file

**/*.md: Only flag documentation issues that are materially wrong, misleading for installation/release behavior, or inconsistent with live MCP behavior. Skip style, phrasing, formatting, and wording preferences.

Files:

  • CONTRIBUTING.md
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Keep changes surgical: modify only what the task requires, match existing style, and preserve behavior during refactors.

Files:

  • marm-mcp-server/marm_mcp_server/console/mcp_client.py
  • marm-mcp-server/tests/test_cli_entrypoint.py
  • marm-mcp-server/marm_mcp_server/services/key_management.py
  • marm-mcp-server/tests/test_runtime_cli.py

⚙️ CodeRabbit configuration file

**/*.py: Prioritize runtime correctness, async/concurrency safety, SQLite transaction safety, auth/rate-limit behavior, release-breaking packaging issues, and MCP protocol compatibility.

Files:

  • marm-mcp-server/marm_mcp_server/console/mcp_client.py
  • marm-mcp-server/tests/test_cli_entrypoint.py
  • marm-mcp-server/marm_mcp_server/services/key_management.py
  • marm-mcp-server/tests/test_runtime_cli.py
marm-mcp-server/marm_mcp_server/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

marm-mcp-server/marm_mcp_server/**/*.py: HTTP and STDIO transports must remain in exact behavioral parity; never fork behavior between transports.
All memory writes must use the serialized asynchronous write queue; do not add bypass write paths.
A marm_log_entry semantic-store failure must never fail the primary log write.
Keep the memory database and concept-graph database isolated; never share connections between their pools.
Graph and concept failures must never break the seven core memory tools.
marm_smart_recall must keep primary memory ranking authoritative; graph enrichment is bounded, read-only, fail-open, and trimmed before primary results when enforcing limits.
Writes must succeed when the embedding encoder is unavailable; embedding loading is lazy and serialized behind a lock.
Prefer the smallest solution: avoid speculative abstractions and unnecessary configuration flags; keep orchestration in its current owner and extract modules only at real boundaries.
Comments must be minimal and explain only non-obvious reasons; never narrate what the next line does.
When adding a tool, implement it in endpoints/, register and whitelist the HTTP route, add the STDIO wrapper, and update every tool-list artifact and both-transport tests.

Files:

  • marm-mcp-server/marm_mcp_server/console/mcp_client.py
  • marm-mcp-server/marm_mcp_server/services/key_management.py
marm-mcp-server/tests/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

marm-mcp-server/tests/**/*.py: Run tests with pytest from marm-mcp-server/; tests should hit real FastAPI endpoints and SQLite, mocking only when it meaningfully speeds testing and matches real behavior with at least 95% fidelity.
Every new MARM Console API route needs at least one happy-path FastAPI response-contract test with the MCP adapter stubbed.
Do not write existence-check or coded-to-pass tests; prefer deep tests exercising real paths, and use pytest.mark.skip only for genuinely unavailable dependencies.

Files:

  • marm-mcp-server/tests/test_cli_entrypoint.py
  • marm-mcp-server/tests/test_runtime_cli.py
**/tests/**

⚙️ CodeRabbit configuration file

**/tests/**: Focus on tests that are flaky, non-isolated, incorrectly asserting behavior, or missing coverage for a changed high-risk path. Skip minor naming, comments, and layout preferences.

Files:

  • marm-mcp-server/tests/test_cli_entrypoint.py
  • marm-mcp-server/tests/test_runtime_cli.py
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: Lyellr88/marm-memory

Timestamp: 2026-07-24T03:31:56.646Z
Learning: Never commit changes without an explicit user request.
🪛 ast-grep (0.44.1)
scripts/test-scripts/docker-linux-bind-mount-smoke.sh

[warning] 7-7: A credential-bearing variable (e.g. PASSWORD, PASSWD, SECRET, TOKEN, API_KEY) is assigned a hardcoded string literal. Secrets committed to a script are exposed in source control, process listings, and shell history, and cannot be rotated without a code change. Read the value from a secrets manager or an injected environment variable at runtime instead (e.g. PASSWORD="${DB_PASSWORD:?must be set}"), and never commit the literal.
Context: api_key="marm-linux-smoke-key-4d82fe9a"
Note: [CWE-798] Use of Hard-coded Credentials.

(hardcoded-password-assignment-bash)

🪛 GitHub Check: GitGuardian Security Checks
scripts/test-scripts/docker-linux-bind-mount-smoke.sh

[error] 1-1: GitGuardian detected a hardcoded secret: 'Generic High Entropy Secret' (GitGuardian id: 35147140). Commit: 075869b. Remediate by removing/replacing the secret, rotating/revoking it, and optionally rewriting git history.

🪛 Shellcheck (0.11.0)
scripts/test-scripts/docker-linux-bind-mount-smoke.sh

[warning] 6-6: Declare and assign separately to avoid masking return values.

(SC2155)


[warning] 11-11: Declare and assign separately to avoid masking return values.

(SC2155)

🔇 Additional comments (6)
CONTRIBUTING.md (1)

228-240: LGTM!

marm-mcp-server/marm_mcp_server/services/key_management.py (1)

1-86: LGTM!

marm-mcp-server/marm_mcp_server/console/mcp_client.py (1)

33-37: LGTM!

marm-mcp-server/tests/test_cli_entrypoint.py (1)

84-84: LGTM!

marm-mcp-server/tests/test_runtime_cli.py (2)

120-121: LGTM!

Also applies to: 146-146, 206-220


223-243: 🎯 Functional Correctness

No change needed. The production output and start_background calls produce the expected strings/kwargs.

set -Eeuo pipefail

readonly image="${MARM_DOCKER_SMOKE_IMAGE:-lyellr88/marm-mcp-server:latest}"
readonly smoke_root="$(mktemp -d)"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

readonly var=$(cmd) masks mktemp/port-picker failures.

Per shellcheck SC2155, readonly smoke_root="$(mktemp -d)" and readonly port="$(python3 ...)" return the exit status of readonly, not the command substitution, so a failure silently leaves the variable empty instead of tripping set -e. An empty smoke_root would redirect data_dir/env_file to /data//marm.env on the runner.

🛠️ Proposed fix: declare and assign separately
-readonly smoke_root="$(mktemp -d)"
+smoke_root="$(mktemp -d)"
+readonly smoke_root
-readonly port="$(python3 - <<'PY'
+port="$(python3 - <<'PY'
 ...
 PY
-)"
+)"
+readonly port

Also applies to: 11-18

🧰 Tools
🪛 Shellcheck (0.11.0)

[warning] 6-6: Declare and assign separately to avoid masking return values.

(SC2155)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/test-scripts/docker-linux-bind-mount-smoke.sh` at line 6, Separate
declaration from command substitution assignment for smoke_root and port in the
script: declare each variable readonly first, then assign the command result so
mktemp or the port-picker failure status is preserved and triggers set -e. Apply
this to the readonly variables in the affected setup block, including smoke_root
and port, without changing their values or subsequent usage.

Source: Linters/SAST tools

Comment thread scripts/test-scripts/docker-linux-bind-mount-smoke.sh Outdated
@Lyellr88
Lyellr88 merged commit c6c4030 into MARM-main Jul 24, 2026
6 of 7 checks passed
@Lyellr88
Lyellr88 deleted the release/v2.28.0 branch July 24, 2026 07:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant