forked from forwardnetworks/forward-mcp
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMakefile
More file actions
354 lines (312 loc) Β· 14.6 KB
/
Copy pathMakefile
File metadata and controls
354 lines (312 loc) Β· 14.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
# Project configuration
PROJECT_NAME=forward-mcp
BINARY_NAME=forward-mcp-server
TEST_CLIENT=forward-mcp-test-client
BUILD_DIR=bin
MAIN_FILE=cmd/server/main.go
TEST_CLIENT_FILE=cmd/test-client/main.go
# Go parameters
GOCMD=go
GOBUILD=$(GOCMD) build
GOCLEAN=$(GOCMD) clean
GOTEST=$(GOCMD) test
GOMOD=$(GOCMD) mod
# Go build flags
LDFLAGS=-ldflags "-s -w"
# CGO must be enabled for SQLite database functionality
CGO_ENABLED=1
.PHONY: all build build-test-client test test-quick test-integration test-all test-coverage test-coverage-all clean run run-test-client dev deps embedding-status embedding-generate-keyword embedding-generate-openai embedding-cache-info embedding-benchmark embedding-clean database-status test-database test-metadata test-enhanced database-clean metadata-stats test-semantic-search demo-smart-search test-path-search-integration test-path-search-mcp lint
all: test build
# Build the main server
build:
@echo "Building $(BINARY_NAME)..."
@mkdir -p $(BUILD_DIR)
CGO_ENABLED=$(CGO_ENABLED) $(GOBUILD) $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME) $(MAIN_FILE)
# Build the test client
build-test-client:
@echo "Building $(TEST_CLIENT)..."
@mkdir -p $(BUILD_DIR)
CGO_ENABLED=$(CGO_ENABLED) $(GOBUILD) -o $(BUILD_DIR)/$(TEST_CLIENT) $(TEST_CLIENT_FILE)
# Run unit tests (excludes integration tests to prevent hanging)
test:
@echo "Running unit tests (excluding integration tests)..."
@echo "π‘ Integration tests are excluded to prevent hanging on slow API calls"
@echo "π‘ Use 'make test-integration' to run integration tests separately"
$(GOTEST) -v -timeout=60s ./internal/... ./cmd/... ./pkg/... -skip 'TestIntegration'
# Run unit tests quickly (no verbose output)
test-quick:
@echo "Running unit tests quickly (no verbose output)..."
$(GOTEST) -timeout=60s ./internal/... ./cmd/... ./pkg/... -skip 'TestIntegration'
# Run integration tests with timeout
test-integration:
@echo "Running integration tests (with 60s timeout)..."
@echo "β οΈ These tests make real API calls and may take time"
@echo "π‘ Ensure your .env file is configured with valid Forward API credentials"
$(GOTEST) -v -timeout=60s ./internal/... ./cmd/... ./pkg/... -run 'TestIntegration'
# Run all tests (unit + integration) with extended timeout
test-all:
@echo "Running all tests (unit + integration) with extended timeout..."
@echo "β οΈ This includes integration tests that make real API calls"
$(GOTEST) -v -timeout=120s ./internal/... ./cmd/... ./pkg/...
# Run test coverage (excludes integration tests)
test-coverage:
@echo "Running test coverage (excluding integration tests)..."
@echo "π‘ Integration tests are excluded to prevent hanging on slow API calls"
$(GOTEST) -v -timeout=60s ./internal/... ./cmd/... ./pkg/... -skip 'TestIntegration' -coverprofile=coverage.out
$(GOCMD) tool cover -html=coverage.out -o coverage.html
@echo "Coverage report generated: coverage.html"
# Run test coverage with integration tests
test-coverage-all:
@echo "Running test coverage (including integration tests)..."
@echo "β οΈ This includes integration tests that make real API calls"
$(GOTEST) -v -timeout=120s ./internal/... ./cmd/... ./pkg/... -coverprofile=coverage.out
$(GOCMD) tool cover -html=coverage.out -o coverage.html
@echo "Coverage report generated: coverage.html"
# Clean build artifacts
clean:
@echo "Cleaning..."
rm -rf $(BUILD_DIR)
rm -f coverage.out coverage.html
$(GOCLEAN)
# Run the server
run: build
@echo "Starting MCP server..."
./$(BUILD_DIR)/$(BINARY_NAME)
# Run the test client
run-test-client: build build-test-client
@echo "Starting MCP test client..."
./$(BUILD_DIR)/$(TEST_CLIENT)
# Development server
dev:
@echo "Starting development server..."
$(GOCMD) run $(MAIN_FILE)
# Install dependencies
deps:
@echo "Installing dependencies..."
$(GOMOD) download
$(GOMOD) tidy
# Build for Linux
build-linux:
@echo "Building for Linux..."
@echo "β οΈ Note: Cross-compilation with SQLite requires appropriate CGO setup"
@mkdir -p $(BUILD_DIR)
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 $(GOBUILD) $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME)_linux $(MAIN_FILE)
# Build for Windows
build-windows:
@echo "Building for Windows..."
@echo "β οΈ Note: Cross-compilation with SQLite requires appropriate CGO setup"
@mkdir -p $(BUILD_DIR)
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 $(GOBUILD) $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME).exe $(MAIN_FILE)
# Docker build
docker-build:
@echo "Building Docker image..."
docker build -t $(PROJECT_NAME) .
# Docker run
docker-run: docker-build
@echo "Running Docker container..."
docker run --env-file .env -p 8080:8080 $(PROJECT_NAME)
# ==========================================
# EMBEDDING MANAGEMENT TARGETS
# ==========================================
# Check embedding status and coverage
embedding-status:
@echo "π Checking embedding status..."
@$(GOCMD) run scripts/embedding-status/main.go
# Generate embeddings using keyword-based service (fast, free, offline)
embedding-generate-keyword:
@echo "π Generating keyword-based embeddings (fast, free, offline)..."
@echo "β‘ This uses your optimized keyword embedding system from ACHIEVEMENTS.md"
@FORWARD_EMBEDDING_PROVIDER=keyword $(GOCMD) run scripts/generate-embeddings/main.go
# Generate embeddings using OpenAI API (slow, costs money, better semantic quality)
embedding-generate-openai:
@echo "π§ Generating OpenAI-based embeddings (requires OPENAI_API_KEY)..."
@if [ -z "$$OPENAI_API_KEY" ]; then \
echo "β Error: OPENAI_API_KEY environment variable not set"; \
echo "π‘ Set it with: export OPENAI_API_KEY=your-key-here"; \
echo "π‘ Or use 'make embedding-generate-keyword' for free alternative"; \
exit 1; \
fi
@echo "π° Warning: This will make API calls to OpenAI and cost money"
@echo "π Estimated cost: ~$$1-5 for 6000+ queries"
@read -p "Continue? (y/N): " confirm && [ "$$confirm" = "y" ] || exit 1
@FORWARD_EMBEDDING_PROVIDER=openai $(GOCMD) run scripts/generate-embeddings/main.go
# Show embedding cache information
embedding-cache-info:
@echo "π Embedding cache information:"
@if [ -f "spec/nqe-embeddings.json" ]; then \
echo "β
Cache file exists: spec/nqe-embeddings.json"; \
echo "π Cache size: $$(du -h spec/nqe-embeddings.json | cut -f1)"; \
echo "π’ Cache entries: $$(grep -o '\"/' spec/nqe-embeddings.json | wc -l | tr -d ' ')"; \
echo "π
Last modified: $$(stat -f "%Sm" spec/nqe-embeddings.json)"; \
else \
echo "β No embedding cache found"; \
echo "π‘ Run 'make embedding-generate-keyword' to create one"; \
fi
# Benchmark embedding search performance
embedding-benchmark:
@echo "β‘ Running embedding search benchmark..."
@$(GOCMD) run scripts/benchmark-search/main.go
# Clear embedding cache (use with caution)
embedding-clean:
@echo "ποΈ Clearing embedding cache..."
@if [ -f "spec/nqe-embeddings.json" ]; then \
read -p "β οΈ This will delete all cached embeddings. Continue? (y/N): " confirm && [ "$$confirm" = "y" ] && \
rm -f spec/nqe-embeddings.json && \
echo "β
Embedding cache cleared" || \
echo "β Operation cancelled"; \
else \
echo "βΉοΈ No embedding cache to clear"; \
fi
# ==========================================
# DATABASE & ENHANCED METADATA TARGETS
# ==========================================
# Check database status and metadata coverage
database-status:
@echo "ποΈ Checking database status and enhanced metadata coverage..."
@if [ -f "data/nqe_queries.db" ]; then \
echo "β
Database exists: data/nqe_queries.db"; \
echo "π Database size: $$(du -h data/nqe_queries.db | cut -f1)"; \
echo "π
Last modified: $$(stat -f "%Sm" data/nqe_queries.db 2>/dev/null || stat -c "%y" data/nqe_queries.db 2>/dev/null || echo "Unknown")"; \
else \
echo "β No database found at data/nqe_queries.db"; \
echo "π‘ Database will be created automatically on first run"; \
fi
# Test database functionality specifically
test-database:
@echo "π§ͺ Running database-specific tests..."
@echo "πΎ Testing database initialization and smart caching..."
@if [ ! -f data/nqe_queries.db ]; then \
echo "π Creating test database by running server briefly..."; \
timeout 15s ./bin/forward-mcp-server >/dev/null 2>&1 || true; \
fi
@if [ -f data/nqe_queries.db ]; then \
echo "β
Database exists and is functional"; \
echo "π Query count: $$(sqlite3 data/nqe_queries.db 'SELECT COUNT(*) FROM nqe_queries;' 2>/dev/null || echo 'Error querying database')"; \
echo "ποΈ Repositories: $$(sqlite3 data/nqe_queries.db 'SELECT repository, COUNT(*) FROM nqe_queries GROUP BY repository;' 2>/dev/null || echo 'Error querying repositories')"; \
else \
echo "β Database test failed - could not create database"; \
exit 1; \
fi
# Test enhanced metadata functionality
test-metadata:
@echo "π§ͺ Running enhanced metadata tests..."
@echo "π Testing semantic search and query index functionality..."
@$(GOCMD) run ./scripts/test-semantic-search | head -20
@echo ""
@echo "β
Metadata and semantic search tests completed"
# Test complete enhanced system (database + metadata + API)
test-enhanced:
@echo "π§ͺ Running complete enhanced metadata system tests..."
@echo "π Testing end-to-end system: Database β API β Semantic Search"
@make test-database
@echo ""
@make test-metadata
@echo ""
@echo "π Complete enhanced system test passed!"
# Note: Database initialization is now handled automatically by the MCP service
# The service uses smart caching with fallback: Database β API β Spec file
# No manual initialization is required - just run 'make run' and the service will handle it
# Clean database (use with caution)
database-clean:
@echo "ποΈ Clearing database..."
@if [ -f "data/nqe_queries.db" ]; then \
read -p "β οΈ This will delete all cached queries and metadata. Continue? (y/N): " confirm && [ "$$confirm" = "y" ] && \
rm -f data/nqe_queries.db && \
echo "β
Database cleared" || \
echo "β Operation cancelled"; \
else \
echo "βΉοΈ No database to clear"; \
fi
# Show enhanced metadata statistics
metadata-stats:
@echo "π Enhanced metadata statistics..."
@if [ -f "data/nqe_queries.db" ]; then \
echo "ποΈ Querying database for metadata coverage..."; \
echo "π‘ Use 'make run' and call get_query_index_stats for detailed statistics"; \
else \
echo "β No database found. Run 'make database-init' to populate with enhanced metadata"; \
fi
# Semantic Search & Demo Targets
test-semantic-search: ## π Test semantic search functionality with comprehensive query examples
@echo "π Running semantic search test..."
@go run ./scripts/test-semantic-search
demo-smart-search: ## π Run smart query discovery demo (shows semantic search β executable mapping)
@echo "π Running smart query discovery demo..."
@go run ./scripts/demo-smart-search
# Test path search integration with customer-specific IPs
test-path-search-integration: ## π Run path search integration tests with customer IPs (10.6.142.197 β 10.5.0.130)
@echo "π Running path search integration tests with customer IPs..."
@echo " Source IP: 10.6.142.197 β Destination IP: 10.5.0.130"
@if [ ! -f .env ]; then \
echo "β .env file not found. Please create it with FORWARD_API_KEY, FORWARD_API_SECRET, and FORWARD_API_BASE_URL"; \
exit 1; \
fi
@go test -v ./internal/service -run "TestIntegrationPathSearch" -tags=integration
# Test path search using MCP client (interactive)
test-path-search-mcp: build build-test-client ## π Test path search using MCP test client (interactive mode)
@echo "π Starting MCP test client for path search testing..."
@echo "π‘ Available path search tests:"
@echo " 5. Customer path search: 100.100.1.1 β 190.37.14.114 (basic)"
@echo " 6. Customer path search with PREFER_DELIVERED intent"
@echo " 7. Customer path search for HTTPS (TCP 443)"
@echo " 8. Customer path search with network functions"
@echo " 9. Customer reverse path: 190.37.14.114 β 100.100.1.1"
@echo ""
@echo "π Note: Using test network_id '162112'"
@echo "π‘ Troubleshooting: If 0 paths found, try options 1-3 first to verify connectivity"
@echo ""
@./bin/forward-mcp-test-client
# Help
help:
@echo "Available targets:"
@echo ""
@echo "ποΈ BUILD & RUN:"
@echo " build - Build the MCP server (with SQLite support)"
@echo " build-test-client - Build the test client"
@echo " build-linux - Cross-compile for Linux (requires CGO setup)"
@echo " build-windows - Cross-compile for Windows (requires CGO setup)"
@echo " run - Build and run the server"
@echo " run-test-client - Build and run the test client"
@echo " dev - Run in development mode"
@echo ""
@echo "π§ͺ TESTING:"
@echo " test - Run all unit tests"
@echo " test-integration - Run integration tests"
@echo " test-coverage - Run tests with coverage report"
@echo " test-database - Run database-specific tests"
@echo " test-metadata - Run enhanced metadata tests"
@echo " test-enhanced - Run complete enhanced system tests"
@echo " test-path-search-mcp - Test path search using MCP client (interactive)"
@echo ""
@echo "ποΈ DATABASE & ENHANCED METADATA:"
@echo " database-status - Check database status and metadata coverage"
@echo " database-clean - Clear database (destructive operation)"
@echo " metadata-stats - Show enhanced metadata statistics"
@echo " π‘ Note: Database initialization is now automatic - no manual init needed"
@echo ""
@echo "π€ SEMANTIC SEARCH & EMBEDDINGS:"
@echo " test-semantic-search - Test semantic search functionality"
@echo " embedding-status - Check embedding coverage and stats"
@echo " embedding-generate-keyword - Generate fast, free keyword embeddings"
@echo " embedding-generate-openai - Generate OpenAI embeddings (costs money)"
@echo " embedding-cache-info - Show embedding cache information"
@echo " embedding-benchmark - Test search performance"
@echo " embedding-clean - Clear embedding cache"
@echo " demo-smart-search - Run smart query discovery demo"
@echo ""
@echo "π οΈ UTILITIES:"
@echo " clean - Clean build artifacts"
@echo " deps - Install dependencies"
@echo " docker-build - Build Docker image"
@echo " docker-run - Run in Docker"
@echo " lint - Run linter"
@echo " help - Show this help"
@echo ""
@echo "π‘ SEMANTIC SEARCH WORKFLOW:"
@echo " 1. make test-semantic-search # Test semantic search functionality"
@echo " 2. make database-status # Check current database state"
@echo " 3. make run # Start server (auto-initializes database)"
@echo " 4. make embedding-generate-openai # Enable AI search (optional)"
.PHONY: lint
lint:
golangci-lint run