Skip to content

Commit 3ac0018

Browse files
committed
Add security configuration and enhance testing framework for MCP Proxy
- Introduced security settings in the configuration, including read-only mode, management disabling, and server add/remove permissions. - Updated README to reflect new security options and command-line flags. - Added comprehensive end-to-end and unit tests to validate security configurations and tool management operations. - Implemented GitHub Actions workflows for unit and end-to-end testing, ensuring robust CI/CD integration.
1 parent d2d3153 commit 3ac0018

16 files changed

Lines changed: 2759 additions & 456 deletions

File tree

.github/workflows/e2e-tests.yml

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
name: E2E Tests
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
pull_request:
7+
branches: [main, develop]
8+
9+
jobs:
10+
e2e-tests:
11+
name: End-to-End Tests
12+
runs-on: ${{ matrix.os }}
13+
strategy:
14+
matrix:
15+
os: [ubuntu-latest, macos-latest, windows-latest]
16+
go-version: ["1.21", "1.22", "1.23"]
17+
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v4
21+
22+
- name: Set up Go
23+
uses: actions/setup-go@v4
24+
with:
25+
go-version: ${{ matrix.go-version }}
26+
27+
- name: Cache Go modules
28+
uses: actions/cache@v3
29+
with:
30+
path: |
31+
~/.cache/go-build
32+
~/go/pkg/mod
33+
key: ${{ runner.os }}-go-${{ matrix.go-version }}-${{ hashFiles('**/go.sum') }}
34+
restore-keys: |
35+
${{ runner.os }}-go-${{ matrix.go-version }}-
36+
${{ runner.os }}-go-
37+
38+
- name: Download dependencies
39+
run: go mod download
40+
41+
- name: Verify dependencies
42+
run: go mod verify
43+
44+
- name: Run unit tests
45+
run: go test -v -race -timeout 30s ./internal/...
46+
47+
- name: Run E2E tests
48+
run: go test -v -race -timeout 5m ./internal/server -run TestE2E
49+
env:
50+
GO_TEST_TIMEOUT: 300s
51+
52+
- name: Run E2E tests with race detector
53+
if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.23'
54+
run: go test -v -race -timeout 10m ./internal/server -run TestE2E
55+
env:
56+
GO_TEST_TIMEOUT: 600s
57+
58+
integration-tests:
59+
name: Integration Tests
60+
runs-on: ubuntu-latest
61+
needs: e2e-tests
62+
63+
steps:
64+
- name: Checkout code
65+
uses: actions/checkout@v4
66+
67+
- name: Set up Go
68+
uses: actions/setup-go@v4
69+
with:
70+
go-version: "1.23"
71+
72+
- name: Build mcpproxy
73+
run: go build -o mcpproxy ./cmd/mcpproxy
74+
75+
- name: Test mcpproxy binary
76+
run: |
77+
# Test version command
78+
./mcpproxy version
79+
80+
# Test help command
81+
./mcpproxy --help
82+
83+
# Test serve command with dry-run (if available)
84+
timeout 10s ./mcpproxy serve --port 0 || true
85+
86+
- name: Run tests with coverage
87+
run: |
88+
go test -v -race -coverprofile=coverage.out -covermode=atomic ./internal/server -run TestE2E
89+
go tool cover -html=coverage.out -o coverage.html
90+
91+
- name: Upload coverage reports
92+
uses: codecov/codecov-action@v3
93+
with:
94+
file: ./coverage.out
95+
flags: e2e-tests
96+
name: e2e-coverage
97+
fail_ci_if_error: false
98+
99+
stress-tests:
100+
name: Stress Tests
101+
runs-on: ubuntu-latest
102+
needs: e2e-tests
103+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
104+
105+
steps:
106+
- name: Checkout code
107+
uses: actions/checkout@v4
108+
109+
- name: Set up Go
110+
uses: actions/setup-go@v4
111+
with:
112+
go-version: "1.23"
113+
114+
- name: Run concurrent stress tests
115+
run: |
116+
# Run the concurrent test multiple times to catch race conditions
117+
for i in {1..5}; do
118+
echo "Stress test iteration $i"
119+
go test -v -race -timeout 10m ./internal/server -run TestE2E_ConcurrentOperations
120+
done
121+
122+
- name: Run memory stress test
123+
run: |
124+
# Run tests with memory limit
125+
GOMAXPROCS=1 GOMEMLIMIT=100MiB go test -v -timeout 15m ./internal/server -run TestE2E

.github/workflows/unit-tests.yml

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
name: Unit Tests
2+
3+
on:
4+
push:
5+
branches: ["*"]
6+
pull_request:
7+
branches: ["*"]
8+
9+
jobs:
10+
test:
11+
name: Unit Tests
12+
runs-on: ${{ matrix.os }}
13+
strategy:
14+
matrix:
15+
os: [ubuntu-latest, macos-latest, windows-latest]
16+
go-version: ["1.21", "1.22", "1.23"]
17+
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v4
21+
22+
- name: Set up Go
23+
uses: actions/setup-go@v5
24+
with:
25+
go-version: ${{ matrix.go-version }}
26+
27+
- name: Cache Go modules
28+
uses: actions/cache@v4
29+
with:
30+
path: |
31+
~/.cache/go-build
32+
~/go/pkg/mod
33+
key: ${{ runner.os }}-go-${{ matrix.go-version }}-${{ hashFiles('**/go.sum') }}
34+
restore-keys: |
35+
${{ runner.os }}-go-${{ matrix.go-version }}-
36+
37+
- name: Download dependencies
38+
run: go mod download
39+
40+
- name: Verify dependencies
41+
run: go mod verify
42+
43+
- name: Run unit tests
44+
run: go test -v -race -coverprofile=coverage.out -run "^Test[^E]" ./...
45+
46+
- name: Generate coverage report
47+
run: go tool cover -html=coverage.out -o coverage.html
48+
49+
- name: Upload coverage to Codecov
50+
if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.23'
51+
uses: codecov/codecov-action@v4
52+
with:
53+
file: ./coverage.out
54+
flags: unittests
55+
name: codecov-umbrella
56+
fail_ci_if_error: false
57+
58+
- name: Upload coverage artifacts
59+
if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.23'
60+
uses: actions/upload-artifact@v4
61+
with:
62+
name: coverage-report
63+
path: |
64+
coverage.out
65+
coverage.html
66+
67+
lint:
68+
name: Lint
69+
runs-on: ubuntu-latest
70+
steps:
71+
- name: Checkout code
72+
uses: actions/checkout@v4
73+
74+
- name: Set up Go
75+
uses: actions/setup-go@v5
76+
with:
77+
go-version: "1.23"
78+
79+
- name: golangci-lint
80+
uses: golangci/golangci-lint-action@v6
81+
with:
82+
version: latest
83+
args: --timeout=5m
84+
85+
build:
86+
name: Build
87+
runs-on: ${{ matrix.os }}
88+
strategy:
89+
matrix:
90+
os: [ubuntu-latest, macos-latest, windows-latest]
91+
92+
steps:
93+
- name: Checkout code
94+
uses: actions/checkout@v4
95+
96+
- name: Set up Go
97+
uses: actions/setup-go@v5
98+
with:
99+
go-version: "1.23"
100+
101+
- name: Build
102+
run: go build -v ./cmd/mcpproxy
103+
104+
- name: Build for different architectures (Linux only)
105+
if: matrix.os == 'ubuntu-latest'
106+
run: |
107+
GOOS=linux GOARCH=amd64 go build -o mcpproxy-linux-amd64 ./cmd/mcpproxy
108+
GOOS=linux GOARCH=arm64 go build -o mcpproxy-linux-arm64 ./cmd/mcpproxy
109+
GOOS=darwin GOARCH=amd64 go build -o mcpproxy-darwin-amd64 ./cmd/mcpproxy
110+
GOOS=darwin GOARCH=arm64 go build -o mcpproxy-darwin-arm64 ./cmd/mcpproxy
111+
GOOS=windows GOARCH=amd64 go build -o mcpproxy-windows-amd64.exe ./cmd/mcpproxy
112+
113+
- name: Upload build artifacts
114+
if: matrix.os == 'ubuntu-latest'
115+
uses: actions/upload-artifact@v4
116+
with:
117+
name: binaries
118+
path: mcpproxy-*

.golangci.yml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
run:
2+
timeout: 5m
3+
go: '1.23'
4+
5+
linters:
6+
enable:
7+
- gofmt
8+
- goimports
9+
- govet
10+
- errcheck
11+
- staticcheck
12+
- unused
13+
- gosimple
14+
- ineffassign
15+
- typecheck
16+
- goconst
17+
- misspell
18+
- unparam
19+
- unconvert
20+
- gocritic
21+
- revive
22+
- gosec
23+
- exportloopref
24+
25+
linters-settings:
26+
goconst:
27+
min-len: 2
28+
min-occurrences: 2
29+
30+
gocritic:
31+
enabled-tags:
32+
- diagnostic
33+
- experimental
34+
- opinionated
35+
- performance
36+
- style
37+
disabled-checks:
38+
- dupImport
39+
- ifElseChain
40+
- octalLiteral
41+
- whyNoLint
42+
43+
revive:
44+
min-confidence: 0
45+
46+
gosec:
47+
excludes:
48+
- G204 # Subprocess launched with variable
49+
- G304 # File path provided as taint input
50+
51+
issues:
52+
exclude-rules:
53+
- path: _test\.go
54+
linters:
55+
- gosec
56+
- goconst
57+
58+
- path: internal/tray/
59+
linters:
60+
- unused
61+
62+
- text: "weak cryptographic primitive"
63+
linters:
64+
- gosec
65+
66+
max-issues-per-linter: 0
67+
max-same-issues: 0

README.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,17 +103,20 @@ Smart MCP Proxy
103103
## Features
104104

105105
- **Intelligent Tool Discovery**: Automatically discover and index tools from multiple MCP servers
106-
- **Semantic Search**: Find relevant tools using natural language queries
106+
- **Enhanced Tool Search**: Consolidated `retrieve_tools` with optional statistics, debug mode, and tool ranking explanations
107+
- **Semantic Search**: Find relevant tools using natural language queries with BM25 full-text search
107108
- **Tool Aggregation**: Combine tools from multiple upstream servers into a single interface
108109
- **Response Truncation & Caching**: Automatically truncate large tool responses to prevent LLM context bloat
109110
- **Smart Pagination**: Access cached response data through pagination with the `read_cache` tool
110111
- **JSON Structure Analysis**: Intelligent splitting of JSON responses by record arrays
111112
- **HTTP & Stdio Support**: Connect to MCP servers via HTTP or stdio protocols
113+
- **Security Controls**: Read-only mode, management disabling, granular server add/remove permissions
112114
- **Persistent Storage**: Cache tool metadata and connection information
113115
- **Configuration Management**: Flexible JSON-based configuration with environment variable support
114116
- **System Tray Integration**: Native system tray with real-time monitoring and control
115117
- **Auto-updates**: Built-in update checking and installation
116118
- **Cross-platform**: Works on macOS, Windows, and Linux
119+
- **MCP Prompts Support**: Ready for prompt templates and workflow guidance (when mcp-go supports it)
117120

118121
## Installation
119122

@@ -179,6 +182,27 @@ export MCPPROXY_DATA_DIR=~/.mcpproxy
179182
./mcpproxy
180183
```
181184

185+
### Security Configuration
186+
187+
Configure security settings to control access in different environments:
188+
189+
```json
190+
{
191+
"read_only_mode": false,
192+
"disable_management": false,
193+
"allow_server_add": true,
194+
"allow_server_remove": true,
195+
"enable_prompts": true
196+
}
197+
```
198+
199+
Security options:
200+
- `read_only_mode`: When true, only allows listing servers, blocks all modifications
201+
- `disable_management`: When true, completely disables the `upstream_servers` tool
202+
- `allow_server_add`: Controls whether new servers can be added (includes `add`, `add_batch`, `import_cursor`)
203+
- `allow_server_remove`: Controls whether servers can be removed
204+
- `enable_prompts`: Enable MCP prompts capability for workflow guidance
205+
182206
### Command Line Options
183207

184208
```bash
@@ -191,6 +215,11 @@ Options:
191215
- `--data-dir, -d`: Data directory path
192216
- `--tray`: Enable system tray (default: true)
193217
- `--log-level`: Log level (debug, info, warn, error)
218+
- `--read-only`: Enable read-only mode (security)
219+
- `--disable-management`: Disable server management (security)
220+
- `--allow-server-add`: Allow adding servers (default: true)
221+
- `--allow-server-remove`: Allow removing servers (default: true)
222+
- `--enable-prompts`: Enable prompts capability (default: true)
194223

195224
## Usage
196225

0 commit comments

Comments
 (0)