Skip to content

Commit 0676f77

Browse files
authored
Merge pull request #3 from drknowhow/feat/cross-project-tools
feat(2.31.0): cross-project tools - c3_project MCP tool
2 parents 74f3a79 + caa791c commit 0676f77

13 files changed

Lines changed: 1039 additions & 7 deletions

File tree

CHANGELOG.md

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

77
## [Unreleased]
88

9+
## [2.31.0] - 2026-06-09
10+
11+
Feature release. C3 tools can now reach **outside the current workspace** to
12+
discover and operate on *other* c3-installed projects. A new `c3_project` MCP
13+
tool lists/scans for projects that have a `.c3` directory and proxies the core
14+
C3 operations (search, read, compress, status, memory, impact, edits, validate,
15+
filter) against any of them — plus guarded writes (`edit`, `shell`, memory
16+
mutations) behind an explicit `allow_write=true`.
17+
18+
### Added
19+
20+
- `services/project_runtime.py` — shared, thread-safe `ProjectRuntimeCache`
21+
(LRU, `.c3`-validated) that builds one `C3Runtime` per foreign project via the
22+
existing `build_runtime`; plus `resolve_project()` (name-or-path resolution
23+
against the global registry) and `scan_for_c3()` / `discover_projects()`
24+
(registry + bounded filesystem scan for unregistered `.c3` projects).
25+
- `cli/tools/project.py` and the `c3_project` MCP tool — action-dispatch surface:
26+
discovery (`list`, `scan`, `info`, `register`, `unregister`), read ops
27+
(`search`, `read`, `compress`, `status`, `memory`, `impact`, `edits`,
28+
`validate`, `filter`), and guarded write ops (`edit`, `shell`, memory
29+
`add/update/delete`). Foreign mutations are logged to the *target* project's
30+
activity log and edit ledger.
31+
- `mcp__c3__c3_project` added to `_C3_MCP_ALLOW` in `cli/c3.py`.
32+
- `tests/test_project_tool.py` covering the resolver, discovery, runtime-cache
33+
LRU/validation, and the dispatcher (read proxy + write guard + audit).
34+
35+
### Changed
36+
37+
- `__version__` in `cli/c3.py` and `version` in `pyproject.toml` bumped to
38+
`2.31.0` (kept in sync).
39+
40+
### Why
41+
42+
Until now every C3 capability was scoped to the single project the MCP server
43+
was launched in. Cross-project work meant switching workspaces. `c3_project`
44+
lets an agent stay in one session, see which sibling projects have C3 installed,
45+
and search/read/edit across them — while keeping writes explicit and auditable
46+
on the project they land in.
47+
948
## [2.30.0] - 2026-05-07
1049

1150
Feature release. Adds first-class Bitbucket Data Center / Server (self-hosted

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ Per-project knobs for everything: budget thresholds, feature flag mode, edit led
166166

167167
## The MCP tool suite
168168

169-
C3 exposes 15 tools as a native MCP server. Your IDE calls them directly:
169+
C3 exposes 16 tools as a native MCP server. Your IDE calls them directly:
170170

171171
| Tool | What it does |
172172
|---|---|
@@ -185,8 +185,9 @@ C3 exposes 15 tools as a native MCP server. Your IDE calls them directly:
185185
| `c3_agent` | Multi-step agentic workflows (review, investigate, refactor) |
186186
| `c3_edits` | Edit-ledger queries + version diffs + restore points |
187187
| `c3_bitbucket` | Bitbucket Data Center integration — PRs, branches, builds, repo admin (v2.30.0) |
188+
| `c3_project` | Cross-project — discover & operate on other c3-installed projects; guarded writes (v2.31.0) |
188189

189-
Every tool is **read-only safe in plan mode** (except `c3_edit`, `c3_shell`, and write actions on `c3_bitbucket`).
190+
Every tool is **read-only safe in plan mode** (except `c3_edit`, `c3_shell`, and write actions on `c3_bitbucket` / `c3_project`).
190191

191192
### Bitbucket Data Center / Server (v2.30.0)
192193

cli/c3.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
# Config
8686
CONFIG_DIR = ".c3"
8787
CONFIG_FILE = ".c3/config.json"
88-
__version__ = "2.30.0"
88+
__version__ = "2.31.0"
8989

9090

9191
def _command_deps() -> CommandDeps:
@@ -239,6 +239,7 @@ def print_savings(savings: dict):
239239
"mcp__c3__c3_memory", "mcp__c3__c3_validate", "mcp__c3__c3_edit",
240240
"mcp__c3__c3_agent", "mcp__c3__c3_delegate", "mcp__c3__c3_edits",
241241
"mcp__c3__c3_impact", "mcp__c3__c3_shell", "mcp__c3__c3_bitbucket",
242+
"mcp__c3__c3_project",
242243
]
243244

244245
# Obsolete MCP tool names from earlier C3 versions. `c3 permissions clean`
@@ -4492,6 +4493,7 @@ def _uninstall_mcp_all(project_path: str):
44924493
- **Memory**: `c3_memory(action='recall')` — full recall. `index` + `fetch` for token-efficient two-step retrieval
44934494
- **Delegate**: `c3_delegate(task, backend='ollama|codex|gemini|claude|auto')` — offload to other models
44944495
- **Bitbucket** (v2.30.0+, when `c3 bitbucket login` has run): `c3_bitbucket(action='list_prs|get_pr|merge_pr|...')` — self-hosted Bitbucket Data Center / Server. Token in OS keyring; mutating actions auto-log to the edit ledger.
4496+
- **Cross-project** (v2.31.0+): `c3_project(action='list|scan|search|read|edit|...', project='<name|path>')` — discover and operate on OTHER c3-installed projects. Reads run freely; writes (edit/shell/memory) need `allow_write=true`.
44954497
44964498
## Self-Check
44974499
If you haven't called a c3_* tool in several turns during active development, re-engage

cli/docs.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1148,7 +1148,7 @@ <h3>Graceful Degradation</h3>
11481148

11491149
<!-- ─── MCP Tools ───────────────────── -->
11501150
<h2 id="mcp-tools">MCP Tools Reference</h2>
1151-
<p>C3 exposes 15 MCP tools. All core tools work without Ollama; delegate requires it. The Bitbucket integration is optional and activated via <code>c3 bitbucket login</code>.</p>
1151+
<p>C3 exposes 16 MCP tools. All core tools work without Ollama; delegate requires it. The Bitbucket integration is optional and activated via <code>c3 bitbucket login</code>.</p>
11521152

11531153
<h3>Discovery &amp; Compression</h3>
11541154
<table>

cli/mcp_server.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,65 @@ def finalize(fname, fargs, fresp, fsumm, **kw):
699699
)
700700

701701

702+
@mcp.tool()
703+
async def c3_project(
704+
action: str,
705+
project: str = "",
706+
query: str = "",
707+
file_path: str = "",
708+
symbols: Any = None,
709+
lines: Any = None,
710+
mode: str = "map",
711+
view: str = "health",
712+
top_k: int = 5,
713+
max_tokens: int = 1200,
714+
search_action: str = "code",
715+
mem_action: str = "recall",
716+
fact: str = "",
717+
category: str = "",
718+
fact_id: str = "",
719+
edits_action: str = "history",
720+
file: str = "",
721+
tag: str = "",
722+
limit: int = 50,
723+
target: str = "",
724+
old_string: str = "",
725+
new_string: str = "",
726+
summary: str = "",
727+
edits: str = "",
728+
replace_all: bool = False,
729+
tags: str = "",
730+
cmd: str = "",
731+
timeout: int = 60,
732+
scan_roots: str = "",
733+
allow_write: bool = False,
734+
ctx: Context = None,
735+
) -> str:
736+
"""CROSS-PROJECT — run C3 against OTHER c3-installed projects (read-only safe in plan mode).
737+
Discover: list (registry), scan (registry+filesystem), info, register, unregister.
738+
Read : search, read, compress, status, memory, impact, edits, validate, filter.
739+
Write : edit, shell, memory(add/update/delete) — require allow_write=true; logged to that project's ledger.
740+
project = registered name OR absolute path (.c3 required). list/scan need no project.
741+
search_action/mem_action/edits_action pick the sub-op for those verbs."""
742+
svc = _svc(ctx)
743+
744+
def finalize(fname, fargs, fresp, fsumm, **kw):
745+
return _finalize_response(ctx, fname, fargs, fresp, fsumm, **kw)
746+
747+
from cli.tools.project import handle_project
748+
return await asyncio.to_thread(
749+
handle_project, action, svc, finalize,
750+
project=project, query=query, file_path=file_path, symbols=symbols,
751+
lines=lines, mode=mode, view=view, top_k=top_k, max_tokens=max_tokens,
752+
search_action=search_action, mem_action=mem_action, fact=fact,
753+
category=category, fact_id=fact_id, edits_action=edits_action, file=file,
754+
tag=tag, limit=limit, target=target, old_string=old_string,
755+
new_string=new_string, summary=summary, edits=edits,
756+
replace_all=replace_all, tags=tags, cmd=cmd, timeout=timeout,
757+
scan_roots=scan_roots, allow_write=allow_write,
758+
)
759+
760+
702761
def main() -> None:
703762
"""Entry-point for the ``c3-mcp`` console script."""
704763
from services import error_reporting

0 commit comments

Comments
 (0)