feat(cli): focused command surface, docker convenience commands, and … - #110
Conversation
…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>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📜 Recent review details
|
| 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
- Lyellr88/marm-memory#87: Related README mirror generation workflow.
- Lyellr88/marm-memory#89: Related CLI entrypoint and dispatch changes.
- Lyellr88/marm-memory#107: Related Console authentication and
run_consolebehavior.
🚥 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.
Comment @coderabbitai help to get the list of available commands.
There was a problem hiding this comment.
💡 Codex Review
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): |
There was a problem hiding this comment.
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 👍 / 👎.
| if args.as_json: | ||
| print_payload(latest, as_json=True) |
There was a problem hiding this comment.
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}", |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
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 winRuff format check is failing on this file.
Pipeline logs show
ruff format --checkfailing for this file, which will block CI/merge. Runruff format marm-mcp-server/marm_mcp_server/services/product_help.pyand 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
📒 Files selected for processing (39)
AGENTS.mdCHANGELOG.mdREADME.mddocs/INSTALL-DOCKER.mddocs/INSTALL-LINUX.mddocs/INSTALL-PLATFORMS.mddocs/INSTALL-WINDOWS.mddocs/TECHNICAL-OVERVIEW.mdmarm-console/artifacts/marm-console/src/App.tsxmarm-console/artifacts/marm-console/src/lib/marm-api.tsmarm-mcp-server/Dockerfilemarm-mcp-server/README.mdmarm-mcp-server/docker-compose.ymlmarm-mcp-server/marm-docs/FAQ.mdmarm-mcp-server/marm-docs/README.mdmarm-mcp-server/marm-docs/ROADMAP.mdmarm-mcp-server/marm_mcp_server/__init__.pymarm-mcp-server/marm_mcp_server/cli.pymarm-mcp-server/marm_mcp_server/config/settings.pymarm-mcp-server/marm_mcp_server/console/app.pymarm-mcp-server/marm_mcp_server/console/auth.pymarm-mcp-server/marm_mcp_server/console/cli.pymarm-mcp-server/marm_mcp_server/console/static/assets/index-D10wAXCq.jsmarm-mcp-server/marm_mcp_server/console/static/index.htmlmarm-mcp-server/marm_mcp_server/server.pymarm-mcp-server/marm_mcp_server/services/docker_cli.pymarm-mcp-server/marm_mcp_server/services/docker_commands.pymarm-mcp-server/marm_mcp_server/services/key_management.pymarm-mcp-server/marm_mcp_server/services/package_management.pymarm-mcp-server/marm_mcp_server/services/product_help.pymarm-mcp-server/marm_mcp_server/services/product_logs.pymarm-mcp-server/marm_mcp_server/services/product_workflows.pymarm-mcp-server/marm_mcp_server/services/projects_cli.pymarm-mcp-server/pyproject.tomlmarm-mcp-server/server.jsonmarm-mcp-server/tests/test_bundled_console.pymarm-mcp-server/tests/test_docker_commands.pymarm-mcp-server/tests/test_runtime_cli.pyscripts/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.ymldocs/TECHNICAL-OVERVIEW.mdmarm-mcp-server/marm_mcp_server/console/static/index.htmlmarm-mcp-server/marm_mcp_server/services/product_help.pydocs/INSTALL-PLATFORMS.mdmarm-mcp-server/pyproject.tomlmarm-mcp-server/marm_mcp_server/config/settings.pydocs/INSTALL-WINDOWS.mdmarm-mcp-server/marm_mcp_server/__init__.pymarm-mcp-server/marm_mcp_server/server.pymarm-mcp-server/Dockerfilemarm-mcp-server/marm-docs/FAQ.mdmarm-mcp-server/marm_mcp_server/services/product_logs.pydocs/INSTALL-LINUX.mdAGENTS.mdmarm-console/artifacts/marm-console/src/lib/marm-api.tsdocs/INSTALL-DOCKER.mdmarm-mcp-server/tests/test_bundled_console.pyCHANGELOG.mdmarm-mcp-server/marm_mcp_server/services/product_workflows.pymarm-mcp-server/marm_mcp_server/console/auth.pymarm-mcp-server/server.jsonmarm-console/artifacts/marm-console/src/App.tsxmarm-mcp-server/marm_mcp_server/services/key_management.pymarm-mcp-server/marm_mcp_server/services/projects_cli.pymarm-mcp-server/marm_mcp_server/console/cli.pymarm-mcp-server/marm_mcp_server/services/docker_cli.pymarm-mcp-server/marm_mcp_server/services/package_management.pyREADME.mdmarm-mcp-server/marm_mcp_server/console/app.pymarm-mcp-server/README.mdmarm-mcp-server/marm_mcp_server/console/static/assets/index-D10wAXCq.jsmarm-mcp-server/marm-docs/README.mdmarm-mcp-server/tests/test_docker_commands.pymarm-mcp-server/tests/test_runtime_cli.pymarm-mcp-server/marm_mcp_server/services/docker_commands.pymarm-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.mddocs/INSTALL-PLATFORMS.mddocs/INSTALL-WINDOWS.mdmarm-mcp-server/marm-docs/FAQ.mddocs/INSTALL-LINUX.mdAGENTS.mddocs/INSTALL-DOCKER.mdCHANGELOG.mdREADME.mdmarm-mcp-server/README.mdmarm-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 duringmarm_log_entrymust never fail the log write.
Graph and concept failures must never break the seven core memory tools.
marm_smart_recallmust 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.pymarm-mcp-server/marm_mcp_server/config/settings.pymarm-mcp-server/marm_mcp_server/__init__.pymarm-mcp-server/marm_mcp_server/server.pymarm-mcp-server/marm_mcp_server/services/product_logs.pymarm-mcp-server/marm_mcp_server/services/product_workflows.pymarm-mcp-server/marm_mcp_server/console/auth.pymarm-mcp-server/marm_mcp_server/services/key_management.pymarm-mcp-server/marm_mcp_server/services/projects_cli.pymarm-mcp-server/marm_mcp_server/console/cli.pymarm-mcp-server/marm_mcp_server/services/docker_cli.pymarm-mcp-server/marm_mcp_server/services/package_management.pymarm-mcp-server/marm_mcp_server/console/app.pymarm-mcp-server/marm_mcp_server/services/docker_commands.pymarm-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.pymarm-mcp-server/marm_mcp_server/config/settings.pymarm-mcp-server/marm_mcp_server/__init__.pymarm-mcp-server/marm_mcp_server/server.pymarm-mcp-server/marm_mcp_server/services/product_logs.pymarm-mcp-server/tests/test_bundled_console.pymarm-mcp-server/marm_mcp_server/services/product_workflows.pymarm-mcp-server/marm_mcp_server/console/auth.pymarm-mcp-server/marm_mcp_server/services/key_management.pymarm-mcp-server/marm_mcp_server/services/projects_cli.pymarm-mcp-server/marm_mcp_server/console/cli.pymarm-mcp-server/marm_mcp_server/services/docker_cli.pymarm-mcp-server/marm_mcp_server/services/package_management.pymarm-mcp-server/marm_mcp_server/console/app.pymarm-mcp-server/tests/test_docker_commands.pymarm-mcp-server/tests/test_runtime_cli.pymarm-mcp-server/marm_mcp_server/services/docker_commands.pymarm-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 withpytestfrommarm-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.
Usepytest.mark.skiponly for genuinely unavailable dependencies, never to avoid implementing or running a test.
Files:
marm-mcp-server/tests/test_bundled_console.pymarm-mcp-server/tests/test_docker_commands.pymarm-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.pymarm-mcp-server/tests/test_docker_commands.pymarm-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
toolsarray; 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 & AvailabilityFollow 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_maintenancerotates via truncation rather than rename; if it can rename, this should periodically reopenpathand detect via inode change.marm-mcp-server/marm_mcp_server/services/projects_cli.py (1)
70-72: 🩺 Stability & Availability
RuntimeRequestErroris already covered by the CLI error path.marm-mcp-server/marm_mcp_server/services/key_management.py (1)
60-68: 🗄️ Data Integrity & IntegrationNo change needed for
~/.marm/.envcontents.The managed key path is only assigned/read for
MARM_API_KEYin 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 winSensitive 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.pySession cookie sets
secure=False, and Console host is configurable off-loopback.
_host()inconsole/cli.pyletsMARM_CONSOLE_HOSTbind to0.0.0.0/::, not just127.0.0.1. If an operator does that (e.g. to reach the console from another machine on the LAN), thismarm_console_sessioncookie would travel in plaintext with noSecureflag. Worth confirming this is intentionally scoped to the documented loopback-only use case, or gatingsecureon 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 theApp.tsxsource 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!
…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>
There was a problem hiding this comment.
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 winSensitive 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.pyReject 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_keytreats a0return code fromicaclsas 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
📒 Files selected for processing (13)
AGENTS.mdCONTRIBUTING.mdmarm-mcp-server/marm_mcp_server/console/auth.pymarm-mcp-server/marm_mcp_server/console/mcp_client.pymarm-mcp-server/marm_mcp_server/services/docker_commands.pymarm-mcp-server/marm_mcp_server/services/key_management.pymarm-mcp-server/marm_mcp_server/services/product_help.pymarm-mcp-server/marm_mcp_server/services/product_workflows.pymarm-mcp-server/tests/test_bundled_console.pymarm-mcp-server/tests/test_cli_entrypoint.pymarm-mcp-server/tests/test_docker_commands.pymarm-mcp-server/tests/test_runtime_cli.pyscripts/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.pymarm-mcp-server/tests/test_cli_entrypoint.pymarm-mcp-server/marm_mcp_server/services/key_management.pymarm-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.pymarm-mcp-server/tests/test_cli_entrypoint.pymarm-mcp-server/marm_mcp_server/services/key_management.pymarm-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.
Amarm_log_entrysemantic-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_recallmust 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 inendpoints/, 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.pymarm-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 withpytestfrommarm-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 usepytest.mark.skiponly for genuinely unavailable dependencies.
Files:
marm-mcp-server/tests/test_cli_entrypoint.pymarm-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.pymarm-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 CorrectnessNo change needed. The production output and
start_backgroundcalls produce the expected strings/kwargs.
| set -Eeuo pipefail | ||
|
|
||
| readonly image="${MARM_DOCKER_SMOKE_IMAGE:-lyellr88/marm-mcp-server:latest}" | ||
| readonly smoke_root="$(mktemp -d)" |
There was a problem hiding this comment.
🩺 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 portAlso 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
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.
Summary by CodeRabbit
import-key.