Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 22 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.git
.github
.specify
native
specs
docs
*.md
!README.md
node_modules
frontend/node_modules
frontend/dist
e2e
coverage*
*.test
*.out
.DS_Store
Thumbs.db
.vscode
.idea
mcpproxy
mcpproxy-tray
mcpproxy-dev
66 changes: 57 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ jobs:
# Build the prompt
PROMPT="Generate concise release notes for version ${VERSION} of MCPProxy (Smart MCP Proxy).

MCPProxy is a desktop application that acts as a smart proxy for AI agents using the Model Context Protocol (MCP). It provides intelligent tool discovery, token savings, and security quarantine for MCP servers.
MCPProxy is a smart proxy for AI agents using the Model Context Protocol (MCP). It provides intelligent tool discovery, token savings, and security quarantine for MCP servers. MCPProxy has two editions: Personal (desktop app) and Teams (multi-user server). Note which changes affect which edition if applicable.

Commits since last release:
${COMMITS}
Expand Down Expand Up @@ -225,6 +225,21 @@ jobs:
cgo: "1"
name: mcpproxy-darwin-arm64
archive_format: tar.gz
# Teams edition (Linux only) — uncomment when teams MVP is ready
# - os: ubuntu-latest
# goos: linux
# goarch: amd64
# cgo: "0"
# name: mcpproxy-teams-linux-amd64
# archive_format: tar.gz
# edition: teams
# - os: ubuntu-latest
# goos: linux
# goarch: arm64
# cgo: "0"
# name: mcpproxy-teams-linux-arm64
# archive_format: tar.gz
# edition: teams

runs-on: ${{ matrix.os }}

Expand Down Expand Up @@ -371,18 +386,23 @@ jobs:
VERSION=${GITHUB_REF#refs/tags/}
LDFLAGS="-s -w -X main.version=${VERSION} -X github.com/smart-mcp-proxy/mcpproxy-go/internal/httpapi.buildVersion=${VERSION}"

# Determine clean binary name
if [ "${{ matrix.goos }}" = "windows" ]; then
# Determine clean binary name and build flags
EDITION="${{ matrix.edition }}"
BUILD_TAGS=""
if [ "$EDITION" = "teams" ]; then
CLEAN_BINARY="mcpproxy-teams"
BUILD_TAGS="-tags teams"
elif [ "${{ matrix.goos }}" = "windows" ]; then
CLEAN_BINARY="mcpproxy.exe"
else
CLEAN_BINARY="mcpproxy"
fi

# Create clean core binary for archive
go build -ldflags "${LDFLAGS}" -o ${CLEAN_BINARY} ./cmd/mcpproxy
go build ${BUILD_TAGS} -ldflags "${LDFLAGS}" -o ${CLEAN_BINARY} ./cmd/mcpproxy

# Build tray binary for platforms with GUI support (macOS and Windows)
if [ "${{ matrix.goos }}" = "darwin" ] || [ "${{ matrix.goos }}" = "windows" ]; then
# Build tray binary for platforms with GUI support (macOS and Windows, personal only)
if [ "$EDITION" != "teams" ] && { [ "${{ matrix.goos }}" = "darwin" ] || [ "${{ matrix.goos }}" = "windows" ]; }; then
echo "Building mcpproxy-tray for ${{ matrix.goos }}..."

# Determine tray binary name
Expand Down Expand Up @@ -851,13 +871,13 @@ jobs:
- name: Upload versioned archive artifact
uses: actions/upload-artifact@v4
with:
name: versioned-${{ matrix.goos }}-${{ matrix.goarch }}
name: versioned-${{ matrix.edition || 'personal' }}-${{ matrix.goos }}-${{ matrix.goarch }}
path: mcpproxy-*-${{ matrix.goos }}-${{ matrix.goarch }}.${{ matrix.archive_format }}

- name: Upload latest archive artifact
uses: actions/upload-artifact@v4
with:
name: latest-${{ matrix.goos }}-${{ matrix.goarch }}
name: latest-${{ matrix.edition || 'personal' }}-${{ matrix.goos }}-${{ matrix.goarch }}
path: mcpproxy-latest-${{ matrix.goos }}-${{ matrix.goarch }}.${{ matrix.archive_format }}

- name: Upload macOS installer DMG
Expand Down Expand Up @@ -965,8 +985,36 @@ jobs:
name: installer-windows-${{ matrix.arch }}
path: signed/mcpproxy-setup-${{ github.ref_name }}-${{ matrix.arch }}.exe

build-docker:
runs-on: ubuntu-latest
needs: [build]
# Disabled until teams MVP is ready — uncomment to enable
if: false && startsWith(github.ref, 'refs/tags/v')
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v5
with:
context: .
push: true
build-args: |
VERSION=${{ github.ref_name }}
COMMIT=${{ github.sha }}
BUILD_DATE=${{ github.event.head_commit.timestamp }}
tags: |
ghcr.io/smart-mcp-proxy/mcpproxy-teams:${{ github.ref_name }}
ghcr.io/smart-mcp-proxy/mcpproxy-teams:latest

release:
needs: [build, sign-windows, generate-notes]
needs: [build, sign-windows, generate-notes] # add build-docker when teams MVP is ready
runs-on: ubuntu-latest
environment: production

Expand Down
33 changes: 31 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,32 @@ Only halt execution and ask a human IF:

MCPProxy is a Go-based desktop application that acts as a smart proxy for AI agents using the Model Context Protocol (MCP). It provides intelligent tool discovery, massive token savings, and built-in security quarantine against malicious MCP servers.

## Editions (Personal & Teams)

MCPProxy is built in two editions from the same codebase using Go build tags:

| Edition | Build Command | Binary | Distribution |
|---------|--------------|--------|-------------|
| **Personal** (default) | `go build ./cmd/mcpproxy` | `mcpproxy` | macOS DMG, Windows installer, Linux tar.gz |
| **Teams** | `go build -tags teams ./cmd/mcpproxy` | `mcpproxy-teams` | Docker image, .deb package, Linux tar.gz |

### Key Directories

| Directory | Purpose |
|-----------|---------|
| `cmd/mcpproxy/edition.go` | Default edition = "personal" |
| `cmd/mcpproxy/edition_teams.go` | Build-tagged override for teams |
| `cmd/mcpproxy/teams_register.go` | Teams feature registration entry point |
| `internal/teams/` | Teams-only code (all files have `//go:build teams`) |
| `native/macos/` | Future Swift tray app (placeholder) |
| `native/windows/` | Future C# tray app (placeholder) |

### Edition Detection

The binary self-identifies its edition:
- `mcpproxy version` → `MCPProxy v0.21.0 (personal) darwin/arm64`
- `/api/v1/status` → `{"edition": "personal", ...}`

## Architecture: Core + Tray Split

- **Core Server** (`mcpproxy`): Headless HTTP API server with MCP proxy functionality
Expand All @@ -39,9 +65,12 @@ MCPProxy is a Go-based desktop application that acts as a smart proxy for AI age

### Build
```bash
go build -o mcpproxy ./cmd/mcpproxy # Core server
go build -o mcpproxy ./cmd/mcpproxy # Core server (personal)
go build -tags teams -o mcpproxy-teams ./cmd/mcpproxy # Core server (teams)
GOOS=darwin CGO_ENABLED=1 go build -o mcpproxy-tray ./cmd/mcpproxy-tray # Tray app
make build # Frontend and backend
make build # Frontend and backend (personal)
make build-teams # Frontend and backend (teams)
make build-docker # Teams Docker image
./scripts/build.sh # Cross-platform build
```

Expand Down
32 changes: 32 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Build stage
FROM golang:1.24-alpine AS builder

RUN apk add --no-cache git nodejs npm make

WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download

COPY . .

# Build frontend
RUN cd frontend && npm ci && npm run build
RUN mkdir -p web/frontend && cp -r frontend/dist web/frontend/

# Build teams binary
ARG VERSION=dev
ARG COMMIT=unknown
ARG BUILD_DATE=unknown
RUN CGO_ENABLED=0 go build \
-tags teams \
-ldflags "-X main.version=${VERSION} -X main.commit=${COMMIT} -X main.date=${BUILD_DATE} -X github.com/smart-mcp-proxy/mcpproxy-go/internal/httpapi.buildVersion=${VERSION} -s -w" \
-o /mcpproxy ./cmd/mcpproxy

# Runtime stage
FROM gcr.io/distroless/static-debian12

COPY --from=builder /mcpproxy /usr/local/bin/mcpproxy

EXPOSE 8080

ENTRYPOINT ["mcpproxy", "serve", "--listen", "0.0.0.0:8080"]
27 changes: 25 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MCPProxy Makefile

.PHONY: help build swagger swagger-verify frontend-build frontend-dev backend-dev clean test test-coverage test-e2e test-e2e-oauth lint dev-setup docs-setup docs-dev docs-build docs-clean
.PHONY: help build build-teams build-docker build-deb swagger swagger-verify frontend-build frontend-dev backend-dev clean test test-coverage test-e2e test-e2e-oauth lint dev-setup docs-setup docs-dev docs-build docs-clean

SWAGGER_BIN ?= $(HOME)/go/bin/swag
SWAGGER_OUT ?= oas
Expand All @@ -23,6 +23,11 @@ help:
@echo " make lint - Run linter"
@echo " make dev-setup - Install development dependencies (swag, frontend, Playwright)"
@echo ""
@echo "Teams Edition:"
@echo " make build-teams - Build Teams edition binary (with -tags teams)"
@echo " make build-docker - Build Teams Docker image"
@echo " make build-deb - Build Teams .deb package (TODO)"
@echo ""
@echo "Documentation Commands:"
@echo " make docs-setup - Install documentation dependencies"
@echo " make docs-dev - Start docs dev server (http://localhost:3000)"
Expand Down Expand Up @@ -86,10 +91,28 @@ backend-dev:
@echo "🚀 Run: ./mcpproxy-dev serve"
@echo "🌐 In dev mode, make sure frontend dev server is running on port 3000"

# Build Teams edition
build-teams: swagger frontend-build
@echo "🔨 Building Teams edition binary (version: $(VERSION))..."
go build -tags teams -ldflags "$(LDFLAGS)" -o mcpproxy-teams ./cmd/mcpproxy
@echo "✅ Teams build completed! Run: ./mcpproxy-teams serve"

# Build Teams Docker image
build-docker:
@echo "🐳 Building Teams Docker image (version: $(VERSION))..."
docker build --build-arg VERSION=$(VERSION) --build-arg COMMIT=$(COMMIT) --build-arg BUILD_DATE=$(BUILD_DATE) -t mcpproxy-teams:$(VERSION) -t mcpproxy-teams:latest .
@echo "✅ Docker image built: mcpproxy-teams:$(VERSION)"

# Build Teams .deb package (placeholder)
build-deb:
@echo "📦 Building Teams .deb package..."
@echo "⚠️ TODO: Implement deb package build (nfpm or dpkg-deb)"
@echo " See: https://nfpm.goreleaser.com/"

# Clean build artifacts
clean:
@echo "🧹 Cleaning build artifacts..."
rm -f mcpproxy mcpproxy-dev mcpproxy-tray
rm -f mcpproxy mcpproxy-dev mcpproxy-tray mcpproxy-teams
rm -rf frontend/dist frontend/node_modules web/frontend
go clean
@echo "✅ Cleanup completed"
Expand Down
5 changes: 5 additions & 0 deletions cmd/mcpproxy/edition.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package main

// Edition identifies which MCPProxy edition this binary is.
// This is the default value; teams edition overrides it via build tags.
var Edition = "personal"
7 changes: 7 additions & 0 deletions cmd/mcpproxy/edition_teams.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//go:build teams

package main

func init() {
Edition = "teams"
}
7 changes: 7 additions & 0 deletions cmd/mcpproxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"fmt"
"os"
"os/signal"
"runtime"
"strings"
"sync/atomic"
"syscall"
Expand All @@ -40,6 +41,7 @@ import (

clioutput "github.com/smart-mcp-proxy/mcpproxy-go/internal/cli/output"
"github.com/smart-mcp-proxy/mcpproxy-go/internal/config"
"github.com/smart-mcp-proxy/mcpproxy-go/internal/httpapi"
"github.com/smart-mcp-proxy/mcpproxy-go/internal/experiments"
"github.com/smart-mcp-proxy/mcpproxy-go/internal/logs"
"github.com/smart-mcp-proxy/mcpproxy-go/internal/registries"
Expand Down Expand Up @@ -96,6 +98,7 @@ func main() {
Short: "Smart MCP Proxy - Intelligent tool discovery and proxying for Model Context Protocol servers",
Version: version,
}
rootCmd.SetVersionTemplate(fmt.Sprintf("MCPProxy %s (%s) %s/%s\n", version, Edition, runtime.GOOS, runtime.GOARCH))

// Add global flags
rootCmd.PersistentFlags().StringVarP(&configFile, "config", "c", "", "Configuration file path")
Expand Down Expand Up @@ -469,9 +472,13 @@ func runServer(cmd *cobra.Command, _ []string) error {

logger.Info("Starting mcpproxy",
zap.String("version", version),
zap.String("edition", Edition),
zap.String("log_level", cmdLogLevel),
zap.Bool("log_to_file", cmdLogToFile))

// Pass edition to httpapi for status endpoint
httpapi.SetEdition(Edition)

// Override other settings from command line
cfg.DebugSearch = cmdDebugSearch

Expand Down
18 changes: 18 additions & 0 deletions cmd/mcpproxy/teams_register.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//go:build teams

package main

import (
"log"

"github.com/smart-mcp-proxy/mcpproxy-go/internal/teams"
)

func init() {
// Initialize all registered teams features.
// Individual feature packages (auth, workspace, etc.) register
// themselves via their own init() functions.
if err := teams.SetupAll(teams.Dependencies{}); err != nil {
log.Fatalf("failed to initialize teams features: %v", err)
}
}
Loading
Loading