Skip to content

Commit 75f771a

Browse files
authored
Merge pull request #5 from cdeust/feat/mcp-registry-submission
chore(mcp): MCP Registry / Glama / Anthropic Directory submission (mcpb)
2 parents 3a73509 + 810494b commit 75f771a

11 files changed

Lines changed: 499 additions & 0 deletions

File tree

.github/workflows/release.yml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,69 @@ jobs:
127127
automatised-pipeline-${{ matrix.target_tag }}.tar.gz
128128
automatised-pipeline-${{ matrix.target_tag }}.tar.gz.sha256
129129
fail_on_unmatched_files: true
130+
131+
# Pack and publish the .mcpb bundle after all three platform binaries
132+
# are available on the GitHub Release.
133+
package_mcpb:
134+
name: package .mcpb bundle
135+
needs: build
136+
runs-on: ubuntu-latest
137+
steps:
138+
- uses: actions/checkout@v4
139+
140+
- name: Download platform binaries from release
141+
run: |
142+
TAG="${{ github.ref_name }}"
143+
BASE="https://github.com/cdeust/automatised-pipeline/releases/download/${TAG}"
144+
for TARGET in macos-aarch64 linux-x86_64 linux-aarch64; do
145+
curl -fsSL "${BASE}/automatised-pipeline-${TARGET}.tar.gz" \
146+
-o "automatised-pipeline-${TARGET}.tar.gz"
147+
done
148+
149+
- name: Assemble staging directory
150+
run: |
151+
STAGING="$(mktemp -d)/bundle"
152+
mkdir -p "$STAGING"
153+
154+
# Static bundle files
155+
cp manifest.json "$STAGING/"
156+
cp README.md "$STAGING/"
157+
cp LICENSE "$STAGING/"
158+
cp PRIVACY.md "$STAGING/"
159+
cp launch.sh "$STAGING/"
160+
chmod +x "$STAGING/launch.sh"
161+
162+
# icon.png — copy if present (maintainer replaces placeholder)
163+
if [ -f icon.png ]; then cp icon.png "$STAGING/"; fi
164+
165+
# Extract platform binaries into bin/<platform>/
166+
for TARGET in macos-aarch64 linux-x86_64 linux-aarch64; do
167+
mkdir -p "$STAGING/bin/${TARGET}"
168+
tar -xzf "automatised-pipeline-${TARGET}.tar.gz" \
169+
-C "$STAGING/bin/${TARGET}/"
170+
chmod +x "$STAGING/bin/${TARGET}/automatised-pipeline"
171+
done
172+
173+
echo "STAGING=$STAGING" >> "$GITHUB_ENV"
174+
175+
- name: Pack .mcpb bundle
176+
run: |
177+
# .mcpb is a ZIP archive with manifest.json at root.
178+
# Try the official packer first; fall back to zip.
179+
if npx -y @anthropic-ai/mcpb@latest pack "$STAGING" automatised-pipeline.mcpb 2>/dev/null; then
180+
echo "Packed via @anthropic-ai/mcpb"
181+
else
182+
cd "$STAGING" && zip -r "$OLDPWD/automatised-pipeline.mcpb" . && cd "$OLDPWD"
183+
echo "Packed via zip (mcpb CLI unavailable)"
184+
fi
185+
shasum -a 256 automatised-pipeline.mcpb | tee automatised-pipeline.mcpb.sha256
186+
ls -la automatised-pipeline.mcpb automatised-pipeline.mcpb.sha256
187+
188+
- name: Upload .mcpb to release
189+
uses: softprops/action-gh-release@v2
190+
with:
191+
tag_name: ${{ github.ref_name }}
192+
files: |
193+
automatised-pipeline.mcpb
194+
automatised-pipeline.mcpb.sha256
195+
fail_on_unmatched_files: true

.mcpbignore

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# .mcpbignore — files excluded from the .mcpb bundle.
2+
# The bundle only needs: manifest.json, icon.png, README.md, LICENSE,
3+
# PRIVACY.md, launch.sh, and the pre-built binaries under bin/.
4+
# Everything else is build-time, development, or documentation artefact.
5+
6+
target/
7+
tests/
8+
benches/
9+
stages/
10+
crates/
11+
docs/
12+
tools/
13+
.git/
14+
.github/
15+
.claude/
16+
.claude-plugin/
17+
src/
18+
19+
Cargo.toml
20+
Cargo.lock
21+
*.tar.gz
22+
*.mcpb
23+
*.sha256
24+
25+
CHANGELOG.md
26+
NOTES.md
27+
CONTRIBUTING.md
28+
CODE_OF_CONDUCT.md
29+
SECURITY.md
30+
31+
# MCP registry / distribution metadata (not needed at runtime)
32+
server.json
33+
glama.json
34+
.mcpbignore
35+
36+
# Editor / tool artefacts
37+
.DS_Store
38+
*.swp
39+
*.swo

PRIVACY.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Privacy Policy — automatised-pipeline
2+
3+
**Last updated: 2026-06-19**
4+
5+
automatised-pipeline is a local, offline Rust binary that runs entirely on your machine. This policy describes what data it processes, where that data lives, and what — if anything — leaves your machine.
6+
7+
---
8+
9+
## What data it processes
10+
11+
When you call `index_codebase` or `analyze_codebase`, the server reads source files in the directories you explicitly pass to it. It parses them with tree-sitter to extract symbols, imports, and call edges, then writes a LadybugDB property-graph database to the `output_dir` you specify.
12+
13+
The following data is processed locally:
14+
15+
- **Source file contents** — read in memory, parsed, and represented as graph nodes and edges. File contents are not stored verbatim; only structural metadata (symbol names, kinds, line ranges, qualified names) is persisted.
16+
- **Git commit history** — only when you call `index_history`. Author names, timestamps, and commit messages from your local git repository are written into the graph database.
17+
18+
No passwords, tokens, secrets, or environment variables are read. The server does not scan directories you do not pass to it.
19+
20+
---
21+
22+
## Where data is stored
23+
24+
All data is stored exclusively on your local filesystem, at the `output_dir` path you provide in each tool call. Nothing is written outside that directory. You control the location; you control deletion.
25+
26+
The graph database is a directory of LadybugDB files. Deleting that directory permanently removes all indexed data.
27+
28+
---
29+
30+
## What leaves your machine
31+
32+
**Nothing.** automatised-pipeline makes no network connections. It has no telemetry, no analytics, no crash reporting, and no license validation. It does not phone home.
33+
34+
The binary communicates exclusively over stdio (JSON-RPC 2.0) with the MCP host that spawned it — typically Claude Desktop or Claude Code. That communication is local inter-process communication on your machine.
35+
36+
---
37+
38+
## Your control
39+
40+
- **Stop indexing at any time** — kill the process. No partial writes persist as corrupt state; the server uses atomic file writes throughout.
41+
- **Delete all data** — remove the `output_dir` you passed to `index_codebase`. Nothing else to clean up.
42+
- **Audit the code** — the full source is at [https://github.com/cdeust/automatised-pipeline](https://github.com/cdeust/automatised-pipeline). Every dependency is declared in `Cargo.toml` with a documented justification comment.
43+
44+
---
45+
46+
## Contact
47+
48+
Questions about this policy: [admin@ai-architect.tools](mailto:admin@ai-architect.tools)

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
<!-- mcp-name: io.github.cdeust/automatised-pipeline -->
2+
13
<p align="center">
24
<img src="assets/banner.svg" alt="automatised-pipeline — codebase intelligence as an MCP server" width="100%"/>
35
</p>

glama.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"$schema": "https://glama.ai/mcp/schemas/server.json",
3+
"maintainers": ["cdeust"]
4+
}

icon.png

31 KB
Loading

launch.sh

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/bin/sh
2+
# launch.sh — MCPB bundle launcher for automatised-pipeline.
3+
#
4+
# Dispatches to the pre-built binary for the current platform.
5+
# Called by the MCP host (Claude Desktop, Claude Code) as the server
6+
# entry point when the .mcpb bundle is installed.
7+
#
8+
# Platform matrix (matches the release workflow target_tag names):
9+
# Darwin arm64 → bin/macos-aarch64/automatised-pipeline
10+
# Linux x86_64 → bin/linux-x86_64/automatised-pipeline
11+
# Linux aarch64 → bin/linux-aarch64/automatised-pipeline
12+
#
13+
# Usage (by MCP host): ${__dirname}/launch.sh
14+
# The MCP host sets __dirname to the extracted bundle root.
15+
16+
set -e
17+
18+
# Resolve bundle root: use __dirname if set by the MCP host, otherwise
19+
# derive it from $0 (works when run directly for testing).
20+
if [ -n "${__dirname:-}" ]; then
21+
BUNDLE_DIR="$__dirname"
22+
else
23+
BUNDLE_DIR="$(cd "$(dirname "$0")" && pwd)"
24+
fi
25+
26+
OS="$(uname -s)"
27+
ARCH="$(uname -m)"
28+
29+
case "${OS}-${ARCH}" in
30+
Darwin-arm64)
31+
BIN="$BUNDLE_DIR/bin/macos-aarch64/automatised-pipeline"
32+
;;
33+
Linux-x86_64)
34+
BIN="$BUNDLE_DIR/bin/linux-x86_64/automatised-pipeline"
35+
;;
36+
Linux-aarch64)
37+
BIN="$BUNDLE_DIR/bin/linux-aarch64/automatised-pipeline"
38+
;;
39+
*)
40+
echo "automatised-pipeline: unsupported platform: ${OS}-${ARCH}" >&2
41+
echo "Supported: Darwin-arm64, Linux-x86_64, Linux-aarch64" >&2
42+
exit 1
43+
;;
44+
esac
45+
46+
if [ ! -f "$BIN" ]; then
47+
echo "automatised-pipeline: binary not found at: $BIN" >&2
48+
echo "The .mcpb bundle may be corrupt. Re-install from:" >&2
49+
echo " https://github.com/cdeust/automatised-pipeline/releases" >&2
50+
exit 1
51+
fi
52+
53+
if [ ! -x "$BIN" ]; then
54+
chmod +x "$BIN"
55+
fi
56+
57+
exec "$BIN" "$@"

manifest.json

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
{
2+
"manifest_version": "0.4",
3+
"name": "automatised-pipeline",
4+
"display_name": "automatised-pipeline — Codebase Intelligence",
5+
"version": "0.5.0",
6+
"license": "MIT",
7+
"author": {
8+
"name": "Clement Deust",
9+
"email": "admin@ai-architect.tools",
10+
"url": "https://ai-architect.tools"
11+
},
12+
"description": "Codebase intelligence MCP server — index any repo into a property graph; 24 tools for agents.",
13+
"long_description": "automatised-pipeline is a Rust MCP server that indexes any Rust / Python / TypeScript codebase into a LadybugDB property graph, resolves imports and call chains across files, detects functional communities via Leiden-class community detection, traces execution flows from entry points, builds a hybrid BM25 + sparse TF-IDF + RRF search index, and exposes all of it to AI agents through 24 MCP tools. It is the codebase intelligence layer that sits between a finding and a PRD — read-only intelligence that tells the system what is true about the code so the next stage can reason without guessing.",
14+
"homepage": "https://github.com/cdeust/automatised-pipeline",
15+
"documentation": "https://github.com/cdeust/automatised-pipeline#readme",
16+
"support": "https://github.com/cdeust/automatised-pipeline/issues",
17+
"icon": "icon.png",
18+
"privacy_policies": [
19+
"https://github.com/cdeust/automatised-pipeline/blob/main/PRIVACY.md"
20+
],
21+
"compatibility": {
22+
"platforms": ["darwin", "linux"]
23+
},
24+
"server": {
25+
"type": "binary",
26+
"entry_point": "launch.sh",
27+
"mcp_config": {
28+
"command": "${__dirname}/launch.sh",
29+
"args": []
30+
}
31+
},
32+
"tools": [
33+
{
34+
"name": "health_check",
35+
"description": "Stage 0 — Healthcheck + handshake verification. Returns server identity, protocol version, and the registered stage count. Use this before calling any other stage tool to confirm the MCP is live."
36+
},
37+
{
38+
"name": "extract_finding",
39+
"description": "Stage 1a — Deterministic extraction. Normalizes one incoming finding (inline object or absolute path to a .json file) to the canonical schema, writes stage-1.source.json + stage-1.extracted.json atomically under <output_dir>/runs/<run_id>/findings/<finding_id>/, and creates or updates an index.json entry. Does NOT call an LLM."
40+
},
41+
{
42+
"name": "refine_finding",
43+
"description": "Stage 1b — Orchestrator-aware persistence. Reads an existing stage-1.extracted.json, composes stage-1.refined.json with the agent-produced refined_prompt + refinement payload, and updates index.json atomically. Pure persistence — no LLM call, no network."
44+
},
45+
{
46+
"name": "start_verification",
47+
"description": "Stage 2a — Create a clarification session for a refined finding. Verifies stage-1.refined.json exists and parses (schema_ok), then atomically writes stage-2.session.json with state 'open'. No LLM call."
48+
},
49+
{
50+
"name": "append_clarification",
51+
"description": "Stage 2b — Append one turn (agent_question or user_answer) to stage-2.session.json. Enforces the alternation invariant (two consecutive same-kind turns rejected) and the §3 state machine. Whole-file atomic rewrite per spec §12.3. No LLM call."
52+
},
53+
{
54+
"name": "finalize_verification",
55+
"description": "Stage 2c — Consume the user-ready signal. Computes sha256 over the canonical transcript bytes, writes stage-2.verified.json atomically, flips the session to 'finalized', and updates index.json with verified+stage2_path. No LLM call."
56+
},
57+
{
58+
"name": "abort_verification",
59+
"description": "Stage 2d — Kill a non-terminal session. Atomically rewrites stage-2.session.json with state 'aborted', aborted_at, and optional abort_reason. A fresh start_verification after abort overwrites the session."
60+
},
61+
{
62+
"name": "index_codebase",
63+
"description": "Stage 3a — Index a codebase. Walks the directory, parses source files with tree-sitter (Rust, Python, TypeScript), and persists a code-intelligence graph into a LadybugDB database at <output_dir>/graph/. Returns node/edge counts and elapsed time."
64+
},
65+
{
66+
"name": "query_graph",
67+
"description": "Stage 3a — Execute a Cypher query against an indexed code graph. The graph must have been created by a prior index_codebase call. Returns column names and rows."
68+
},
69+
{
70+
"name": "get_symbol",
71+
"description": "Stage 3a — Look up a symbol by qualified name in the code graph. Returns the node properties plus all incoming and outgoing edges. Qualified names follow the pattern 'file_path::symbol_name' (e.g., 'src/main.rs::handle_tool_call')."
72+
},
73+
{
74+
"name": "resolve_graph",
75+
"description": "Stage 3b — Resolve cross-file edges in the code graph. Runs AFTER index_codebase. Adds Imports, Calls, Implements, Extends, and Uses edges by matching string references to concrete target nodes. Returns resolution statistics including edge counts and resolution rate."
76+
},
77+
{
78+
"name": "lsp_resolve",
79+
"description": "Stage 3b-v2 — LSP-enhanced resolution. Queries a Language Server Protocol server (rust-analyzer, pyright, typescript-language-server) to resolve method calls on inferred types that the static resolver cannot handle. Runs AFTER resolve_graph."
80+
},
81+
{
82+
"name": "cluster_graph",
83+
"description": "Stage 3c — Run community detection and process tracing on an indexed+resolved graph. Groups symbols into functional communities via Louvain+C2 repair, detects entry points, and traces BFS call chains to create Process nodes. Requires resolve_graph to have been called first."
84+
},
85+
{
86+
"name": "get_processes",
87+
"description": "Stage 3c — List all detected processes (execution flows from entry points). Each process has an entry point, entry kind (main/test/handler/lib_entry), BFS depth, and symbol count. Requires cluster_graph to have been called first."
88+
},
89+
{
90+
"name": "get_impact",
91+
"description": "Stage 3c — Blast radius analysis for a symbol. Returns the symbol's reverse dependencies — callers (reverse Calls), importers (reverse Imports), users (reverse Uses), and implementors (reverse Implements) — each as a re-queryable handle you can traverse further via get_symbol/get_context/query_graph."
92+
},
93+
{
94+
"name": "search_codebase",
95+
"description": "Stage 3d — Search the code graph by keyword. Returns ranked symbols with name, kind, file path, community, process participation, and relevance score. Use this to find symbols without knowing their exact qualified names."
96+
},
97+
{
98+
"name": "get_context",
99+
"description": "Stage 3d — 360° symbol view. Returns the symbol plus ALL its relationships grouped by kind: what it imports, what imports it, what it calls, what calls it, what it implements, what implements it, community membership, and process participation."
100+
},
101+
{
102+
"name": "analyze_codebase",
103+
"description": "Stage 3 — All-in-one codebase analysis. Runs index_codebase + resolve_graph + cluster_graph in sequence, producing a fully searchable code graph in one call. Supports Rust, Python, and TypeScript (auto-detected by extension)."
104+
},
105+
{
106+
"name": "detect_changes",
107+
"description": "Stage 3e — Git diff impact analysis. Maps changed lines to affected symbols, communities, and processes in the code graph. Accepts either raw unified diff text OR base_ref/head_ref to run git diff internally. Returns affected symbols with a heuristic risk score (0.0-1.0)."
108+
},
109+
{
110+
"name": "index_history",
111+
"description": "History layer — ingests git commit history into an already-indexed graph as a traversable version spine. Creates Commit nodes with author/timestamp/message and Version nodes per (entity, commit) for every File and symbol a commit changed."
112+
},
113+
{
114+
"name": "prepare_prd_input",
115+
"description": "Stage 4 — Bundle graph intel (matched symbols, impacted communities, impacted processes, graph stats) into stage-4.prd_input.json for the PRD generator. TWO modes: FINDING mode (pass finding_id) or FEATURE mode (pass feature_description)."
116+
},
117+
{
118+
"name": "validate_prd_against_graph",
119+
"description": "Stage 6 — Validate a PRD against the resolved+clustered graph. Three axes: symbol hallucination, community-consistency, and process-impact contradiction. LLM-free. Read-only."
120+
},
121+
{
122+
"name": "check_security_gates",
123+
"description": "Stage 8 — Graph-aware security gates. Runs five checks on the changed_symbols list: S1 auth-critical community touch, S2 unsafe-symbol touch, S3 public-API surface change, S4 unresolved-import introduction, S5 test-coverage structural gap. LLM-free. Read-only."
124+
},
125+
{
126+
"name": "verify_semantic_diff",
127+
"description": "Stage 9 — Compare a post-implementation graph against a pre-implementation graph to flag regressions: nodes added/removed, edges added/removed, dangling references, new unresolved imports, and new strongly-connected cycles. Returns a heuristic regression_score."
128+
}
129+
],
130+
"tools_generated": true
131+
}

0 commit comments

Comments
 (0)