Skip to content

feat(cortex): MCP stdio server (--mcp) exposing the semantic graph to LLMs#98

Merged
ApiliumDevTeam merged 23 commits into
mainfrom
feat/aingle-mcp-server
Jun 22, 2026
Merged

feat(cortex): MCP stdio server (--mcp) exposing the semantic graph to LLMs#98
ApiliumDevTeam merged 23 commits into
mainfrom
feat/aingle-mcp-server

Conversation

@ApiliumDevTeam

Copy link
Copy Markdown
Contributor

Summary

Adds an MCP (Model Context Protocol) server to aingle_cortex, enabling Claude Code / Claude Desktop to consume the aingle semantic graph as a context backend.

  • aingle-cortex --mcp serves MCP over stdio (logs to stderr; stdout reserved for JSON-RPC), reusing the existing AppState instead of binding TCP.
  • New shared src/service/ layer (Approach A): REST handlers and MCP tools call the same business logic, guaranteeing REST↔MCP parity.
  • 7 tools: aingle_ping, aingle_query_pattern, aingle_graph_stats, aingle_create_triple (write), aingle_verify_proof (ZK; returns valid:false for invalid proofs, not an error), and aingle_dag_history (signed DAG provenance, gated by the dag feature).
  • Gated behind a new mcp cargo feature (rmcp 1.7 + schemars); the mcp feature does not require dag — the dag tool is registered via a separate merged tool-router only when dag is on.
  • Running without the mcp feature and passing --mcp exits non-zero with a clear error.

Implementation notes

  • Built feature-first: scaffold → error mapping → service-extraction pattern → one tool per capability, each as a thin REST-handler delegation plus an MCP tool over the shared service fn.
  • DTOs reused as tool I/O with #[cfg_attr(feature = "mcp", derive(schemars::JsonSchema))].
  • Write tool carries MCP annotations (read_only=false, idempotent=false — the graph keys triples by content hash, so a duplicate insert errors); read tools annotated read_only=true.

Test plan

  • cargo build -p aingle_cortex (default) — compiles
  • cargo build -p aingle_cortex --no-default-features --features "rest mcp" — compiles (mcp without dag)
  • cargo build -p aingle_cortex --features "mcp dag" — compiles
  • cargo test -p aingle_cortex --features "mcp dag" --lib — 160 passed, 0 failed
  • cargo test -p aingle_cortex --features "mcp dag" --test mcp_integration — in-process rmcp client round-trip (create→query) + tools/list incl. aingle_dag_history + stdout-hygiene subprocess test
  • New service code is clippy-clean; rustfmt applied
  • Manual smoke: register aingle-cortex --mcp --db ./data/graph.sled in a Claude MCP client and confirm tools appear and return data

Notes

  • Two pre-existing cluster_integration_test failures ("missing Ed25519 signature") reproduce on the base commit and are unrelated to this change.
  • Broad coverage of the remaining REST endpoints as MCP tools is a planned follow-up that replicates the same pattern.

ApiliumDevTeam and others added 22 commits June 22, 2026 12:59
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add crates/aingle_cortex/tests/mcp_integration.rs with two tests:
- in-process duplex client/server driving AingleMcp via an rmcp client
- subprocess stdout-hygiene check (stdout is JSON-RPC only)

Enable the rmcp `client` feature as a dev-dependency for the in-process
client (production `mcp` feature uses the server side only).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ns_batch, validate)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…trix

Gate `AuditEntry`/`Event` imports in rest/triples.rs behind
`#[cfg(any(feature = dag, feature = cluster))]` so the rest-only
(no dag/cluster) build is warning-free; all usages live in the
DAG/cluster write paths. Apply rustfmt to feature files and replace
`map_or(true, ..)` with `is_none_or` in service/query.rs (clippy).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ApiliumDevTeam

Copy link
Copy Markdown
Contributor Author

Update: broad coverage complete

The follow-up "broad coverage" is now included in this PR — the MCP surface went from 6 to 25 tools, all following the same extract→delegate→tool pattern with per-capability unit tests and REST↔MCP parity.

Tool inventory (25):

  • Triples: create_triple, batch_insert, get_triple, delete_triple (destructive), list_triples
  • Query: query_pattern, list_subjects, list_predicates, graph_stats
  • SPARQL: sparql (gated by the sparql feature, separate merged router)
  • Proofs/ZK: verify_proof, get_proof
  • DAG provenance: dag_history, dag_tips, dag_action, dag_chain, dag_stats, dag_prune (destructive) — gated by the dag feature
  • Skills: validate_skill, sandbox_create, sandbox_delete (destructive)
  • Agents/reasoning: agent_consistency, verify_assertions_batch, validate
  • plus ping

Feature-gated tools (dag, sparql) live in separate #[tool_router(router = ...)] blocks merged at construction, so the crate compiles with mcp standalone (verified: --no-default-features --features "rest mcp").

Verification: full build matrix (mcp-only / mcp+sparql / mcp+dag / default) green; 187 lib tests + 2 MCP integration tests pass; new code is clippy-clean and rustfmt-applied.

…mcp-server

# Conflicts:
#	crates/aingle_cortex/src/main.rs
@ApiliumDevTeam ApiliumDevTeam merged commit e8508ee into main Jun 22, 2026
16 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant