Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
46285ca
spec(mcp-server): add requirements
tzachbon Jan 26, 2026
0f78f57
spec(mcp-server): add technical design
tzachbon Jan 26, 2026
e00dfc2
spec(mcp-server): add implementation tasks
tzachbon Jan 26, 2026
1f02573
chore: initialize repo with bun and corepack
tzachbon Jan 26, 2026
fa88e45
feat(mcp): initialize mcp-server directory with bun project
tzachbon Jan 26, 2026
fde4749
feat(mcp): copy agent prompts to mcp-server assets
tzachbon Jan 26, 2026
644f4c6
feat(mcp): copy spec templates to mcp-server assets
tzachbon Jan 26, 2026
4b7395b
feat(mcp): create assets barrel with embedded text imports
tzachbon Jan 26, 2026
ae302a4
chore(mcp): pass quality checkpoint
tzachbon Jan 26, 2026
ff20fd6
feat(mcp): implement MCPLogger with stderr output
tzachbon Jan 26, 2026
fac6d19
feat(mcp): implement StateManager for .ralph-state.json
tzachbon Jan 26, 2026
f17c4c2
feat(mcp): implement FileManager for spec file operations
tzachbon Jan 26, 2026
551e7f9
chore(mcp): mark task 1.10 typecheck quality checkpoint complete
tzachbon Jan 26, 2026
32b78fb
feat(mcp): implement ralph_status and ralph_help tools
tzachbon Jan 26, 2026
3e51a92
feat(mcp): implement ralph_switch and ralph_cancel tools
tzachbon Jan 26, 2026
a3b691c
feat(mcp): implement ralph_start tool
tzachbon Jan 26, 2026
bff457e
docs(mcp): mark task 1.14 quality checkpoint complete
tzachbon Jan 26, 2026
5a14cb0
feat(mcp): implement ralph_complete_phase tool
tzachbon Jan 26, 2026
76dc2ad
feat(mcp): implement instruction tools for spec phases
tzachbon Jan 26, 2026
c63613f
feat(mcp): implement ralph_implement tool
tzachbon Jan 26, 2026
1f55978
feat(mcp): create tool registration barrel
tzachbon Jan 26, 2026
d21ce1d
spec(mcp-server): pass quality checkpoint 1.19 typecheck
tzachbon Jan 26, 2026
6bfa82d
feat(mcp): create MCP server entry point
tzachbon Jan 26, 2026
ca46a43
feat(mcp): add CLI flags for help and version
tzachbon Jan 26, 2026
e3c764a
feat(mcp): complete POC with Claude Desktop validation
tzachbon Jan 26, 2026
d834d49
refactor(mcp): extract instruction response builder
tzachbon Jan 26, 2026
9fa11c5
refactor(mcp): add comprehensive error handling
tzachbon Jan 26, 2026
e3ce5c4
spec(mcp-server): mark task 2.3 typecheck verification complete
tzachbon Jan 26, 2026
fdca545
refactor(mcp): add JSON schema validation for state files
tzachbon Jan 26, 2026
e215b2f
refactor(mcp): add edge case handling
tzachbon Jan 26, 2026
ce98a18
refactor(mcp): cleanup and finalize types
tzachbon Jan 26, 2026
0e6f190
test(mcp): set up test infrastructure
tzachbon Jan 26, 2026
75fa1ef
test(mcp): add unit tests for StateManager
tzachbon Jan 26, 2026
5ae6796
test(mcp): add unit tests for FileManager
tzachbon Jan 26, 2026
528e306
chore(mcp): pass quality checkpoint 3.4
tzachbon Jan 26, 2026
d12738a
test(mcp): add unit tests for MCPLogger
tzachbon Jan 26, 2026
4d495a4
test(mcp): add unit tests for tool handlers
tzachbon Jan 26, 2026
f4fd7ba
test(mcp): add integration tests for full workflow
tzachbon Jan 26, 2026
ba727df
chore(mcp): pass quality checkpoint 3.8
tzachbon Jan 26, 2026
f8ddc9d
feat(mcp): add build and install scripts
tzachbon Jan 26, 2026
19d8ebe
ci(mcp): add GitHub Actions release workflow
tzachbon Jan 26, 2026
f14d7ec
chore(mcp): pass quality checkpoint 4.3
tzachbon Jan 26, 2026
67b6846
chore(spec): complete task 4.4 - PR created and CI verified
tzachbon Jan 26, 2026
05921b5
chore(mcp): verify CI passing for PR #75
tzachbon Jan 26, 2026
ee56b32
fix(mcp): address review - no pending reviews
tzachbon Jan 26, 2026
af8b341
chore(spec): complete final validation for mcp-server
tzachbon Jan 26, 2026
905258e
docs(mcp): document completion status
tzachbon Jan 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions .github/workflows/mcp-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
name: MCP Server Release

on:
push:
tags:
- 'v*'

permissions:
contents: write

jobs:
build:
name: Build binaries
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: macos-latest
target: darwin-arm64
artifact: ralph-specum-mcp-darwin-arm64
- os: macos-13
target: darwin-x64
artifact: ralph-specum-mcp-darwin-x64
- os: ubuntu-latest
target: linux-x64
artifact: ralph-specum-mcp-linux-x64
- os: windows-latest
target: windows-x64
artifact: ralph-specum-mcp-windows-x64.exe

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: '1.2.0'

- name: Install dependencies
working-directory: mcp-server
run: bun install

- name: Build binary
working-directory: mcp-server
run: |
bun build src/index.ts --compile --target=bun-${{ matrix.target }} --outfile=dist/${{ matrix.artifact }}

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact }}
path: mcp-server/dist/${{ matrix.artifact }}

release:
name: Create GitHub Release
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true

- name: List artifacts
run: ls -la dist/

- name: Create Release
uses: softprops/action-gh-release@v2
with:
files: |
dist/ralph-specum-mcp-darwin-arm64
dist/ralph-specum-mcp-darwin-x64
dist/ralph-specum-mcp-linux-x64
dist/ralph-specum-mcp-windows-x64.exe
generate_release_notes: true
draft: false
prerelease: ${{ contains(github.ref, '-alpha') || contains(github.ref, '-beta') || contains(github.ref, '-rc') }}

publish-npm:
name: Publish to npm
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: '1.2.0'

- name: Setup Node.js for npm publish
uses: actions/setup-node@v4
with:
node-version: '22'
registry-url: 'https://registry.npmjs.org'

- name: Install dependencies
working-directory: mcp-server
run: bun install

- name: Publish to npm
working-directory: mcp-server
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
22
1 change: 1 addition & 0 deletions mcp-server/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
registry=https://registry.npmmirror.com/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Reconsider using a regional npm mirror as the default registry.

Using registry.npmmirror.com (a China-based npm mirror) as the default registry in a committed .npmrc can cause issues:

  1. CI/CD reliability: Builds running outside China may experience slower downloads or sync delays.
  2. Global contributors: Developers in other regions may face connectivity or availability issues.
  3. Package publication: Publishing should target the official npm registry (https://registry.npmjs.org/).

Consider removing this file or using the official npm registry. Individual developers can configure regional mirrors locally without committing them to the repository.

Suggested fix

Either remove mcp-server/.npmrc entirely, or use the official registry:

-registry=https://registry.npmmirror.com/
+registry=https://registry.npmjs.org/
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
registry=https://registry.npmmirror.com/
registry=https://registry.npmjs.org/
🤖 Prompt for AI Agents
In `@mcp-server/.npmrc` at line 1, The committed .npmrc sets the default registry
to "registry=https://registry.npmmirror.com/", which can cause cross-region CI
and contributor issues; either delete the .npmrc from the repo or update its
contents to the official npm registry by replacing that line with
"registry=https://registry.npmjs.org/" so repo-wide installs/publishes use the
standard registry while allowing developers to configure mirrors locally.

207 changes: 207 additions & 0 deletions mcp-server/bun.lock

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions mcp-server/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "@smart-ralph/ralph-specum-mcp",
"version": "0.1.0",
"type": "module",
"description": "MCP server for Ralph Specum spec-driven development",
"main": "src/index.ts",
"bin": {
"ralph-specum-mcp": "src/index.ts"
},
"scripts": {
"start": "bun run src/index.ts",
"build": "bun build src/index.ts --compile --outfile=dist/ralph-specum-mcp",
"build:all": "./scripts/build.sh",
"typecheck": "tsc --noEmit",
"test": "bun test"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.0.0",
"zod": "^3.25.0"
},
"devDependencies": {
"@types/bun": "latest",
"typescript": "^5.7.0"
},
"keywords": [
"mcp",
"model-context-protocol",
"ralph",
"spec-driven-development"
],
"author": "",
"license": "MIT"
}
42 changes: 42 additions & 0 deletions mcp-server/scripts/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash
set -e

VERSION=$(jq -r '.version' package.json)
OUTDIR="dist"

mkdir -p "$OUTDIR"

platforms=(
"bun-darwin-arm64"
"bun-darwin-x64"
"bun-linux-x64"
"bun-windows-x64"
)

built_count=0
failed_count=0

for platform in "${platforms[@]}"; do
echo "Building for $platform..."
outfile="$OUTDIR/ralph-specum-mcp-${platform#bun-}"
[[ "$platform" == *windows* ]] && outfile="${outfile}.exe"

if bun build --compile --target="$platform" ./src/index.ts --outfile "$outfile" 2>&1; then
built_count=$((built_count + 1))
echo " Success: $outfile"
else
failed_count=$((failed_count + 1))
echo " Failed: $platform (cross-compilation may require network access)"
fi
done

echo ""
echo "Build complete. $built_count succeeded, $failed_count failed."
echo "Binaries in $OUTDIR/:"
ls -la "$OUTDIR/" 2>/dev/null || echo "No binaries found"

# Exit with error if no binaries were built
if [ "$built_count" -eq 0 ]; then
echo "Error: No binaries were built"
exit 1
fi
40 changes: 40 additions & 0 deletions mcp-server/scripts/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/bin/bash
set -e

REPO="tzachbon/smart-ralph-mcp-server"
BINARY_NAME="ralph-specum-mcp"

# Detect OS and architecture
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)

case "$ARCH" in
x86_64) ARCH="x64" ;;
aarch64|arm64) ARCH="arm64" ;;
*) echo "Unsupported architecture: $ARCH"; exit 1 ;;
esac

case "$OS" in
darwin|linux) ;;
mingw*|msys*|cygwin*) OS="windows" ;;
*) echo "Unsupported OS: $OS"; exit 1 ;;
esac

# Get latest release
LATEST=$(curl -fsSL "https://api.github.com/repos/$REPO/releases/latest" | grep tag_name | cut -d'"' -f4)
ASSET="${BINARY_NAME}-${OS}-${ARCH}"
[[ "$OS" == "windows" ]] && ASSET="${ASSET}.exe"

# Download and install
INSTALL_DIR="${INSTALL_DIR:-/usr/local/bin}"
echo "Installing $BINARY_NAME $LATEST to $INSTALL_DIR..."

curl -fsSL "https://github.com/$REPO/releases/download/$LATEST/$ASSET" -o "/tmp/$BINARY_NAME"
chmod +x "/tmp/$BINARY_NAME"
sudo mv "/tmp/$BINARY_NAME" "$INSTALL_DIR/$BINARY_NAME"
Comment on lines +32 to +34
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Security: No checksum verification for downloaded binary.

Downloading and executing a binary without verifying its integrity poses a supply-chain attack risk. Consider publishing checksums with releases and verifying them before installation.

Suggested approach
  1. Publish a checksums.txt file with each release containing SHA256 hashes.
  2. Verify the downloaded binary:
 curl -fsSL "https://github.com/$REPO/releases/download/$LATEST/$ASSET" -o "/tmp/$BINARY_NAME"
+curl -fsSL "https://github.com/$REPO/releases/download/$LATEST/checksums.txt" -o "/tmp/checksums.txt"
+
+EXPECTED_HASH=$(grep "$ASSET" /tmp/checksums.txt | awk '{print $1}')
+ACTUAL_HASH=$(sha256sum "/tmp/$BINARY_NAME" | awk '{print $1}')
+if [[ "$EXPECTED_HASH" != "$ACTUAL_HASH" ]]; then
+  echo "Error: Checksum verification failed!"
+  rm -f "/tmp/$BINARY_NAME" "/tmp/checksums.txt"
+  exit 1
+fi
+
 chmod +x "/tmp/$BINARY_NAME"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
curl -fsSL "https://github.com/$REPO/releases/download/$LATEST/$ASSET" -o "/tmp/$BINARY_NAME"
chmod +x "/tmp/$BINARY_NAME"
sudo mv "/tmp/$BINARY_NAME" "$INSTALL_DIR/$BINARY_NAME"
curl -fsSL "https://github.com/$REPO/releases/download/$LATEST/$ASSET" -o "/tmp/$BINARY_NAME"
curl -fsSL "https://github.com/$REPO/releases/download/$LATEST/checksums.txt" -o "/tmp/checksums.txt"
EXPECTED_HASH=$(grep "$ASSET" /tmp/checksums.txt | awk '{print $1}')
ACTUAL_HASH=$(sha256sum "/tmp/$BINARY_NAME" | awk '{print $1}')
if [[ "$EXPECTED_HASH" != "$ACTUAL_HASH" ]]; then
echo "Error: Checksum verification failed!"
rm -f "/tmp/$BINARY_NAME" "/tmp/checksums.txt"
exit 1
fi
chmod +x "/tmp/$BINARY_NAME"
sudo mv "/tmp/$BINARY_NAME" "$INSTALL_DIR/$BINARY_NAME"
🤖 Prompt for AI Agents
In `@mcp-server/scripts/install.sh` around lines 32 - 34, The install script
downloads and installs "$ASSET" without verifying integrity; add SHA256 checksum
verification by downloading the release's checksums file (e.g., checksums.txt
for $LATEST), extract the expected hash for "$ASSET"/"$BINARY_NAME", compute the
downloaded file's SHA256 (for "/tmp/$BINARY_NAME"), compare them and abort on
mismatch before running chmod/mv; ensure the script logs a clear error and exits
non‑zero if verification fails and only proceeds to chmod +x and sudo mv when
the checksum matches.


echo "Installed! Add to your MCP client config:"
echo ""
echo ' "ralph-specum": {'
echo " \"command\": \"$INSTALL_DIR/$BINARY_NAME\""
echo ' }'
Loading