Skip to content

Commit b6f294f

Browse files
Your Nameclaude
andcommitted
feat(mcp): universal cross-client launcher + OSS distribution prep
Code-Intelligence is launching as public OSS, not staying an internal dev-tool, so the "ci" MCP server needs to work the same way regardless of which agent/IDE spawns it, and the release/distribution story needs to actually be complete rather than partially wired. - scripts/mcp-launcher.sh: single launcher shared by Claude Code (.mcp.json), Cursor (.cursor/mcp.json), and VS Code (.vscode/mcp.json). Resolves in order: cached/local binary -> SHA256-verified GitHub Release download (Linux only, only when HEAD is exactly a released git tag, never guesses "latest") -> cargo build from source. A failed or corrupted download never gets executed but always falls back to building from source instead of dead-ending. - fix release.yml: the musl cross-build passed bare --no-default-features, which silently dropped the tier0-5 language grammars along with the intended embeddings feature; now scoped to --features tier0-5. Also adds SHA256SUMS generation and a GHCR Docker-image-publish job. - add root LICENSE (MIT) and `ci --version` (clap `version` attribute) so the launcher can sanity-check a downloaded binary's version. - docs/mcp-client-setup.md documents the launcher's resolution tiers and the Windsurf/JetBrains manual-paste snippets (global-only config, can't be checked into the repo). - retire .claude/hooks/ci-mcp-entrypoint.sh (Claude-only, superseded by the universal launcher's build-from-source tier). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent 2079011 commit b6f294f

13 files changed

Lines changed: 339 additions & 74 deletions

File tree

.claude/hooks/ci-mcp-entrypoint.sh

Lines changed: 0 additions & 48 deletions
This file was deleted.

.cursor/mcp.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"mcpServers": {
3+
"ci": {
4+
"command": "bash",
5+
"args": ["scripts/mcp-launcher.sh"]
6+
}
7+
}
8+
}

.github/workflows/release.yml

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jobs:
4343

4444
- name: Build (cross)
4545
if: matrix.cross
46-
run: cross build --release --bin ci --target ${{ matrix.target }} --no-default-features
46+
run: cross build --release --bin ci --target ${{ matrix.target }} --no-default-features --features tier0-5
4747

4848
- name: Build (native)
4949
if: ${{ !matrix.cross }}
@@ -70,8 +70,43 @@ jobs:
7070
path: dist
7171
merge-multiple: true
7272

73+
- name: Generate checksums
74+
working-directory: dist
75+
run: sha256sum ci-*.tar.gz > SHA256SUMS
76+
7377
- name: Publish release
7478
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
7579
with:
76-
files: dist/*.tar.gz
80+
files: |
81+
dist/*.tar.gz
82+
dist/SHA256SUMS
7783
generate_release_notes: true
84+
85+
docker:
86+
name: Publish container image
87+
runs-on: ubuntu-latest
88+
permissions:
89+
contents: read
90+
packages: write
91+
steps:
92+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
93+
94+
- name: Log in to GHCR
95+
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
96+
with:
97+
registry: ghcr.io
98+
username: ${{ github.actor }}
99+
password: ${{ secrets.GITHUB_TOKEN }}
100+
101+
- name: Resolve image tag
102+
id: version
103+
run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
104+
105+
- uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
106+
with:
107+
context: .
108+
file: Containerfile
109+
push: true
110+
tags: |
111+
ghcr.io/eilodon/code-intelligence:${{ steps.version.outputs.version }}
112+
ghcr.io/eilodon/code-intelligence:latest

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ __pycache__/
2727
# OS / editor
2828
.DS_Store
2929
Thumbs.db
30-
.vscode/
30+
.vscode/*
31+
!.vscode/mcp.json
3132
.idea/
3233
*.swp
3334
*.swo

.mcp.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"ci": {
1919
"type": "stdio",
2020
"command": "bash",
21-
"args": [".claude/hooks/ci-mcp-entrypoint.sh"],
21+
"args": ["scripts/mcp-launcher.sh"],
2222
"env": {}
2323
}
2424
}

.vscode/mcp.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"servers": {
3+
"ci": {
4+
"command": "bash",
5+
"args": ["scripts/mcp-launcher.sh"]
6+
}
7+
}
8+
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Eilodon
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,14 @@ ci index --project-root .
3232
ci serve --project-root .
3333
```
3434

35-
Tích hợp vào MCP client (ví dụ Claude Code) qua `.mcp.json`:
36-
37-
```json
38-
{
39-
"mcpServers": {
40-
"ci": {
41-
"type": "stdio",
42-
"command": "ci",
43-
"args": ["serve", "--project-root", "."]
44-
}
45-
}
46-
}
47-
```
35+
Repo đã có sẵn config cho Claude Code (`.mcp.json`), Cursor (`.cursor/mcp.json`)
36+
và VS Code (`.vscode/mcp.json`) — cả ba đều trỏ vào `scripts/mcp-launcher.sh`,
37+
một launcher dùng chung: tự tìm binary đã build/cache, tải bản prebuilt đã
38+
verify checksum nếu đang ở đúng git tag, hoặc build từ source nếu không có
39+
gì sẵn — clone repo về là chạy được ngay, không cần build tay bước 1 ở trên
40+
trước. Xem [`docs/mcp-client-setup.md`](docs/mcp-client-setup.md) để biết
41+
cách dùng với Windsurf/JetBrains (config toàn cục, không check-in vào repo
42+
được) và chi tiết cách launcher hoạt động.
4843

4944
> **Lưu ý**: `ci serve` tự động thêm `.codeindex/` vào `.gitignore` khi khởi động để tránh
5045
> commit DB vào repo.
@@ -194,8 +189,13 @@ reason = "core không được phụ thuộc server layer"
194189
## Deployment
195190

196191
- `cargo build --release` → binary tĩnh musl qua `.github/workflows/release.yml`, matrix:
197-
`x86_64-unknown-linux-musl`, `aarch64-unknown-linux-musl`, `aarch64-apple-darwin`.
198-
- `Containerfile` multi-stage (`rust:alpine``scratch`), image ~10MB.
192+
`x86_64-unknown-linux-musl`, `aarch64-unknown-linux-musl` (kèm `SHA256SUMS`),
193+
`aarch64-apple-darwin`. `scripts/mcp-launcher.sh` tự tải + verify checksum bản
194+
đúng platform khi checkout đang ở đúng git tag — xem
195+
[`docs/mcp-client-setup.md`](docs/mcp-client-setup.md).
196+
- `Containerfile` multi-stage (`rust:alpine``scratch`), image ~10MB, publish
197+
lên `ghcr.io/eilodon/code-intelligence` (tag theo version + `latest`) mỗi khi
198+
push git tag.
199199
- `compose.yaml` mẫu hardened (`read_only`, `cap_drop: ALL`, `no-new-privileges`, `pids_limit: 64`,
200200
`mem_limit: 256m`).
201201

@@ -216,4 +216,4 @@ Chi tiết resolver internals, ADR, migration plans nằm trong [`docs/`](docs/)
216216

217217
## License
218218

219-
MIT
219+
[MIT](LICENSE)

crates/ci-cli/src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use clap::{Parser, Subcommand};
66
#[derive(Parser)]
77
#[command(
88
name = "ci",
9-
about = "Code Intelligence — MCP server for codebase analysis"
9+
about = "Code Intelligence — MCP server for codebase analysis",
10+
version
1011
)]
1112
struct Cli {
1213
#[command(subcommand)]

docs/cloud-environment-setup.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ This must build to the **same path** `.mcp.json` expects:
6868
benefit here, since this binary is a local dev/dogfood tool, not a
6969
distributed artifact; keep this in sync with
7070
`.claude/hooks/session-start-build-ci.sh` and
71-
`.claude/hooks/ci-mcp-entrypoint.sh` if that ever changes).
71+
`scripts/mcp-launcher.sh` if that ever changes).
7272

7373
Keep it under Claude Code's ~5-minute Setup Script budget — 59s measured
7474
leaves a wide margin.
@@ -89,9 +89,11 @@ session before any cache exists, or right after the ~7-day cache expiry)
8989

9090
## What's already handled in this repo (defense in depth, not a substitute)
9191

92-
- `.claude/hooks/ci-mcp-entrypoint.sh``.mcp.json`'s actual entrypoint
93-
now. Execs the pre-built binary directly if present (no `cargo`
94-
involved, no risk of an unexpected rebuild reopening this exact race);
92+
- `scripts/mcp-launcher.sh``.mcp.json`'s actual entrypoint now (shared
93+
across every MCP client, not just Claude Code; see
94+
`docs/mcp-client-setup.md`). Execs an already-cached binary directly if
95+
present (no `cargo` involved, no risk of an unexpected rebuild reopening
96+
this exact race);
9597
only builds inline if the binary is missing outright.
9698
- `.claude/hooks/session-start-build-ci.sh` — still runs every session.
9799
Redundant with the Setup Script in the common case (no-op if `target/`

0 commit comments

Comments
 (0)