Skip to content

Release/v2.26.0 - #107

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

Release/v2.26.0#107
Lyellr88 merged 3 commits into
MARM-mainfrom
release/v2.26.0

Conversation

@Lyellr88

@Lyellr88 Lyellr88 commented Jul 22, 2026

Copy link
Copy Markdown
Owner

v2.26.0 - Managed Runtime CLI and Bundled Console

This release makes MARM easier to install, run, inspect, and manage locally.

  • Added the marm-memory CLI with managed start, stop, restart, status, logs, and doctor workflows.

  • Added named runtime profiles for standard, swarm, swarm-max, and trusted deployments.

  • Bundled MARM Console into the main marm-mcp-server package. marm-memory console now runs the local app without a
    separate Console backend checkout or Node install.

  • Added CLI workflows for Knowledge setup/builds, project indexing, maintenance, embedding migration, key generation,
    and diagnostics.

  • Added verified runtime process ownership, bounded logs, graceful shutdown behavior, and clear human-readable status
    output with stable --json automation output.

  • Hardened runtime polling, error reporting, lifecycle rate-limit handling, and Docker/Glama frontend build parity.

  • Updated docs and install guidance around the managed runtime and bundled Console.

No MCP tools were added or removed. HTTP and STDIO remain at 14 public tools.

Summary by CodeRabbit

  • New Features

    • Added the marm-memory CLI for starting, stopping, restarting, status/doctor, and knowledge setup, with managed runtime support.
    • Bundled the MARM Console into releases and added console controls for memories, sessions, logs, notebooks, projects, compaction, and concept graphs.
    • Introduced runtime profiles (standard, swarm, swarm-max, trusted) plus configurable rate limits, and improved dense concept-graph visualization.
    • Added runtime diagnostics via /internal/runtime/status and a runtime shutdown endpoint.
  • Bug Fixes

    • Hardened Console auth and health/SPA routing behavior, including clearer 404/503 handling.
  • Documentation

    • Updated install/upgrade, swarm/profile, and concept-graph setup instructions; added a technical product overview.

Lyellr88 added 2 commits July 21, 2026 06:43
Add the marm-memory lifecycle CLI, bundle the Console into the main package, and align runtime, documentation, and CI workflows around the managed local host.
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR introduces the marm-memory managed runtime CLI, bundles the MARM Console frontend and API into the MCP server, adds runtime diagnostics and lifecycle endpoints, updates knowledge setup and dependency checks, and revises release workflows and documentation.

Changes

Managed runtime and bundled Console

Layer / File(s) Summary
Runtime CLI and lifecycle
marm-mcp-server/marm_mcp_server/cli.py, marm-mcp-server/marm_mcp_server/core/*, marm-mcp-server/marm_mcp_server/endpoints/system.py
Adds product CLI commands, runtime state persistence, detached start/stop/restart flows, graceful shutdown, runtime status endpoints, and log maintenance.
Console storage, contracts, and APIs
marm-mcp-server/marm_mcp_server/console/*
Adds SQLite-backed memory and concept queries, MCP client plumbing, typed payloads, authentication, static hosting, and REST endpoints for Console domains.
Knowledge setup and diagnostics
marm-mcp-server/marm_mcp_server/services/*, marm-mcp-server/marm_mcp_server/utils/dependency_check.py
Adds optional spaCy setup, structured dependency checks, and aggregated status/doctor reports.
Frontend rendering and packaging
marm-console/artifacts/..., marm-mcp-server/marm_mcp_server/console/static/*, .github/workflows/publish-mcp.yml
Updates dense-graph visualization, adds bundled frontend assets, and builds/copies the frontend during validation and release jobs.
CLI documentation and architecture references
README.md, marm-mcp-server/README.md, marm-mcp-server/marm-docs/README.md, docs/*, CHANGELOG.md
Replaces legacy startup, migration, swarm, and knowledge setup commands with managed CLI workflows and adds a technical overview.
Release metadata and validation
.github/dependabot.yml, marm-mcp-server/pyproject.toml, marm-mcp-server/tests/*, scripts/check-file-length.py, CONTRIBUTING.md
Updates release metadata, removes archived dashboard references, adjusts source scanning, and adds runtime, Console, dependency, and bundled-UI tests.

Estimated code review effort: 5 (Critical) | ~120 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.

Comment thread marm-mcp-server/marm_mcp_server/cli.py Fixed
Comment thread marm-mcp-server/marm_mcp_server/cli.py Fixed
Comment thread marm-mcp-server/marm_mcp_server/console/app.py Fixed

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 78f87eaf79

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

Comment thread CHANGELOG.md

<details>
<summary><strong>Unreleased: Notebook Scratch Pad, Permanent Docs Store, and Chunking Rework (v2.25.0)</strong></summary>
<summary><strong>July 21st, 2026: Managed Runtime CLI and Bundled Console (v2.26.0)</strong></summary>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Bump all release metadata to v2.26.0

This changelog advertises a v2.26.0 release, but the package/runtime metadata is still 2.25.0; python scripts/find-versions.py reports pyproject.toml, server.json, __init__.py, settings.py, server.py, Docker metadata, README, and install docs still at 2.25.0. A release from this commit will either publish the old package version or fail because that version already exists, and the new CLI will report the wrong version, so update the full version set before tagging.

AGENTS.md reference: AGENTS.md:L39-L47

Useful? React with 👍 / 👎.

Comment thread marm-mcp-server/marm_mcp_server/cli.py Outdated
Comment on lines +524 to +525
if args.command == "key":
print(generate_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 Bypass auto-key generation for product key commands

When SERVER_HOST=0.0.0.0 and no MARM_API_KEY is set, importing settings auto-generates and saves a key unless the legacy --generate-key flag is present in sys.argv; this new marm-memory key generate path does not hit that guard, so the command can create ~/.marm/.env and print the auto-generated-key notice before printing a separate generated key. Please make the product key-generation command part of the bypass or delay settings import so a read-only key-generation command does not mutate the runtime key.

Useful? React with 👍 / 👎.

Comment on lines +71 to +72
process = subprocess.Popen(
[sys.executable, "-m", "marm_mcp_server.console.cli", "--serve"],

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 Propagate generated API keys to Console

For the default background marm-memory console launch, if the managed runtime is bound to 0.0.0.0 with no explicit MARM_API_KEY, settings auto-generates/loads the key into the runtime process but this Console subprocess only inherits os.environ; console/mcp_client.py sends Authorization only from os.environ, while MARM auth requires a bearer token on every non-public route once a key exists. In that environment the bundled Console starts but its MCP-backed API calls get 401s, so pass the generated key through or have the Console client read the same settings key.

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: 13

Caution

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

⚠️ Outside diff range comments (1)
README.md (1)

73-73: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Remove stale legacy profile flags from the deployment guidance.

The deployment summaries still advertise --swarm, --swarm-max, and --trusted, while the current managed CLI guidance uses marm-memory start --profile .... Align every mirror so users do not copy an obsolete or inconsistent invocation:

  • README.md#L73-L73: replace the legacy flags with --profile swarm, --profile swarm-max, and --profile trusted.
  • marm-mcp-server/README.md#L75-L75: apply the same profile syntax.
  • marm-mcp-server/marm-docs/README.md#L39-L39: apply the same profile syntax.
🤖 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 `@README.md` at line 73, Update the deployment summary entries in README.md
(lines 73-73), marm-mcp-server/README.md (lines 75-75), and
marm-mcp-server/marm-docs/README.md (lines 39-39) to replace --swarm,
--swarm-max, and --trusted with --profile swarm, --profile swarm-max, and
--profile trusted, keeping all three mirrors consistent.
🧹 Nitpick comments (1)
marm-mcp-server/marm_mcp_server/console/memory_store.py (1)

34-67: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Full entities table scan on every memory list/get call.

Unlike the relationships count above it (which pushes the memory_ids set into SQL via json_each), the second loop pulls every row of entities.source_memory_ids into Python and does the intersection there. This runs on every list_memories/get_memory call and scales linearly with total entity count regardless of how many memory ids were requested. Consider mirroring the SQL-side json_each approach used for relationships to avoid loading the whole table.

🤖 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/console/memory_store.py` around lines 34 -
67, Optimize _concept_link_counts by replacing the full
entities.source_memory_ids scan with a SQL-side json_each query filtered to the
requested memory_ids, mirroring the existing relationships query. Aggregate
matching source memory IDs directly in SQLite and add those counts to counts,
while preserving malformed JSON and sqlite error handling.
🤖 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 `@docs/TECHNICAL-OVERVIEW.md`:
- Line 215: Update the embedding migration instruction in the technical overview
to use the currently registered `marm-memory maintenance embeddings migrate`
command instead of the obsolete `marm-mcp-server --migrate-embeddings`
invocation, while preserving the stopped-process requirement and mixed-dimension
behavior.
- Line 3: Synchronize all release metadata to v2.26.0: update
docs/TECHNICAL-OVERVIEW.md:3, docs/INSTALL-LINUX.md:5,
docs/INSTALL-WINDOWS.md:5, marm-mcp-server/README.md:1, and
marm-mcp-server/marm-docs/README.md:1, then run python scripts/find-versions.py
to verify no stale version sources remain.
- Around line 283-285: Update the MARM Console section to describe `marm-memory
console` as the bundled packaged launch path, replacing language that
characterizes Console as only a separate development application or still being
packaged. Retain the distinction that contributors can run the separate
FastAPI/React/Vite development servers during active development.

In `@marm-mcp-server/marm_mcp_server/console/app.py`:
- Around line 61-66: Update the FastAPI app initialization around `app` to add
app-wide bearer-token authentication for every non-health route, using a
per-runtime token and allowing the health endpoint unauthenticated. Add
`TrustedHostMiddleware` configured from the console host settings so requests
with untrusted Host headers are rejected, while preserving the existing lifespan
and app metadata.

In `@marm-mcp-server/marm_mcp_server/console/cli.py`:
- Around line 39-48: Update _serve() so start_log_maintenance does not target
runtime_dir() / "console.log", which is actively streamed by run_console().
Disable maintenance for the active console log or use a separate rotated target,
while preserving the existing uvicorn startup behavior.

In `@marm-mcp-server/marm_mcp_server/console/concept_store.py`:
- Around line 61-101: The read paths including summary, search, neighborhood,
get_entity, build_runs, get_build_run, duplicates, and graph_overview must close
SQLite handles deterministically. Import and apply contextlib.closing around
each _connect result, while retaining the existing transaction context so
connections are closed after each operation rather than relying on garbage
collection.

In `@marm-mcp-server/marm_mcp_server/console/endpoints/concepts.py`:
- Around line 154-168: Update _run_concept_build to catch
mcp_client.McpRequestError alongside mcp_client.McpUnavailable and handle both
through the existing launch failure-update path. Preserve the current immediate
error status, mcp_unavailable error code behavior unless an established
request-error code is available, and ensure neither MCP exception escapes the
background thread without updating the job record.

In `@marm-mcp-server/marm_mcp_server/console/memory_store.py`:
- Around line 152-176: Parenthesize the OR expression in the compaction_role ==
"none" branch of list_memories so it remains grouped when combined with the
other clauses via AND. Preserve the existing filtering semantics for NULL or
"none" roles and ensure both result rows and total counts use the corrected
condition.
- Around line 15-67: The SQLite connections used by _connect callers and
_concept_link_counts must be explicitly closed rather than relying on the
connection context manager. Wrap each _connect(db_path) usage and the ad-hoc
sqlite3.connect(db_path) in contextlib.closing while preserving existing
commit/rollback behavior and error handling.

In `@marm-mcp-server/marm_mcp_server/console/models.py`:
- Around line 40-43: Update ProjectDeletePayload.confirm to require the same
explicit typed confirmation literal used by the other delete payloads, removing
the boolean default; then update the downstream delete_project/internal
projects-delete contract to accept and validate that string confirmation value
end-to-end.

In `@marm-mcp-server/marm_mcp_server/core/graph_supervisor.py`:
- Around line 92-103: Replace the `_lock.locked()`-based `"starting"`
determination in the graph status method with an explicit lifecycle state or a
synchronized snapshot. Ensure `state`, `_client`, and `_available` are read
consistently under the existing synchronization strategy so shutdown cannot be
reported as starting and contradictory `started`/`available` values cannot be
returned.

In `@marm-mcp-server/pyproject.toml`:
- Line 8: Update every release-version declaration in pyproject.toml,
marm_mcp_server.__init__, config.settings, and server.py from 2.25.0 to 2.26.0,
then run python scripts/find-versions.py to verify no stale version remains.

In `@marm-mcp-server/tests/test_http_rate_limit.py`:
- Around line 29-34: Strengthen the shutdown test around the runtime status and
shutdown requests by asserting the shutdown response content and performing a
follow-up status check that confirms the write queue/runtime is stopped. Ensure
the shutdown path does not leave persistent global state in shared runtime or
rate-limiter singletons that could affect later tests.

---

Outside diff comments:
In `@README.md`:
- Line 73: Update the deployment summary entries in README.md (lines 73-73),
marm-mcp-server/README.md (lines 75-75), and marm-mcp-server/marm-docs/README.md
(lines 39-39) to replace --swarm, --swarm-max, and --trusted with --profile
swarm, --profile swarm-max, and --profile trusted, keeping all three mirrors
consistent.

---

Nitpick comments:
In `@marm-mcp-server/marm_mcp_server/console/memory_store.py`:
- Around line 34-67: Optimize _concept_link_counts by replacing the full
entities.source_memory_ids scan with a SQL-side json_each query filtered to the
requested memory_ids, mirroring the existing relationships query. Aggregate
matching source memory IDs directly in SQLite and add those counts to counts,
while preserving malformed JSON and sqlite error handling.
🪄 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

Run ID: 5592b44b-fb5c-4d45-a10d-fad1adc200a2

📥 Commits

Reviewing files that changed from the base of the PR and between e9ce968 and 78f87ea.

⛔ Files ignored due to path filters (1)
  • marm-mcp-server/marm_mcp_server/console/static/favicon.svg is excluded by !**/*.svg
📒 Files selected for processing (64)
  • .github/dependabot.yml
  • .github/workflows/publish-mcp.yml
  • CHANGELOG.md
  • CONTRIBUTING.md
  • README.md
  • docs-site/app.js
  • docs/FAQ.md
  • docs/INSTALL-LINUX.md
  • docs/INSTALL-WINDOWS.md
  • docs/TECHNICAL-OVERVIEW.md
  • marm-console/README.md
  • marm-console/artifacts/marm-console/src/components/knowledge/GraphViz.tsx
  • marm-console/run-dev.ps1
  • marm-console/server/README.md
  • marm-console/server/__main__.py
  • marm-console/server/requirements.txt
  • marm-console/tests/conftest.py
  • marm-console/tests/test_concept_build_concurrency.py
  • marm-console/tests/test_concept_store.py
  • marm-console/tests/test_memory_dashboard_gap_routes.py
  • marm-console/tests/test_memory_mutation_routes.py
  • marm-console/tests/test_overview_health.py
  • marm-console/tests/test_project_routes.py
  • marm-mcp-server/README.md
  • marm-mcp-server/marm-docs/README.md
  • marm-mcp-server/marm_mcp_server/cli.py
  • marm-mcp-server/marm_mcp_server/console/__init__.py
  • marm-mcp-server/marm_mcp_server/console/__main__.py
  • marm-mcp-server/marm_mcp_server/console/app.py
  • marm-mcp-server/marm_mcp_server/console/cli.py
  • marm-mcp-server/marm_mcp_server/console/concept_store.py
  • marm-mcp-server/marm_mcp_server/console/core.py
  • marm-mcp-server/marm_mcp_server/console/endpoints/__init__.py
  • marm-mcp-server/marm_mcp_server/console/endpoints/compaction.py
  • marm-mcp-server/marm_mcp_server/console/endpoints/concepts.py
  • marm-mcp-server/marm_mcp_server/console/endpoints/logs.py
  • marm-mcp-server/marm_mcp_server/console/endpoints/memory.py
  • marm-mcp-server/marm_mcp_server/console/endpoints/notebook.py
  • marm-mcp-server/marm_mcp_server/console/endpoints/overview.py
  • marm-mcp-server/marm_mcp_server/console/endpoints/projects.py
  • marm-mcp-server/marm_mcp_server/console/endpoints/sessions.py
  • marm-mcp-server/marm_mcp_server/console/mcp_client.py
  • marm-mcp-server/marm_mcp_server/console/memory_store.py
  • marm-mcp-server/marm_mcp_server/console/models.py
  • marm-mcp-server/marm_mcp_server/console/static/assets/index-CPMGdUC9.js
  • marm-mcp-server/marm_mcp_server/console/static/assets/index-Q5uE8oOU.css
  • marm-mcp-server/marm_mcp_server/console/static/index.html
  • marm-mcp-server/marm_mcp_server/console/static/robots.txt
  • marm-mcp-server/marm_mcp_server/core/graph_supervisor.py
  • marm-mcp-server/marm_mcp_server/core/runtime_manager.py
  • marm-mcp-server/marm_mcp_server/core/shutdown_manager.py
  • marm-mcp-server/marm_mcp_server/endpoints/system.py
  • marm-mcp-server/marm_mcp_server/middleware/rate_limiting.py
  • marm-mcp-server/marm_mcp_server/server.py
  • marm-mcp-server/marm_mcp_server/services/knowledge_setup.py
  • marm-mcp-server/marm_mcp_server/services/runtime_status.py
  • marm-mcp-server/marm_mcp_server/utils/dependency_check.py
  • marm-mcp-server/pyproject.toml
  • marm-mcp-server/tests/test_bundled_console.py
  • marm-mcp-server/tests/test_http_rate_limit.py
  • marm-mcp-server/tests/test_knowledge_setup.py
  • marm-mcp-server/tests/test_runtime_cli.py
  • marm-mcp-server/tests/test_runtime_status.py
  • scripts/check-file-length.py
💤 Files with no reviewable changes (6)
  • marm-console/server/README.md
  • scripts/check-file-length.py
  • CONTRIBUTING.md
  • marm-console/server/main.py
  • marm-console/server/requirements.txt
  • docs-site/app.js

@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.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

🛑 Comments failed to post (13)
docs/TECHNICAL-OVERVIEW.md (3)

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

Synchronize all release version metadata to v2.26.0.

CHANGELOG.md declares v2.26.0, but these release-facing documents still advertise v2.25.0:

  • docs/TECHNICAL-OVERVIEW.md#L3-L3: change the implementation version to v2.26.0.
  • docs/INSTALL-LINUX.md#L5-L5: change the installation-guide version to v2.26.0.
  • docs/INSTALL-WINDOWS.md#L5-L5: change the installation-guide version to v2.26.0.
  • marm-mcp-server/README.md#L1-L1: update the package README version.
  • marm-mcp-server/marm-docs/README.md#L1-L1: regenerate/update the documentation mirror version.

As per coding guidelines, version bumps must update every enumerated version source and run python scripts/find-versions.py.

📍 Affects 5 files
  • docs/TECHNICAL-OVERVIEW.md#L3-L3 (this comment)
  • docs/INSTALL-LINUX.md#L5-L5
  • docs/INSTALL-WINDOWS.md#L5-L5
  • marm-mcp-server/README.md#L1-L1
  • marm-mcp-server/marm-docs/README.md#L1-L1
🤖 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 `@docs/TECHNICAL-OVERVIEW.md` at line 3, Synchronize all release metadata to
v2.26.0: update docs/TECHNICAL-OVERVIEW.md:3, docs/INSTALL-LINUX.md:5,
docs/INSTALL-WINDOWS.md:5, marm-mcp-server/README.md:1, and
marm-mcp-server/marm-docs/README.md:1, then run python scripts/find-versions.py
to verify no stale version sources remain.

Source: Coding guidelines


215-215: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Update the embedding migration command.

This still documents marm-mcp-server --migrate-embeddings, while marm-mcp-server/marm_mcp_server/cli.py:191-205 registers marm-memory maintenance embeddings migrate. Users following this overview can invoke the obsolete workflow.

🤖 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 `@docs/TECHNICAL-OVERVIEW.md` at line 215, Update the embedding migration
instruction in the technical overview to use the currently registered
`marm-memory maintenance embeddings migrate` command instead of the obsolete
`marm-mcp-server --migrate-embeddings` invocation, while preserving the
stopped-process requirement and mixed-dimension behavior.

283-285: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Describe the bundled Console architecture.

The overview says Console is a separate development application and is “still being packaged,” contradicting marm-console/README.md:22-28 and the v2.26.0 bundled-Console release objective. Update this section to document marm-memory console as the packaged launch path while retaining the separate contributor dev server distinction.

Also applies to: 305-316

🤖 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 `@docs/TECHNICAL-OVERVIEW.md` around lines 283 - 285, Update the MARM Console
section to describe `marm-memory console` as the bundled packaged launch path,
replacing language that characterizes Console as only a separate development
application or still being packaged. Retain the distinction that contributors
can run the separate FastAPI/React/Vite development servers during active
development.
marm-mcp-server/marm_mcp_server/console/app.py (1)

61-66: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the console app and nearby auth/middleware setup
git ls-files marm-mcp-server/marm_mcp_server/console
echo '--- app.py ---'
nl -ba marm-mcp-server/marm_mcp_server/console/app.py | sed -n '1,220p'
echo '--- search for auth / trusted host / cors in console package ---'
rg -n "TrustedHostMiddleware|CORSMiddleware|Authentication|Bearer|token|Host header|host header|Depends\(|APIKey|OAuth|middleware" marm-mcp-server/marm_mcp_server/console marm-mcp-server/marm_mcp_server -g '!**/__pycache__/**'

Repository: Lyellr88/marm-memory

Length of output: 1550


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the console package structure to find where routes are registered
ast-grep outline marm-mcp-server/marm_mcp_server/console --view expanded

Repository: Lyellr88/marm-memory

Length of output: 8971


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check whether the console exposes mutation endpoints and how they are mounted
rg -n "include_router|APIRouter|`@router`\.(get|post|put|patch|delete)|`@app`\.(get|post|put|patch|delete)" marm-mcp-server/marm_mcp_server/console marm-mcp-server/marm_mcp_server -g '!**/__pycache__/**'

Repository: Lyellr88/marm-memory

Length of output: 19788


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read the console entrypoint and route modules if they exist
fd -a -t f 'app.py|*.py' marm-mcp-server/marm_mcp_server/console marm-mcp-server/marm_mcp_server | sed -n '1,200p'

Repository: Lyellr88/marm-memory

Length of output: 456


🏁 Script executed:

#!/bin/bash
set -euo pipefail
nl -ba marm-mcp-server/marm_mcp_server/console/app.py | sed -n '1,220p'

Repository: Lyellr88/marm-memory

Length of output: 198


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- console/app.py ---'
sed -n '1,220p' marm-mcp-server/marm_mcp_server/console/app.py

printf '%s\n' '--- console/cli.py ---'
sed -n '1,220p' marm-mcp-server/marm_mcp_server/console/cli.py

printf '%s\n' '--- console/__main__.py ---'
sed -n '1,220p' marm-mcp-server/marm_mcp_server/console/__main__.py

Repository: Lyellr88/marm-memory

Length of output: 7156


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- console/app.py with line numbers ---'
python3 - <<'PY'
from pathlib import Path
path = Path("marm-mcp-server/marm_mcp_server/console/app.py")
for i, line in enumerate(path.read_text().splitlines(), 1):
    print(f"{i:4d}: {line}")
PY

Repository: Lyellr88/marm-memory

Length of output: 4338


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- search for authentication / trusted host / CORS in console ---'
rg -n "TrustedHostMiddleware|CORSMiddleware|Authentication|APIKey|Bearer|token|auth|host header|Host" marm-mcp-server/marm_mcp_server/console marm-mcp-server/marm_mcp_server -g '!**/__pycache__/**'

Repository: Lyellr88/marm-memory

Length of output: 50377


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
for rel in [
    "marm-mcp-server/marm_mcp_server/console/app.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/memory.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/sessions.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/logs.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/notebook.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/compaction.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/concepts.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/projects.py",
]:
    print(f"\n--- {rel} ---")
    text = Path(rel).read_text().splitlines()
    for i, line in enumerate(text, 1):
        if "Authorization" in line or "Depends" in line or "middleware" in line or "`@router`." in line or "`@app`." in line or "HTTPException" in line:
            print(f"{i:4d}: {line}")
PY

Repository: Lyellr88/marm-memory

Length of output: 5469


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- console auth / host / middleware search ---'
rg -n "TrustedHostMiddleware|CORSMiddleware|Authorization|Bearer|apiKey|Depends\(|middleware" marm-mcp-server/marm_mcp_server/console marm-mcp-server/marm_mcp_server -g '!**/__pycache__/**' | head -n 200

printf '%s\n' '--- console endpoints with decorators and imports ---'
python3 - <<'PY'
from pathlib import Path

for rel in [
    "marm-mcp-server/marm_mcp_server/console/endpoints/memory.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/sessions.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/logs.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/notebook.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/compaction.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/concepts.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/projects.py",
]:
    print(f"\n### {rel}")
    for i, line in enumerate(Path(rel).read_text().splitlines(), 1):
        if any(tok in line for tok in ("from fastapi", "`@router`.", "Authorization", "Depends(", "HTTPException")):
            print(f"{i:4d}: {line}")
PY

Repository: Lyellr88/marm-memory

Length of output: 50377


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path

targets = [
    "marm-mcp-server/marm_mcp_server/console/app.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/memory.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/sessions.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/logs.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/notebook.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/compaction.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/concepts.py",
    "marm-mcp-server/marm_mcp_server/console/endpoints/projects.py",
]
for rel in targets:
    print(f"\n--- {rel} ---")
    for i, line in enumerate(Path(rel).read_text().splitlines(), 1):
        if any(token in line for token in (
            "CORSMiddleware",
            "TrustedHostMiddleware",
            "Authorization",
            "Bearer",
            "Depends(",
            "APIKey",
            "apiKey",
            "middleware",
            "`@router`.",
            "`@app`.",
        )):
            print(f"{i:4d}: {line}")
PY

Repository: Lyellr88/marm-memory

Length of output: 2666


Broken Authentication (CWE-306): Missing Authentication for Critical Function

Reachability: External
● Entry
  marm-mcp-server/marm_mcp_server/server.py:49
  lifespan
│
▼
● Sink
  marm-mcp-server/marm_mcp_server/console/app.py

Protect the Console API with auth and Host validation The Console exposes mutable /api/* routes with no app-wide authentication or TrustedHostMiddleware. Loopback binding and CORS are not an access boundary here: a DNS-rebound page can still send same-origin requests, and MARM_CONSOLE_HOST can expose the same unauthenticated APIs on the network. Require a per-runtime bearer token for non-health routes and reject untrusted Host headers.

🤖 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/console/app.py` around lines 61 - 66, Update
the FastAPI app initialization around `app` to add app-wide bearer-token
authentication for every non-health route, using a per-runtime token and
allowing the health endpoint unauthenticated. Add `TrustedHostMiddleware`
configured from the console host settings so requests with untrusted Host
headers are rejected, while preserving the existing lifespan and app metadata.
marm-mcp-server/marm_mcp_server/console/cli.py (1)

39-48: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
ast-grep run --pattern 'def start_log_maintenance($$$) { $$$ }' --lang python marm-mcp-server/marm_mcp_server/core/runtime_manager.py
ast-grep run --pattern 'def bound_log_file($$$) { $$$ }' --lang python marm-mcp-server/marm_mcp_server/core/runtime_manager.py

Repository: Lyellr88/marm-memory

Length of output: 811


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== cli.py ==\n'
wc -l marm-mcp-server/marm_mcp_server/console/cli.py
sed -n '1,140p' marm-mcp-server/marm_mcp_server/console/cli.py

printf '\n== runtime_manager.py outline ==\n'
ast-grep outline marm-mcp-server/marm_mcp_server/core/runtime_manager.py --view expanded || true

printf '\n== runtime_manager.py relevant text ==\n'
rg -n "start_log_maintenance|bound_log_file|log" marm-mcp-server/marm_mcp_server/core/runtime_manager.py
sed -n '1,260p' marm-mcp-server/marm_mcp_server/core/runtime_manager.py

Repository: Lyellr88/marm-memory

Length of output: 13679


Avoid truncating the active console log in _serve() ``

start_log_maintenance(runtime_dir() / "console.log") rewrites the same file that run_console() is already streaming to via the inherited stdout fd. That can race with live writes and drop or garble console output; keep maintenance off the active log or point it at a rotated target.

🤖 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/console/cli.py` around lines 39 - 48, Update
_serve() so start_log_maintenance does not target runtime_dir() / "console.log",
which is actively streamed by run_console(). Disable maintenance for the active
console log or use a separate rotated target, while preserving the existing
uvicorn startup behavior.
marm-mcp-server/marm_mcp_server/console/concept_store.py (1)

61-101: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== File map =="
git ls-files marm-mcp-server/marm_mcp_server/console/concept_store.py
echo

echo "== Relevant lines in concept_store.py =="
sed -n '1,260p' marm-mcp-server/marm_mcp_server/console/concept_store.py | nl -ba | sed -n '1,260p'
echo

echo "== Search for connection handling in console package =="
rg -n "contextlib\.closing|with connection:|sqlite3\.connect|def _connect|def summary|def search|def neighborhood|def get_entity|def build_runs|def get_build_run|def duplicates|def graph_overview" marm-mcp-server/marm_mcp_server/console

Repository: Lyellr88/marm-memory

Length of output: 312


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== concept_store.py with line numbers =="
awk '{printf "%6d  %s\n", NR, $0}' marm-mcp-server/marm_mcp_server/console/concept_store.py | sed -n '1,260p'
echo

echo "== Connection-related helpers and read functions =="
rg -n "def _connect|def _schema_status|def summary|def search|def neighborhood|def get_entity|def build_runs|def get_build_run|def duplicates|def graph_overview|closing|sqlite3\.connect|connection\.close|with connection:|with closing" marm-mcp-server/marm_mcp_server/console/concept_store.py
echo

echo "== Other console files mentioning closing or sqlite connections =="
rg -n "closing|sqlite3\.connect|connection\.close|with connection:" marm-mcp-server/marm_mcp_server/console

Repository: Lyellr88/marm-memory

Length of output: 13537


Close concept-store connections deterministically with connection: only manages the transaction; it doesn’t close the SQLite handle. These read paths (summary, search, neighborhood, get_entity, build_runs, get_build_run, duplicates, graph_overview) rely on GC to release the FD, so a polling consumer can accumulate open handles. Wrap the connection in contextlib.closing as well.

🤖 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/console/concept_store.py` around lines 61 -
101, The read paths including summary, search, neighborhood, get_entity,
build_runs, get_build_run, duplicates, and graph_overview must close SQLite
handles deterministically. Import and apply contextlib.closing around each
_connect result, while retaining the existing transaction context so connections
are closed after each operation rather than relying on garbage collection.
marm-mcp-server/marm_mcp_server/console/endpoints/concepts.py (1)

154-168: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Background build thread only handles McpUnavailable, not McpRequestError.

core._mcp_tool_mutation catches both mcp_client.McpRequestError and mcp_client.McpUnavailable when talking to the MCP server. _run_concept_build only catches McpUnavailable. If the MCP server responds with an HTTP error (4xx/5xx → McpRequestError), the exception propagates unhandled inside the daemon thread — it's swallowed by Python's default thread excepthook, and the job record is never updated. The build then reports "queued"/"running" for up to _CONCEPT_BUILD_STALE_SECONDS (300s) before _stale_build_result finally marks it "error"/"stale_run", instead of surfacing the real failure immediately.

🐛 Proposed fix
 def _run_concept_build(job_id: str, payload: dict) -> None:
     payload["run_id"] = job_id
     try:
         mcp_client.post("marm_concept_build", payload, timeout=120.0)
-    except mcp_client.McpUnavailable:
+    except (mcp_client.McpUnavailable, mcp_client.McpRequestError) as exc:
         with _launching_concept_builds_lock:
             launch = _launching_concept_builds.get(job_id)
             if launch:
                 failed, _ = launch
                 failed.update(
                     status="error",
-                    error_code="mcp_unavailable",
+                    error_code="mcp_unavailable" if isinstance(exc, mcp_client.McpUnavailable) else "mcp_request_error",
                     finished_at=time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
                 )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

def _run_concept_build(job_id: str, payload: dict) -> None:
    payload["run_id"] = job_id
    try:
        mcp_client.post("marm_concept_build", payload, timeout=120.0)
    except (mcp_client.McpUnavailable, mcp_client.McpRequestError) as exc:
        with _launching_concept_builds_lock:
            launch = _launching_concept_builds.get(job_id)
            if launch:
                failed, _ = launch
                failed.update(
                    status="error",
                    error_code="mcp_unavailable" if isinstance(exc, mcp_client.McpUnavailable) else "mcp_request_error",
                    finished_at=time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
                )
🤖 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/console/endpoints/concepts.py` around lines
154 - 168, Update _run_concept_build to catch mcp_client.McpRequestError
alongside mcp_client.McpUnavailable and handle both through the existing launch
failure-update path. Preserve the current immediate error status,
mcp_unavailable error code behavior unless an established request-error code is
available, and ensure neither MCP exception escapes the background thread
without updating the job record.
marm-mcp-server/marm_mcp_server/console/memory_store.py (2)

15-67: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Does Python's sqlite3.Connection close the underlying database when used as a with context manager?

💡 Result:

No, Python's sqlite3.Connection does not close the underlying database connection when used as a with context manager [1][2][3]. The sqlite3 context manager is designed specifically for transaction control, not resource management [1][4]. When you use a connection object with a with statement, it performs the following actions upon exiting the block: - If the block finishes successfully, the context manager commits the transaction [1][2]. - If an exception occurs within the block, the context manager rolls back the transaction [1][2]. - It does not implicitly close the connection or open a new transaction [1][3]. Because the connection remains open after the with block concludes, you must manually call con.close to release the database resource [1][4][5]. Failure to do so may lead to resource leaks, such as open file handles [5]. As of Python 3.13, if a Connection object is garbage collected without being closed, a ResourceWarning will be emitted [1][6]. If you prefer to have the connection automatically closed upon exiting the block, you can use contextlib.closing: from contextlib import closing import sqlite3 with closing(sqlite3.connect('example.db')) as con: with con: # Perform database operations # The connection will be closed automatically when exiting the 'closing' block

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the file and inspect the relevant section with line numbers.
git ls-files marm-mcp-server/marm_mcp_server/console/memory_store.py
echo '---'
cat -n marm-mcp-server/marm_mcp_server/console/memory_store.py | sed -n '1,220p'

echo '--- SEARCH close/closing usages ---'
rg -n "contextlib\.closing|\.close\(\)|with _connect\(|sqlite3\.connect\(" marm-mcp-server/marm_mcp_server/console/memory_store.py marm-mcp-server/marm_mcp_server/console -g '*.py'

Repository: Lyellr88/marm-memory

Length of output: 12606


Close SQLite connections explicitly
with _connect(db_path) as connection: only commits/rolls back; it does not close the handle. These console queries can leave file descriptors open until GC runs. Wrap _connect() and the ad-hoc _concept_link_counts() connection in contextlib.closing or close them in finally.

🧰 Tools
🪛 ast-grep (0.44.1)

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

(use-jsonify)

🤖 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/console/memory_store.py` around lines 15 -
67, The SQLite connections used by _connect callers and _concept_link_counts
must be explicitly closed rather than relying on the connection context manager.
Wrap each _connect(db_path) usage and the ad-hoc sqlite3.connect(db_path) in
contextlib.closing while preserving existing commit/rollback behavior and error
handling.

152-176: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Missing parentheses break the compaction_role="none" filter combined with any other filter.

Line 171's clause "compaction_role IS NULL OR compaction_role = 'none'" is not parenthesized, unlike the is None branch at line 169. Since clauses are joined with AND, SQL's precedence (AND binds tighter than OR) turns WHERE compaction_role IS NULL OR compaction_role = 'none' AND session_name = ? into WHERE compaction_role IS NULL OR (compaction_role = 'none' AND session_name = ?). Any request combining compaction_role=none with session/project/platform/context_type/q will return extra rows from unrelated sessions/projects that merely have a NULL compaction_role, and the total count will be inflated the same way.

🐛 Proposed fix
     elif compaction_role == "none":
-        clauses.append("compaction_role IS NULL OR compaction_role = 'none'")
+        clauses.append("(compaction_role IS NULL OR compaction_role = 'none')")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

def list_memories(
    db_path: Path,
    *,
    q: str | None = None,
    session: str | None = None,
    project: str | None = None,
    platform: str | None = None,
    context_type: str | None = None,
    compaction_role: str | None = None,
    limit: int = 50,
    offset: int = 0,
) -> dict:
    limit = min(max(limit, 1), 200)
    offset = max(offset, 0)
    clauses: list[str] = []
    params: list[object] = []
    if compaction_role is None:
        clauses.append("(compaction_role IS NULL OR compaction_role != 'source')")
    elif compaction_role == "none":
        clauses.append("(compaction_role IS NULL OR compaction_role = 'none')")
    elif compaction_role == "compacted":
        clauses.append("compaction_role = 'source'")
    else:
        clauses.append("compaction_role = ?")
        params.append(compaction_role)
🤖 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/console/memory_store.py` around lines 152 -
176, Parenthesize the OR expression in the compaction_role == "none" branch of
list_memories so it remains grouped when combined with the other clauses via
AND. Preserve the existing filtering semantics for NULL or "none" roles and
ensure both result rows and total counts use the corrected condition.
marm-mcp-server/marm_mcp_server/console/models.py (1)

40-43: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

ProjectDeletePayload.confirm is a plain bool, unlike every other delete payload.

MemoryDeletePayload, MemoryBulkDeletePayload, SessionDeletePayload, BulkDeletePayload, LogDeletePayload, and NotebookDeletePayload all require confirm: Literal["DELETE"] (or "DELETE_ALL") as an explicit typed-in confirmation string to guard against accidental destructive calls. ProjectDeletePayload instead uses confirm: bool = False, defaulting to a value that's trivially true-able (e.g., any client bug that defaults booleans to True, or a generic "confirm" toggle reused across forms) without the same deliberate string-match safeguard. Project deletion is at least as destructive as the others — worth aligning it with the same Literal pattern.

♻️ Proposed fix
+from typing import Literal
+
 class ProjectDeletePayload(BaseModel):
     name: str
-    confirm: bool = False
+    confirm: Literal["DELETE"]

Note: endpoints/projects.py's delete_project forwards payload.model_dump() directly to the MCP internal/projects/delete operation, so the downstream contract would need to tolerate the string value instead of a bool.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

from typing import Literal

class ProjectDeletePayload(BaseModel):
    name: str
    confirm: Literal["DELETE"]
🤖 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/console/models.py` around lines 40 - 43,
Update ProjectDeletePayload.confirm to require the same explicit typed
confirmation literal used by the other delete payloads, removing the boolean
default; then update the downstream delete_project/internal projects-delete
contract to accept and validate that string confirmation value end-to-end.
marm-mcp-server/marm_mcp_server/core/graph_supervisor.py (1)

92-103: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Do not use _lock.locked() as the startup indicator.

_lock is also held by stop(). While shutdown clears _ready, this method can report "starting" even though the graph is stopping. Since _client and _available are read without synchronization, it can also return contradictory fields such as started: false with available: true. Track an explicit lifecycle state or capture a consistent snapshot under the existing synchronization strategy.

As per path instructions, Python reviews prioritize runtime correctness and async/concurrency safety.

🤖 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/core/graph_supervisor.py` around lines 92 -
103, Replace the `_lock.locked()`-based `"starting"` determination in the graph
status method with an explicit lifecycle state or a synchronized snapshot.
Ensure `state`, `_client`, and `_available` are read consistently under the
existing synchronization strategy so shutdown cannot be reported as starting and
contradictory `started`/`available` values cannot be returned.

Source: Path instructions

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

8-8: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
grep -n '^version' marm-mcp-server/pyproject.toml
rg -n 'SERVER_VERSION|__version__' marm-mcp-server/marm_mcp_server/__init__.py marm-mcp-server/marm_mcp_server/config/settings.py marm-mcp-server/marm_mcp_server/server.py

Repository: Lyellr88/marm-memory

Length of output: 801


Version bump is still missing marm-mcp-server/pyproject.toml, marm-mcp-server/marm_mcp_server/__init__.py, marm-mcp-server/marm_mcp_server/config/settings.py, and marm-mcp-server/marm_mcp_server/server.py still declare 2.25.0. Update all release-version sources to 2.26.0 and run python scripts/find-versions.py.

🤖 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/pyproject.toml` at line 8, Update every release-version
declaration in pyproject.toml, marm_mcp_server.__init__, config.settings, and
server.py from 2.25.0 to 2.26.0, then run python scripts/find-versions.py to
verify no stale version remains.

Source: Coding guidelines

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

29-34: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Shallow shutdown assertions — verify state isolation and add real assertions.

These two new checks only assert status_code == 200; they don't verify shutdown actually changed runtime state (e.g., write-queue stopped) or that no lingering global state from /internal/runtime/shutdown leaks into later tests reusing the same rate_limiter/runtime singletons. As per path instructions, "Do not write existence-check or coded-to-pass tests; prefer deep tests exercising real paths over broad shallow coverage," and tests should not be "non-isolated."

Consider asserting on response content (e.g., shutdown.json()) and/or a follow-up runtime_status check confirming the queue/runtime reflects the shutdown, and confirm shutdown_manager doesn't set any global flag that could affect subsequent tests in the same process.

🤖 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/tests/test_http_rate_limit.py` around lines 29 - 34,
Strengthen the shutdown test around the runtime status and shutdown requests by
asserting the shutdown response content and performing a follow-up status check
that confirms the write queue/runtime is stopped. Ensure the shutdown path does
not leave persistent global state in shared runtime or rate-limiter singletons
that could affect later tests.

Source: Path instructions

@Lyellr88

Copy link
Copy Markdown
Owner Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Address PR review findings across managed runtime lifecycle, Console authentication, SQLite reads, graph state reporting, and CLI diagnostics.

Synchronize v2.26.0 release metadata and documentation, preserve bounded logs and dynamic static assets, and expand regression coverage for the corrected behavior.
Comment thread marm-mcp-server/marm_mcp_server/cli.py Dismissed

@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: 1

🤖 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 `@marm-mcp-server/marm_mcp_server/cli.py`:
- Around line 37-43: Update _write_generated_api_key to preserve direct display
only for interactive stdout; refuse non-interactive or redirected output by
default, and require an explicit opt-in before emitting the generated key when
stdout is captured or piped. Keep the existing interactive message unchanged.
🪄 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

Run ID: 15212bb1-f44a-406e-878b-524a06d49e9f

📥 Commits

Reviewing files that changed from the base of the PR and between 78f87ea and b469066.

📒 Files selected for processing (31)
  • 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/tests/test_concept_store.py
  • marm-console/tests/test_memory_mutation_routes.py
  • marm-console/tests/test_overview_health.py
  • marm-mcp-server/Dockerfile
  • marm-mcp-server/README.md
  • marm-mcp-server/docker-compose.yml
  • marm-mcp-server/marm-docs/README.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/cli.py
  • marm-mcp-server/marm_mcp_server/console/concept_store.py
  • marm-mcp-server/marm_mcp_server/console/endpoints/concepts.py
  • marm-mcp-server/marm_mcp_server/console/mcp_client.py
  • marm-mcp-server/marm_mcp_server/console/memory_store.py
  • marm-mcp-server/marm_mcp_server/core/graph_supervisor.py
  • marm-mcp-server/marm_mcp_server/server.py
  • marm-mcp-server/pyproject.toml
  • marm-mcp-server/server.json
  • marm-mcp-server/tests/test_bundled_console.py
  • marm-mcp-server/tests/test_cli_entrypoint.py
  • marm-mcp-server/tests/test_graph_supervisor.py
  • marm-mcp-server/tests/test_runtime_cli.py
🚧 Files skipped from review as they are similar to previous changes (16)
  • marm-console/tests/test_overview_health.py
  • marm-mcp-server/pyproject.toml
  • marm-mcp-server/marm_mcp_server/console/endpoints/concepts.py
  • docs/TECHNICAL-OVERVIEW.md
  • marm-mcp-server/marm_mcp_server/console/mcp_client.py
  • docs/INSTALL-LINUX.md
  • marm-console/tests/test_concept_store.py
  • marm-mcp-server/marm_mcp_server/server.py
  • CHANGELOG.md
  • marm-mcp-server/marm-docs/README.md
  • marm-mcp-server/README.md
  • marm-mcp-server/marm_mcp_server/console/cli.py
  • README.md
  • marm-mcp-server/marm_mcp_server/console/app.py
  • marm-mcp-server/marm_mcp_server/console/concept_store.py
  • marm-mcp-server/tests/test_runtime_cli.py
📜 Review details
🧰 Additional context used
📓 Path-based instructions (9)
{marm-mcp-server/pyproject.toml,marm-mcp-server/server.json,marm-mcp-server/marm_mcp_server/__init__.py,marm-mcp-server/marm_mcp_server/config/settings.py,marm-mcp-server/marm_mcp_server/server.py,marm-mcp-server/Dockerfile,docker-compose.yml,README.md,docs/INSTALL-*.md}

📄 CodeRabbit inference engine (AGENTS.md)

When bumping the version, update every enumerated version source and run python scripts/find-versions.py; follow SemVer definitions for breaking changes, features, and fixes.

Files:

  • marm-mcp-server/Dockerfile
  • docs/INSTALL-DOCKER.md
  • docs/INSTALL-PLATFORMS.md
  • marm-mcp-server/marm_mcp_server/__init__.py
  • marm-mcp-server/server.json
  • marm-mcp-server/marm_mcp_server/config/settings.py
  • docs/INSTALL-WINDOWS.md
**/*.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/INSTALL-DOCKER.md
  • docs/INSTALL-PLATFORMS.md
  • docs/INSTALL-WINDOWS.md
marm-mcp-server/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • marm-mcp-server/marm_mcp_server/__init__.py
  • marm-mcp-server/tests/test_graph_supervisor.py
  • marm-mcp-server/tests/test_cli_entrypoint.py
  • marm-mcp-server/tests/test_bundled_console.py
  • marm-mcp-server/marm_mcp_server/config/settings.py
  • marm-mcp-server/marm_mcp_server/core/graph_supervisor.py
  • marm-mcp-server/marm_mcp_server/console/memory_store.py
  • marm-mcp-server/marm_mcp_server/cli.py
marm-mcp-server/marm_mcp_server/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

marm-mcp-server/marm_mcp_server/**/*.py: All memory writes must go through the serialized asynchronous write queue; do not add bypass paths.
A semantic-store failure in marm_log_entry must never fail the 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.
Use one lazy-loaded, lock-serialized fastembed encoder with 512 dimensions; writes must succeed when the encoder is unavailable.
Prefer the smallest change that solves the problem; avoid speculative abstractions and unrequested configuration flags.
Use minimal comments that explain only non-obvious reasons; never narrate the next line.
Keep orchestration in its current owner file and extract modules only at real architectural boundaries.

Files:

  • marm-mcp-server/marm_mcp_server/__init__.py
  • marm-mcp-server/marm_mcp_server/config/settings.py
  • marm-mcp-server/marm_mcp_server/core/graph_supervisor.py
  • marm-mcp-server/marm_mcp_server/console/memory_store.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/__init__.py
  • marm-mcp-server/tests/test_graph_supervisor.py
  • marm-mcp-server/tests/test_cli_entrypoint.py
  • marm-console/tests/test_memory_mutation_routes.py
  • marm-mcp-server/tests/test_bundled_console.py
  • marm-mcp-server/marm_mcp_server/config/settings.py
  • marm-mcp-server/marm_mcp_server/core/graph_supervisor.py
  • marm-mcp-server/marm_mcp_server/console/memory_store.py
  • marm-mcp-server/marm_mcp_server/cli.py
marm-mcp-server/{marm_mcp_server/endpoints/**/*.py,server.py,server_stdio.py,server.json,scripts/find-tools.py,tests/**/*.py,README.md,docs/**/*.md,marm_mcp_server/marm-docs/**/*.md}

📄 CodeRabbit inference engine (AGENTS.md)

When adding or removing an MCP tool, update the endpoint implementation, HTTP route and whitelist, STDIO registration or wrapper, server.json, canonical tool list, all full tool-list documentation and counts, and tests for both transports.

Files:

  • marm-mcp-server/tests/test_graph_supervisor.py
  • marm-mcp-server/tests/test_cli_entrypoint.py
  • marm-mcp-server/tests/test_bundled_console.py
  • marm-mcp-server/server.json
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 preserves at least 95% fidelity.
Every new MARM Console API route requires 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 merely to avoid implementation effort.

Files:

  • marm-mcp-server/tests/test_graph_supervisor.py
  • marm-mcp-server/tests/test_cli_entrypoint.py
  • marm-mcp-server/tests/test_bundled_console.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_graph_supervisor.py
  • marm-mcp-server/tests/test_cli_entrypoint.py
  • marm-console/tests/test_memory_mutation_routes.py
  • marm-mcp-server/tests/test_bundled_console.py
marm-mcp-server/marm_mcp_server/core/{graph_supervisor.py,graph_client.py}

📄 CodeRabbit inference engine (AGENTS.md)

The code-graph binary must run as a supervised child process over newline-delimited JSON-RPC, start lazily, and degrade on failure.

Files:

  • marm-mcp-server/marm_mcp_server/core/graph_supervisor.py
🪛 ast-grep (0.44.1)
marm-mcp-server/marm_mcp_server/console/memory_store.py

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

(use-jsonify)

🪛 GitHub Check: CodeQL
marm-mcp-server/marm_mcp_server/cli.py

[failure] 39-39: Clear-text logging of sensitive information
This expression logs sensitive data (password) as clear text.

🔇 Additional comments (15)
docs/INSTALL-DOCKER.md (1)

5-5: LGTM!

docs/INSTALL-PLATFORMS.md (1)

1-1: LGTM!

docs/INSTALL-WINDOWS.md (1)

5-5: LGTM!

Also applies to: 70-70, 79-79, 97-108, 296-296

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

28-29: LGTM!

Also applies to: 46-51, 69-79, 102-110, 126-135

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

125-125: LGTM!

Also applies to: 385-388

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

8-8: LGTM!

Also applies to: 44-70, 73-74, 116-116, 174-174, 195-195, 234-234, 272-272, 292-292, 352-352, 374-382, 402-402, 431-431, 441-441

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

1-5: LGTM!

Also applies to: 14-25, 28-35, 38-65, 68-79

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

18-24: LGTM!

Also applies to: 34-34, 46-46

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

341-363: LGTM!

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

17-20: LGTM!

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

6-6: LGTM!

Also applies to: 20-25

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

21-21: LGTM!

marm-mcp-server/Dockerfile (1)

68-68: LGTM!

marm-console/tests/test_memory_mutation_routes.py (1)

1-2: LGTM!

Also applies to: 176-191, 194-225

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

534-534: LGTM!

Also applies to: 652-652

Comment thread marm-mcp-server/marm_mcp_server/cli.py
@Lyellr88
Lyellr88 merged commit e66a0c5 into MARM-main Jul 22, 2026
6 of 7 checks passed
@Lyellr88
Lyellr88 deleted the release/v2.26.0 branch July 22, 2026 09:01
@coderabbitai coderabbitai Bot mentioned this pull request Aug 10, 2026
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.

2 participants