Skip to content

Commit 050be8b

Browse files
cdeustclaude
andcommitted
release: v3.14.11 — track automatised-pipeline rename + fix pool allowlist
Two fixes: 1. ingest_codebase blocking bug. mcp_client_pool.get_client() did not inject _extra_allowed_commands, so the upstream binary was rejected by the base allowlist. Pool now mirrors what ap_bridge.py applies on its bridge path. ingest_codebase now succeeds when mcp-connections.json points at a valid binary. 2. Track upstream binary rename. cdeust/automatised-pipeline v0.0.7 renamed the Rust binary from ai-architect-mcp to automatised-pipeline. Updated pipeline_installer (--bin flag, _BUILT_BINARY_REL), pipeline_discovery (_BINARY_CANDIDATES, _BUILT_RELATIVE), pipeline_install_release (asset naming), ap_bridge (allowlist), http_launcher / http_standalone (binary discovery). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 127a613 commit 050be8b

10 files changed

Lines changed: 69 additions & 24 deletions

File tree

.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "cortex",
33
"description": "Persistent memory for Claude Code — remembers across sessions automatically. Install and forget. Scientific retrieval backed by 41 published papers.",
4-
"version": "3.14.10",
4+
"version": "3.14.11",
55
"author": {
66
"name": "Clement Deust",
77
"email": "admin@ai-architect.tools"

CHANGELOG.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,45 @@ adheres to [Semantic Versioning](https://semver.org/).
66

77
## [Unreleased]
88

9+
## [3.14.11] — track automatised-pipeline binary rename + fix pool allowlist
10+
11+
### Fixed
12+
13+
- **`ingest_codebase` failed with `Command 'ai-architect-mcp' not in
14+
allowed list`.** The pool path in `mcp_client_pool.get_client()`
15+
instantiated `MCPClient` without injecting `_extra_allowed_commands`,
16+
while the bridge path in `ap_bridge.py` injected `{"node",
17+
"automatised-pipeline", "ai-architect-mcp"}` before connecting. The
18+
`ingest_codebase` codepath went through the pool, so the upstream
19+
binary was rejected by the base allowlist
20+
(`['cortex', 'mcp-server', 'node', 'npx', 'python', 'python3']`).
21+
Pool now mirrors the bridge's extension.
22+
23+
### Changed
24+
25+
- **Track upstream binary rename** (`automatised-pipeline` ≥ v0.0.7):
26+
the upstream Rust binary is now named `automatised-pipeline` (was
27+
`ai-architect-mcp`). Updated:
28+
- `pipeline_installer.py`: `--bin automatised-pipeline` and
29+
`_BUILT_BINARY_REL = "target/release/automatised-pipeline"`.
30+
- `pipeline_discovery.py`: dropped legacy `ai-architect-mcp` from
31+
`_BINARY_CANDIDATES`; `_BUILT_RELATIVE` updated.
32+
- `pipeline_install_release.py`: release-asset naming convention
33+
follows upstream (`automatised-pipeline-{os}-{arch}.tar.gz`).
34+
- `ap_bridge.py`: dropped `ai-architect-mcp` from
35+
`_extra_allowed_commands` (only `automatised-pipeline` + `node`).
36+
- `http_launcher.py`, `http_standalone.py`: binary discovery uses
37+
the new name.
38+
39+
### Migration notes
40+
41+
- Users running the upstream pipeline must update to v0.0.7 of
42+
`cdeust/automatised-pipeline` (binary renamed). Cortex's source
43+
build path (`pipeline_installer`) and prebuilt fast-path
44+
(`pipeline_install_release`) both target the new name.
45+
- Existing installs at `~/.claude/methodology/bin/mcp-server` keep
46+
working — the symlink target is rebuilt on next install.
47+
948
## [3.14.10] — self-locating plugin MCP launcher
1049

1150
### Fixed

mcp_server/infrastructure/ap_bridge.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,13 +223,12 @@ async def connect(self) -> bool:
223223
cfg = {**cfg, "callTimeoutMs": 0}
224224
self._client = MCPClient(cfg)
225225
# AP's binary is not in the default allowlist.
226-
# ``ai-architect-mcp`` is the crate name in
227-
# automatised-pipeline; ``node`` is for the
228-
# plugin-cache resolution path.
226+
# ``automatised-pipeline`` is the bin name shipped by
227+
# cdeust/automatised-pipeline ≥ v0.0.7; ``node`` is for
228+
# the plugin-cache resolution path.
229229
self._client._extra_allowed_commands = {
230230
"node",
231231
"automatised-pipeline",
232-
"ai-architect-mcp",
233232
}
234233
await self._client.connect()
235234
self._connected = True

mcp_server/infrastructure/mcp_client_pool.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ async def get_client(server_name: str) -> MCPClient:
6464
config = _load_server_config(server_name)
6565
client = MCPClient(config)
6666

67+
# Upstream MCP servers ship binaries that are not in the default
68+
# allowlist. Mirror the extension that ap_bridge.py applies on its
69+
# bridge path so the pool path is not silently rejected. Without
70+
# this, ingest_codebase fails with "Command not in allowed list"
71+
# even when mcp-connections.json correctly points at the binary.
72+
# source: ap_bridge.py L226-L233 — same set, same reason.
73+
client._extra_allowed_commands = {"node", "automatised-pipeline"}
74+
6775
await client.connect()
6876
_pool[server_name] = client
6977

mcp_server/infrastructure/pipeline_discovery.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
"cortex-pipeline",
4040
"automatised-pipeline",
4141
"ai-automatised-pipeline",
42-
"ai-architect-mcp",
4342
)
4443

4544
# Common source-checkout locations. Relative to each user's working dir

mcp_server/infrastructure/pipeline_install_release.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
1717
Asset naming convention (upstream contract)
1818
-------------------------------------------
19-
- ``ai-architect-mcp-{os}-{arch}.tar.gz`` containing the binary at
20-
the archive root as ``ai-architect-mcp``.
21-
- ``ai-architect-mcp-{os}-{arch}.tar.gz.sha256`` carrying the hex digest.
19+
- ``automatised-pipeline-{os}-{arch}.tar.gz`` containing the binary at
20+
the archive root as ``automatised-pipeline``.
21+
- ``automatised-pipeline-{os}-{arch}.tar.gz.sha256`` carrying the hex digest.
2222
- ``{os}`` ∈ {macos, linux}; ``{arch}`` ∈ {x86_64, aarch64}.
2323
"""
2424

@@ -98,7 +98,7 @@ def _find_assets(release: dict, tag: str) -> Optional[tuple[str, str]]:
9898
def _verify_and_extract(
9999
tar_path: str, expected_sha: str, dest_dir: str
100100
) -> Optional[str]:
101-
"""Verify SHA256, extract ``ai-architect-mcp`` to dest_dir, return path.
101+
"""Verify SHA256, extract ``automatised-pipeline`` to dest_dir, return path.
102102
103103
Refuses tar entries that escape dest_dir (path-traversal guard).
104104
"""
@@ -116,7 +116,7 @@ def _verify_and_extract(
116116
target = (dest / member.name).resolve()
117117
if not str(target).startswith(str(dest) + os.sep) and target != dest:
118118
return None
119-
if member.isfile() and Path(member.name).name == "ai-architect-mcp":
119+
if member.isfile() and Path(member.name).name == "automatised-pipeline":
120120
# filter="data" enforces safe extraction (no symlinks
121121
# outside dest, no special files, no setuid bits) —
122122
# required default in Python 3.14, opt-in earlier.
@@ -182,7 +182,7 @@ def try_install_prebuilt(symlink_dest: Path) -> dict:
182182
# Move the verified binary into the methodology bin dir under a
183183
# versioned name so subsequent fast-path installs don't clash.
184184
symlink_dest.parent.mkdir(parents=True, exist_ok=True)
185-
final = symlink_dest.parent / "ai-architect-mcp.prebuilt"
185+
final = symlink_dest.parent / "automatised-pipeline.prebuilt"
186186
shutil.move(binary, str(final))
187187
os.chmod(final, 0o755)
188188

mcp_server/infrastructure/pipeline_installer.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@
4242
logger = logging.getLogger(__name__)
4343

4444
_DEFAULT_GIT_URL = "https://github.com/cdeust/automatised-pipeline.git"
45-
_BUILT_BINARY_REL = "target/release/ai-architect-mcp"
45+
_BUILT_BINARY_REL = "target/release/automatised-pipeline"
4646
_DISABLE_ENV = "CORTEX_AUTO_INSTALL_PIPELINE"
4747

48-
# Minimum acceptable size for a successfully-built ai-architect-mcp
48+
# Minimum acceptable size for a successfully-built automatised-pipeline
4949
# binary. The release build is multi-MB; anything below this threshold
5050
# is a corrupted or 0-byte file (disk full, killed compiler, etc.).
5151
_MIN_BINARY_BYTES = 1_024 * 1_024
@@ -149,7 +149,7 @@ def _install_locked(force_rebuild: bool, git_url: Optional[str]) -> dict:
149149
if force_rebuild or not _binary_is_usable(binary):
150150
env = {**os.environ, "PATH": f"{_CARGO_HOME_BIN}:{os.environ.get('PATH', '')}"}
151151
rc, tail = _run_quiet(
152-
[cargo, "build", "--release", "--bin", "ai-architect-mcp"],
152+
[cargo, "build", "--release", "--bin", "automatised-pipeline"],
153153
cwd=str(src),
154154
env=env,
155155
timeout=1800,

mcp_server/server/http_launcher.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,12 @@ def _is_cortex_root(p: Path) -> bool:
9797

9898

9999
def _find_ap_binary() -> str | None:
100-
"""Locate a built ``ai-architect-mcp`` (automatised-pipeline).
100+
"""Locate a built ``automatised-pipeline`` (automatised-pipeline).
101101
102102
Checks, in order:
103103
1. ``CORTEX_AP_COMMAND`` already set — caller knows the path.
104-
2. A sibling dev checkout: ``~/Documents/Developments/automatised-pipeline/target/release/ai-architect-mcp``.
105-
3. ``ai-architect-mcp`` on ``PATH``.
104+
2. A sibling dev checkout: ``~/Documents/Developments/automatised-pipeline/target/release/automatised-pipeline``.
105+
3. ``automatised-pipeline`` on ``PATH``.
106106
107107
Returns the absolute binary path, or ``None`` if not buildable. We
108108
do NOT build here — building requires Rust + cmake and can take
@@ -112,11 +112,11 @@ def _find_ap_binary() -> str | None:
112112
return None # caller explicitly configured it — leave alone
113113
dev = (
114114
Path.home()
115-
/ "Documents/Developments/automatised-pipeline/target/release/ai-architect-mcp"
115+
/ "Documents/Developments/automatised-pipeline/target/release/automatised-pipeline"
116116
)
117117
if dev.is_file() and os.access(dev, os.X_OK):
118118
return str(dev)
119-
path_hit = shutil.which("ai-architect-mcp")
119+
path_hit = shutil.which("automatised-pipeline")
120120
return path_hit
121121

122122

@@ -162,7 +162,7 @@ def _ensure_ap_graph(dev_src: Path | None, env: dict) -> None:
162162
try:
163163
subprocess.Popen( # noqa: S603
164164
[
165-
bin_path or "ai-architect-mcp",
165+
bin_path or "automatised-pipeline",
166166
],
167167
stdin=subprocess.PIPE,
168168
stdout=subprocess.DEVNULL,

mcp_server/server/http_standalone.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,14 +281,14 @@ def _auto_enable_ap() -> None:
281281
dev = (
282282
Path.home()
283283
/ "Documents/Developments/automatised-pipeline"
284-
/ "target/release/ai-architect-mcp"
284+
/ "target/release/automatised-pipeline"
285285
)
286286
if dev.is_file() and os.access(dev, os.X_OK):
287287
bin_path = str(dev)
288288
else:
289289
import shutil as _sh
290290

291-
bin_path = _sh.which("ai-architect-mcp")
291+
bin_path = _sh.which("automatised-pipeline")
292292
if bin_path is None and not os.environ.get("CORTEX_AP_COMMAND"):
293293
return
294294
if bin_path and not os.environ.get("CORTEX_AP_COMMAND"):

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "neuro-cortex-memory"
7-
version = "3.14.10"
7+
version = "3.14.11"
88
description = "Scientifically-grounded memory system based on computational neuroscience research"
99
readme = "README.md"
1010
license = "MIT"

0 commit comments

Comments
 (0)