Skip to content

Commit e04bf28

Browse files
authored
Merge pull request #323 from smart-mcp-proxy/rename-teams-to-server
rename: Teams → Server edition across entire codebase
2 parents 0d5904e + 8002545 commit e04bf28

71 files changed

Lines changed: 237 additions & 168 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/release.yml

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -225,21 +225,21 @@ jobs:
225225
cgo: "1"
226226
name: mcpproxy-darwin-arm64
227227
archive_format: tar.gz
228-
# Teams edition (Linux only) — uncomment when teams MVP is ready
228+
# Server edition (Linux only) — uncomment when server MVP is ready
229229
# - os: ubuntu-latest
230230
# goos: linux
231231
# goarch: amd64
232232
# cgo: "0"
233-
# name: mcpproxy-teams-linux-amd64
233+
# name: mcpproxy-server-linux-amd64
234234
# archive_format: tar.gz
235-
# edition: teams
235+
# edition: server
236236
# - os: ubuntu-latest
237237
# goos: linux
238238
# goarch: arm64
239239
# cgo: "0"
240-
# name: mcpproxy-teams-linux-arm64
240+
# name: mcpproxy-server-linux-arm64
241241
# archive_format: tar.gz
242-
# edition: teams
242+
# edition: server
243243

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

@@ -389,9 +389,9 @@ jobs:
389389
# Determine clean binary name and build flags
390390
EDITION="${{ matrix.edition }}"
391391
BUILD_TAGS=""
392-
if [ "$EDITION" = "teams" ]; then
393-
CLEAN_BINARY="mcpproxy-teams"
394-
BUILD_TAGS="-tags teams"
392+
if [ "$EDITION" = "server" ]; then
393+
CLEAN_BINARY="mcpproxy-server"
394+
BUILD_TAGS="-tags server"
395395
elif [ "${{ matrix.goos }}" = "windows" ]; then
396396
CLEAN_BINARY="mcpproxy.exe"
397397
else
@@ -402,7 +402,7 @@ jobs:
402402
go build ${BUILD_TAGS} -ldflags "${LDFLAGS}" -o ${CLEAN_BINARY} ./cmd/mcpproxy
403403
404404
# Build tray binary for platforms with GUI support (macOS and Windows, personal only)
405-
if [ "$EDITION" != "teams" ] && { [ "${{ matrix.goos }}" = "darwin" ] || [ "${{ matrix.goos }}" = "windows" ]; }; then
405+
if [ "$EDITION" != "server" ] && { [ "${{ matrix.goos }}" = "darwin" ] || [ "${{ matrix.goos }}" = "windows" ]; }; then
406406
echo "Building mcpproxy-tray for ${{ matrix.goos }}..."
407407
408408
# Determine tray binary name
@@ -418,14 +418,14 @@ jobs:
418418
# Code sign macOS binaries
419419
if [ "${{ matrix.goos }}" = "darwin" ]; then
420420
echo "Code signing macOS binary..."
421-
421+
422422
# Debug: List all available certificates
423423
echo "Available certificates:"
424424
security find-identity -v -p codesigning
425-
425+
426426
# Find the Developer ID certificate identity
427427
CERT_IDENTITY=$(security find-identity -v -p codesigning | grep "Developer ID Application" | head -1 | grep -o '"[^"]*"' | tr -d '"')
428-
428+
429429
# Verify we found a valid certificate
430430
if [ -n "${CERT_IDENTITY}" ]; then
431431
echo "✅ Found Developer ID certificate: ${CERT_IDENTITY}"
@@ -434,7 +434,7 @@ jobs:
434434
CERT_IDENTITY="${{ secrets.APPLE_TEAM_ID }}"
435435
echo "⚠️ Using fallback identity: ${CERT_IDENTITY}"
436436
fi
437-
437+
438438
# Validate entitlements file formatting (Apple's recommendation)
439439
echo "=== Validating entitlements file ==="
440440
if [ -f "scripts/entitlements.plist" ]; then
@@ -445,14 +445,14 @@ jobs:
445445
echo "❌ Entitlements file has formatting issues"
446446
exit 1
447447
fi
448-
448+
449449
# Convert to XML format if needed (Apple's recommendation)
450450
plutil -convert xml1 scripts/entitlements.plist
451451
echo "✅ Entitlements converted to XML format"
452452
else
453453
echo "⚠️ No entitlements file found"
454454
fi
455-
455+
456456
# Sign both binaries with proper Developer ID certificate, hardened runtime, and timestamp
457457
echo "=== Signing binaries with hardened runtime ==="
458458
@@ -527,7 +527,7 @@ jobs:
527527
echo "❌ All tray binary signing attempts failed"
528528
exit 1
529529
fi
530-
530+
531531
# Verify signing, hardened runtime, and timestamp using Apple's recommended methods
532532
echo "=== Verifying binary signatures (Apple's recommended verification) ==="
533533
@@ -558,7 +558,7 @@ jobs:
558558
echo "❌ Strict verification FAILED - will not pass notarization"
559559
exit 1
560560
fi
561-
561+
562562
# Check for secure timestamp (Apple's recommended check)
563563
echo "=== Checking for secure timestamp ==="
564564
TIMESTAMP_CHECK=$(codesign -dvv ${CLEAN_BINARY} 2>&1)
@@ -570,14 +570,14 @@ jobs:
570570
echo "Full output:"
571571
echo "$TIMESTAMP_CHECK"
572572
fi
573-
573+
574574
# Display detailed signature info
575575
codesign --display --verbose=4 ${CLEAN_BINARY}
576-
576+
577577
# Check entitlements formatting (Apple's recommendation)
578578
echo "=== Checking entitlements formatting ==="
579579
codesign --display --entitlements - ${CLEAN_BINARY} | head -10
580-
580+
581581
# Verify with spctl (Gatekeeper assessment) - expected to fail before notarization
582582
echo "=== Gatekeeper assessment (expected to fail before notarization) ==="
583583
if spctl --assess --verbose ${CLEAN_BINARY}; then
@@ -586,7 +586,7 @@ jobs:
586586
echo "⚠️ Gatekeeper assessment: REJECTED (expected - binary needs notarization)"
587587
echo "This is normal - the binary will pass after Apple completes notarization"
588588
fi
589-
589+
590590
echo "✅ Binary signed successfully with hardened runtime and timestamp"
591591
fi
592592
@@ -859,7 +859,7 @@ jobs:
859859
if [ -f .keychain_name ]; then
860860
TEMP_KEYCHAIN=$(cat .keychain_name)
861861
echo "Cleaning up keychain: ${TEMP_KEYCHAIN}"
862-
862+
863863
# Remove from search list and delete
864864
security delete-keychain "$TEMP_KEYCHAIN" 2>/dev/null || echo "Keychain already cleaned up"
865865
rm -f .keychain_name
@@ -988,7 +988,7 @@ jobs:
988988
build-docker:
989989
runs-on: ubuntu-latest
990990
needs: [build]
991-
# Disabled until teams MVP is ready — uncomment to enable
991+
# Disabled until server MVP is ready — uncomment to enable
992992
if: false && startsWith(github.ref, 'refs/tags/v')
993993
permissions:
994994
contents: read
@@ -1010,11 +1010,11 @@ jobs:
10101010
COMMIT=${{ github.sha }}
10111011
BUILD_DATE=${{ github.event.head_commit.timestamp }}
10121012
tags: |
1013-
ghcr.io/smart-mcp-proxy/mcpproxy-teams:${{ github.ref_name }}
1014-
ghcr.io/smart-mcp-proxy/mcpproxy-teams:latest
1013+
ghcr.io/smart-mcp-proxy/mcpproxy-server:${{ github.ref_name }}
1014+
ghcr.io/smart-mcp-proxy/mcpproxy-server:latest
10151015
10161016
release:
1017-
needs: [build, sign-windows, generate-notes] # add build-docker when teams MVP is ready
1017+
needs: [build, sign-windows, generate-notes] # add build-docker when server MVP is ready
10181018
runs-on: ubuntu-latest
10191019
environment: production
10201020

CLAUDE.md

Lines changed: 78 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ When operating to complete a task, adhere strictly to the following constraints
88

99
### Must-Do (Defaults & Assumptions)
1010
- **Zero Interruption Policy**: If a decision is needed and no explicit instruction exists, you MUST make an informed, safe assumption based on idiomatic Go best practices and document it in the PR/commit. Do NOT ask for human clarification mid-task.
11-
- **Test-Driven Progress**: You must write a failing Go test (`_test.go`) for every sub-task before implementing the feature.
11+
- **Test-Driven Progress**: You must write a failing Go test (`_test.go`) for every sub-task before implementing the feature.
1212
- **Graceful Fallbacks**: If an API or dependency lacks documentation, use mock interfaces or a simplified implementation rather than blocking the task.
1313
- **Continuous Logging**: Document every step completed in an `execution_log.md` within the current working directory to maintain state.
1414

@@ -28,23 +28,30 @@ Only halt execution and ask a human IF:
2828

2929
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.
3030

31-
## Editions (Personal & Teams)
31+
## Editions (Personal & Server)
3232

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

3535
| Edition | Build Command | Binary | Distribution |
3636
|---------|--------------|--------|-------------|
3737
| **Personal** (default) | `go build ./cmd/mcpproxy` | `mcpproxy` | macOS DMG, Windows installer, Linux tar.gz |
38-
| **Teams** | `go build -tags teams ./cmd/mcpproxy` | `mcpproxy-teams` | Docker image, .deb package, Linux tar.gz |
38+
| **Server** | `go build -tags server ./cmd/mcpproxy` | `mcpproxy-server` | Docker image, .deb package, Linux tar.gz |
39+
40+
> Every feature decision should ask: "Does this make the personal edition so good that developers tell their teammates about it?"
3941
4042
### Key Directories
4143

4244
| Directory | Purpose |
4345
|-----------|---------|
4446
| `cmd/mcpproxy/edition.go` | Default edition = "personal" |
45-
| `cmd/mcpproxy/edition_teams.go` | Build-tagged override for teams |
46-
| `cmd/mcpproxy/teams_register.go` | Teams feature registration entry point |
47-
| `internal/teams/` | Teams-only code (all files have `//go:build teams`) |
47+
| `cmd/mcpproxy/edition_teams.go` | Build-tagged override for server edition |
48+
| `cmd/mcpproxy/teams_register.go` | Server feature registration entry point |
49+
| `internal/teams/` | Server-only code (all files have `//go:build server`) |
50+
| `internal/teams/auth/` | OAuth authentication, session management, JWT tokens, middleware |
51+
| `internal/teams/users/` | User/session models, BBolt store, user server management |
52+
| `internal/teams/workspace/` | Per-user workspace manager for personal upstream servers |
53+
| `internal/teams/multiuser/` | Multi-user router, tool filtering, activity isolation |
54+
| `internal/teams/api/` | Server REST API endpoints (user, admin, auth) |
4855
| `native/macos/` | Future Swift tray app (placeholder) |
4956
| `native/windows/` | Future C# tray app (placeholder) |
5057

@@ -54,6 +61,66 @@ The binary self-identifies its edition:
5461
- `mcpproxy version``MCPProxy v0.21.0 (personal) darwin/arm64`
5562
- `/api/v1/status``{"edition": "personal", ...}`
5663

64+
## Server Multi-User Authentication (Spec 024)
65+
66+
Server edition supports OAuth-based multi-user authentication with Google, GitHub, or Microsoft identity providers.
67+
68+
### Server Configuration
69+
70+
```json
71+
{
72+
"teams": {
73+
"enabled": true,
74+
"admin_emails": ["admin@company.com"],
75+
"oauth": {
76+
"provider": "google",
77+
"client_id": "xxx.apps.googleusercontent.com",
78+
"client_secret": "GOCSPX-xxx",
79+
"tenant_id": "",
80+
"allowed_domains": ["company.com"]
81+
},
82+
"session_ttl": "24h",
83+
"bearer_token_ttl": "24h",
84+
"workspace_idle_timeout": "30m",
85+
"max_user_servers": 20
86+
}
87+
}
88+
```
89+
90+
### Server API Endpoints
91+
92+
| Endpoint | Auth | Description |
93+
|----------|------|-------------|
94+
| `GET /api/v1/auth/login` | Public | Initiate OAuth login flow |
95+
| `GET /api/v1/auth/callback` | Public | OAuth callback (creates session) |
96+
| `GET /api/v1/auth/me` | Session/JWT | Get current user profile |
97+
| `POST /api/v1/auth/token` | Session | Generate JWT bearer token for MCP |
98+
| `POST /api/v1/auth/logout` | Session | Invalidate session |
99+
| `GET /api/v1/user/servers` | Session/JWT | List user's servers (personal + shared) |
100+
| `POST /api/v1/user/servers` | Session/JWT | Add personal upstream server |
101+
| `GET /api/v1/user/activity` | Session/JWT | User's activity log |
102+
| `GET /api/v1/user/diagnostics` | Session/JWT | Server health for user's servers |
103+
| `GET /api/v1/admin/users` | Admin | List all users |
104+
| `POST /api/v1/admin/users/{id}/disable` | Admin | Disable a user |
105+
| `GET /api/v1/admin/activity` | Admin | All users' activity logs |
106+
| `GET /api/v1/admin/sessions` | Admin | List active sessions |
107+
108+
### Server Architecture
109+
110+
- **Auth flow**: OAuth 2.0 + PKCE → Session cookie (Web UI) + JWT bearer (MCP/API)
111+
- **Server types**: Shared (config file, single connection) + Personal (DB, per-user connections)
112+
- **Isolation**: Users see only shared + own personal servers. Activity logs user-scoped.
113+
- **Admin**: Identified by `admin_emails` config. Sees all activity, manages users.
114+
- **Build tag**: All server code behind `//go:build server`. Personal edition unaffected.
115+
116+
### Server Testing
117+
118+
```bash
119+
go test -tags server ./internal/teams/... -v -race # All server unit + integration tests
120+
go build -tags server ./cmd/mcpproxy # Build server edition
121+
go build ./cmd/mcpproxy # Verify personal edition unaffected
122+
```
123+
57124
## Architecture: Core + Tray Split
58125

59126
- **Core Server** (`mcpproxy`): Headless HTTP API server with MCP proxy functionality
@@ -66,11 +133,11 @@ The binary self-identifies its edition:
66133
### Build
67134
```bash
68135
go build -o mcpproxy ./cmd/mcpproxy # Core server (personal)
69-
go build -tags teams -o mcpproxy-teams ./cmd/mcpproxy # Core server (teams)
136+
go build -tags server -o mcpproxy-server ./cmd/mcpproxy # Core server (server edition)
70137
GOOS=darwin CGO_ENABLED=1 go build -o mcpproxy-tray ./cmd/mcpproxy-tray # Tray app
71138
make build # Frontend and backend (personal)
72-
make build-teams # Frontend and backend (teams)
73-
make build-docker # Teams Docker image
139+
make build-server # Frontend and backend (server)
140+
make build-docker # Server Docker image
74141
./scripts/build.sh # Cross-platform build
75142
```
76143

@@ -546,6 +613,8 @@ See `docs/prerelease-builds.md` for download instructions.
546613
- `~/.mcpproxy/mcp_config.json` (config file), `~/.mcpproxy/config.db` (BBolt - not directly used) (027-status-command)
547614
- Go 1.24 (toolchain go1.24.10) + Cobra (CLI), Chi router (HTTP), BBolt (storage), Zap (logging), mcp-go (MCP protocol), crypto/hmac + crypto/sha256 (token hashing) (028-agent-tokens)
548615
- BBolt database (`~/.mcpproxy/config.db`) — new `agent_tokens` bucket (028-agent-tokens)
616+
- Go 1.24 (toolchain go1.24.10) + TypeScript 5.9 / Vue 3.5 + Chi router, BBolt, Zap logging, mcp-go, golang-jwt/jwt/v5, Vue 3, Pinia, DaisyUI (024-teams-multiuser-oauth)
617+
- BBolt database (`~/.mcpproxy/config.db`) - new buckets for users, sessions, user servers (024-teams-multiuser-oauth)
549618

550619
## Recent Changes
551620
- 001-update-version-display: Added Go 1.24 (toolchain go1.24.10)

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ COPY . .
1313
RUN cd frontend && npm ci && npm run build
1414
RUN mkdir -p web/frontend && cp -r frontend/dist web/frontend/
1515

16-
# Build teams binary
16+
# Build server edition binary
1717
ARG VERSION=dev
1818
ARG COMMIT=unknown
1919
ARG BUILD_DATE=unknown
2020
RUN CGO_ENABLED=0 go build \
21-
-tags teams \
21+
-tags server \
2222
-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" \
2323
-o /mcpproxy ./cmd/mcpproxy
2424

Makefile

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# MCPProxy Makefile
22

3-
.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
3+
.PHONY: help build build-server 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
44

55
SWAGGER_BIN ?= $(HOME)/go/bin/swag
66
SWAGGER_OUT ?= oas
@@ -23,10 +23,10 @@ help:
2323
@echo " make lint - Run linter"
2424
@echo " make dev-setup - Install development dependencies (swag, frontend, Playwright)"
2525
@echo ""
26-
@echo "Teams Edition:"
27-
@echo " make build-teams - Build Teams edition binary (with -tags teams)"
28-
@echo " make build-docker - Build Teams Docker image"
29-
@echo " make build-deb - Build Teams .deb package (TODO)"
26+
@echo "Server Edition:"
27+
@echo " make build-server - Build Server edition binary (with -tags server)"
28+
@echo " make build-docker - Build Server Docker image"
29+
@echo " make build-deb - Build Server .deb package (TODO)"
3030
@echo ""
3131
@echo "Documentation Commands:"
3232
@echo " make docs-setup - Install documentation dependencies"
@@ -91,28 +91,28 @@ backend-dev:
9191
@echo "🚀 Run: ./mcpproxy-dev serve"
9292
@echo "🌐 In dev mode, make sure frontend dev server is running on port 3000"
9393

94-
# Build Teams edition
95-
build-teams: swagger frontend-build
96-
@echo "🔨 Building Teams edition binary (version: $(VERSION))..."
97-
go build -tags teams -ldflags "$(LDFLAGS)" -o mcpproxy-teams ./cmd/mcpproxy
98-
@echo "Teams build completed! Run: ./mcpproxy-teams serve"
94+
# Build Server edition
95+
build-server: swagger frontend-build
96+
@echo "🔨 Building Server edition binary (version: $(VERSION))..."
97+
go build -tags server -ldflags "$(LDFLAGS)" -o mcpproxy-server ./cmd/mcpproxy
98+
@echo "Server build completed! Run: ./mcpproxy-server serve"
9999

100-
# Build Teams Docker image
100+
# Build Server Docker image
101101
build-docker:
102-
@echo "🐳 Building Teams Docker image (version: $(VERSION))..."
103-
docker build --build-arg VERSION=$(VERSION) --build-arg COMMIT=$(COMMIT) --build-arg BUILD_DATE=$(BUILD_DATE) -t mcpproxy-teams:$(VERSION) -t mcpproxy-teams:latest .
104-
@echo "✅ Docker image built: mcpproxy-teams:$(VERSION)"
102+
@echo "🐳 Building Server Docker image (version: $(VERSION))..."
103+
docker build --build-arg VERSION=$(VERSION) --build-arg COMMIT=$(COMMIT) --build-arg BUILD_DATE=$(BUILD_DATE) -t mcpproxy-server:$(VERSION) -t mcpproxy-server:latest .
104+
@echo "✅ Docker image built: mcpproxy-server:$(VERSION)"
105105

106-
# Build Teams .deb package (placeholder)
106+
# Build Server .deb package (placeholder)
107107
build-deb:
108-
@echo "📦 Building Teams .deb package..."
108+
@echo "📦 Building Server .deb package..."
109109
@echo "⚠️ TODO: Implement deb package build (nfpm or dpkg-deb)"
110110
@echo " See: https://nfpm.goreleaser.com/"
111111

112112
# Clean build artifacts
113113
clean:
114114
@echo "🧹 Cleaning build artifacts..."
115-
rm -f mcpproxy mcpproxy-dev mcpproxy-tray mcpproxy-teams
115+
rm -f mcpproxy mcpproxy-dev mcpproxy-tray mcpproxy-server
116116
rm -rf frontend/dist frontend/node_modules web/frontend
117117
go clean
118118
@echo "✅ Cleanup completed"

cmd/mcpproxy/edition_teams.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
//go:build teams
1+
//go:build server
22

33
package main
44

55
func init() {
6-
Edition = "teams"
6+
Edition = "server"
77
}

0 commit comments

Comments
 (0)