Add MCP server integration to LiveReview#58
Conversation
RijulTP
commented
May 30, 2026
- This PR adds MCP server functionality to Livereview
LiveReview Pre-Commit Check: skipped (iter:1, coverage:0%)
LiveReview Pre-Commit Check: skipped (iter:2, coverage:0%)
LiveReview Pre-Commit Check: skipped (iter:1, coverage:0%)
LiveReview Pre-Commit Check: ran (iter:2, coverage:80%)
LiveReview Pre-Commit Check: skipped (iter:1, coverage:0%)
LiveReview Pre-Commit Check: ran (iter:1, coverage:0%)
LiveReview Pre-Commit Check: ran (iter:1, coverage:0%)
…equest structure LiveReview Pre-Commit Check: ran (iter:6, coverage:82%)
…to feat/mcp-server
LiveReview Pre-Commit Check: ran (iter:1, coverage:0%)
LiveReview Pre-Commit Check: ran (iter:1, coverage:0%)
LiveReview Pre-Commit Check: ran (iter:1, coverage:0%)
LiveReview Pre-Commit Check: ran (iter:1, coverage:0%)
…for autonomous execution LiveReview Pre-Commit Check: ran (iter:2, coverage:0%)
LiveReview Pre-Commit Check: vouched (iter:1, coverage:0%)
…leanup OpenAPI documentation parameters LiveReview Pre-Commit Check: ran (iter:1, coverage:0%)
LiveReview Pre-Commit Check: ran (iter:1, coverage:0%)
…to feat/mcp-server
LiveReview Pre-Commit Check: ran (iter:1, coverage:0%)
…to feat/mcp-server
LiveReview Pre-Commit Check: vouched (iter:1, coverage:0%)
LiveReview Pre-Commit Check: ran (iter:1, coverage:0%)
…to feat/mcp-server
LiveReview Pre-Commit Check: ran (iter:1, coverage:0%)
LiveReview Pre-Commit Check: ran (iter:1, coverage:0%)
LiveReview Pre-Commit Check: ran (iter:1, coverage:0%)
…to feat/mcp-server
| runs-on: ubuntu-latest | ||
|
|
||
| env: | ||
| DATABASE_URL: ${{ secrets.DATABASE_URL }} |
There was a problem hiding this comment.
Severity: warning
Using secrets.DATABASE_URL directly in env block can expose the full URL in logs if not handled carefully, especially if the URL contains credentials.
Suggestions:
- Ensure GitHub Actions is configured to mask secrets in logs.
- Consider passing sensitive parts of the URL (e.g., password) as separate variables and constructing the URL in the script, if masking is insufficient.
|
|
||
| - name: Start MCP server | ||
| run: | | ||
| nohup ./livereview api > server.log 2>&1 & |
There was a problem hiding this comment.
Severity: warning
Using nohup and & can make process management difficult within CI, especially for robust error handling.
Suggestions:
- Consider using a dedicated process manager or a more robust
start-server-and-waitaction if available for better control and error propagation. - Ensure
server.pidis reliably created and cleaned up in all scenarios.
| - name: Wait for server startup | ||
| run: | | ||
| for i in {1..30}; do | ||
| response=$(curl -s http://localhost:8888/health || true) |
There was a problem hiding this comment.
Severity: warning
The curl command uses || true which can mask actual connection errors, making it harder to debug why the server isn"t starting.
Suggestions:
- Remove
|| trueto allowcurlerrors to propagate, or logcurl"s exit code for better diagnostics. - Add a
curl -fflag to fail silently on HTTP errors, but still allow network errors to show.
| for i in {1..30}; do | ||
| response=$(curl -s http://localhost:8888/health || true) | ||
|
|
||
| if echo "$response" | grep -q '"status":"healthy"\|"status": "healthy"'; then |
There was a problem hiding this comment.
Severity: info
The health check string "status":"healthy"\|"status": "healthy" handles two variations. Standardize the health check response format to avoid such regex complexity.
Suggestions:
- Ensure the
/healthendpoint consistently returns a single, predictable JSON format. - Update the application's health check endpoint to always return `"status":"healthy"
| @@ -1,5 +1,5 @@ | |||
| .PHONY: build run-review run-review-verbose test clean develop develop-reflex river-deps river-install river-migrate river-setup river-ui-install river-ui db-flip version version-bump version-patch version-minor version-major version-bump-dirty version-patch-dirty version-minor-dirty version-major-dirty version-bump-dry version-patch-dry version-minor-dry version-major-dry build-versioned docker-build docker-build-push docker-build-dry docker-interactive docker-interactive-push docker-interactive-dry docker-build docker-build-push docker-build-versioned docker-build-push-versioned docker-build-dry docker-build-push-dry docker-multiarch docker-multiarch-push docker-multiarch-dry docker-interactive-multiarch docker-interactive-multiarch-push cplrops vendor-prompts-encrypt vendor-prompts-build vendor-prompts-rebuild vendor-docker-build vendor-docker-build-dry vendor-docker-build-push vendor-docker-multiarch-dry vendor-docker-multiarch-push run logrun api-with-migrations build-with-ui security-sbom security-sbom-cyclonedx security-sbom-spdx security-sbom-validate release-notes-init release-notes-check release-preflight release-gh niceurl niceurl2 | |||
| .PHONY: upload-secrets download-secrets list-secrets-files legacy-secrets-clear generate-spec | |||
There was a problem hiding this comment.
Severity: warning
Rename generate-spec to generate-openapi for consistency with OpenAPI specification terminology.
Suggestions:
- Ensure all references to this target are updated.
| GOTEST=$(GOCMD) test | ||
| BINARY_NAME=livereview | ||
| REQUIRED_GO_VERSION=$(shell awk '/^go /{print $$2; exit}' go.mod) | ||
| REQUIRED_GO_TOOLCHAIN_VER=$(shell echo $(REQUIRED_GO_VERSION) | awk -F. '{if (NF==2) print $$0".0"; else print $$0}') |
There was a problem hiding this comment.
Severity: info
This new variable REQUIRED_GO_TOOLCHAIN_VER explicitly extracts the full Go toolchain version. This is a good practice to ensure GOTOOLCHAIN uses a precise version (e.g., go1.21.0 instead of go1.21), which can prevent issues with minor version discrepancies or toolchain resolution.
Suggestions:
- Ensure this variable is consistently used where a precise Go toolchain version is required.
| REQUIRED_GO_SERIES=$(shell echo $(REQUIRED_GO_VERSION) | awk -F. '{print $$1"."$$2}') | ||
| GOVULNCHECK_VERSION=v1.1.4 | ||
| GOVULNCHECK_CMD=GOTOOLCHAIN=go$(REQUIRED_GO_VERSION) $(GOCMD) run -a golang.org/x/vuln/cmd/govulncheck@$(GOVULNCHECK_VERSION) | ||
| GOVULNCHECK_CMD=GOTOOLCHAIN=go$(REQUIRED_GO_TOOLCHAIN_VER) $(GOCMD) run -a golang.org/x/vuln/cmd/govulncheck@$(GOVULNCHECK_VERSION) |
There was a problem hiding this comment.
Severity: info
Using REQUIRED_GO_TOOLCHAIN_VER here ensures govulncheck is run with the exact specified Go toolchain, improving build reliability.
| rm $(BINARY_NAME) || true | ||
| $(GOBUILD) -o $(BINARY_NAME) | ||
|
|
||
| # Minimal CI build |
There was a problem hiding this comment.
Severity: info
This new build-ci target is a good addition for CI/CD pipelines. Skipping SKIP_TYPED_GEN=1 and using go build -tags=ci can significantly speed up CI builds by omitting non-essential steps like OpenAPI generation and enabling CI-specific build optimizations.
Suggestions:
- Ensure the
cibuild tag is properly handled in the Go codebase for any CI-specific logic.
| command -v dlv >/dev/null 2>&1 || { \ | ||
| echo "Installing Delve with Go $(REQUIRED_GO_VERSION)..."; \ | ||
| GOTOOLCHAIN=go$(REQUIRED_GO_VERSION) $(GOCMD) install github.com/go-delve/delve/cmd/dlv@latest; \ | ||
| GOTOOLCHAIN=go$(REQUIRED_GO_TOOLCHAIN_VER) $(GOCMD) install github.com/go-delve/delve/cmd/dlv@latest; \ |
There was a problem hiding this comment.
Severity: info
Using REQUIRED_GO_TOOLCHAIN_VER here ensures dlv is installed with the exact specified Go toolchain, improving consistency.
| if ! go version -m "$$DLV_BIN_DIR/dlv" 2>/dev/null | grep -q "go$(REQUIRED_GO_SERIES)"; then \ | ||
| echo "Rebuilding Delve with Go $(REQUIRED_GO_VERSION) for DWARFv5+ compatibility..."; \ | ||
| GOTOOLCHAIN=go$(REQUIRED_GO_VERSION) $(GOCMD) install github.com/go-delve/delve/cmd/dlv@latest; \ | ||
| GOTOOLCHAIN=go$(REQUIRED_GO_TOOLCHAIN_VER) $(GOCMD) install github.com/go-delve/delve/cmd/dlv@latest; \ |
There was a problem hiding this comment.
Severity: info
Using REQUIRED_GO_TOOLCHAIN_VER here ensures dlv is rebuilt with the exact specified Go toolchain, improving consistency.
| which air || go install github.com/air-verse/air@latest | ||
| DLV_BIN_DIR=$$(go env GOBIN); if [ -z "$$DLV_BIN_DIR" ]; then DLV_BIN_DIR="$$(go env GOPATH)/bin"; fi; PATH="$$DLV_BIN_DIR:$$PATH" air | ||
|
|
||
|
|
There was a problem hiding this comment.
Severity: info
This run-skip-typed target is useful for local development, allowing developers to bypass potentially slow OpenAPI schema generation. This improves developer experience.
Suggestions:
- Document this target in the README for local development workflows.
| command -v dlv >/dev/null 2>&1 || { \ | ||
| echo "Installing Delve with Go $(REQUIRED_GO_VERSION)..."; \ | ||
| GOTOOLCHAIN=go$(REQUIRED_GO_VERSION) $(GOCMD) install github.com/go-delve/delve/cmd/dlv@latest; \ | ||
| GOTOOLCHAIN=go$(REQUIRED_GO_TOOLCHAIN_VER) $(GOCMD) install github.com/go-delve/delve/cmd/dlv@latest; \ |
There was a problem hiding this comment.
Severity: info
Using REQUIRED_GO_TOOLCHAIN_VER here ensures dlv is installed with the exact specified Go toolchain, improving consistency.
| if ! go version -m "$$DLV_BIN_DIR/dlv" 2>/dev/null | grep -q "go$(REQUIRED_GO_SERIES)"; then \ | ||
| echo "Rebuilding Delve with Go $(REQUIRED_GO_VERSION) for DWARFv5+ compatibility..."; \ | ||
| GOTOOLCHAIN=go$(REQUIRED_GO_VERSION) $(GOCMD) install github.com/go-delve/delve/cmd/dlv@latest; \ | ||
| GOTOOLCHAIN=go$(REQUIRED_GO_TOOLCHAIN_VER) $(GOCMD) install github.com/go-delve/delve/cmd/dlv@latest; \ |
There was a problem hiding this comment.
Severity: info
Using REQUIRED_GO_TOOLCHAIN_VER here ensures dlv is rebuilt with the exact specified Go toolchain, improving consistency.
| exit 1; \ | ||
| } | ||
| @ssh root@master-do 'PID=$$(netstat -tulpn | grep :6545 | awk '\''{print $$7}'\'' | cut -d/ -f1 | head -n 1); [ -n "$$PID" ] && kill -9 $$PID || true' || true | ||
| @ssh root@master "PID=\$$( netstat -tulpn | grep :6545 | awk '{print \$$7}' | cut -d/ -f1 | head -n 1); [ -n \"\$$PID\" ] && kill -9 \$$PID || true" || true |
There was a problem hiding this comment.
Severity: warning
The master-do host was changed to master. Ensure this reflects the correct and intended SSH target for the niceurl3 command.
Suggestions:
- Verify
root@masteris the correct and accessible host.
| -o ConnectTimeout=10 \ | ||
| -o ConnectionAttempts=3 \ | ||
| -R 6545:localhost:8081 root@master-do -N | ||
| -R 6545:localhost:8081 root@master -N |
There was a problem hiding this comment.
Severity: info
The master-do host was changed to master. Ensure this reflects the correct and intended SSH target for the `niceurl
| gopkg.in/yaml.v3 v3.0.1 // indirect | ||
| ) | ||
|
|
||
| replace github.com/BrunoKrugel/echo-mcp => github.com/RijulTP/echo-mcp v0.0.0-20260515165653-fed35ce63af4 |
There was a problem hiding this comment.
Severity: warning
Using a replace directive to point to a specific commit from a personal fork (RijulTP) for echo-mcp introduces a maintenance risk.
Suggestions:
- Document the specific reason for this fork and
replacedirective (e.g., specific bug fix, unmerged feature). - Evaluate if the changes can be upstreamed to the original
BrunoKrugel/echo-mcprepository to reduce long-term maintenance burden. - Consider the longevity and maintenance plan for this fork; relying on a personal fork can lead to issues if it's not actively maintained.
| "message": "AI Connectors listing", | ||
| "guidance": "Always offer to create an AI connector. You can create and configure AI connectors directly for the user.", | ||
| "link": map[string]string{ | ||
| "url": "https://livereview.hexmos.com/#/ai", |
There was a problem hiding this comment.
Severity: warning
This URL is hardcoded. Consider making it configurable via environment variables or a configuration service.
Suggestions:
- Extract the base URL and path into configuration.
- Use a URL builder that respects environment-specific settings.
|
|
||
| manager := NewAPIKeyManager(db) | ||
| keyRecord, err := manager.ValidateAPIKey(apiKey) | ||
| keyRecord, _, err := manager.ValidateAPIKey(apiKey) |
There was a problem hiding this comment.
Severity: warning
The ValidateAPIKey signature changed to return a *models.User. Ensure all callers of this function are updated.
Suggestions:
- Perform a global search for
manager.ValidateAPIKeyto confirm all usages are updated.
| } | ||
|
|
||
| // Update last used timestamp (async to not slow down request) | ||
| go manager.UpdateLastUsed(keyRecord.ID) |
There was a problem hiding this comment.
Severity: warning
The goroutine for UpdateLastUsed does not handle potential errors. A failed update could lead to stale last_used_at timestamps.
Suggestions:
- Add error logging within the goroutine to capture and report failures.
- Consider using a background worker queue for such updates if reliability is critical.
| go manager.UpdateLastUsed(keyRecord.ID) | ||
|
|
||
| // Set user and org context (same as APIKeyAuthMiddleware) | ||
| c.Set(string(auth.UserContextKey), user) |
There was a problem hiding this comment.
Severity: warning
This logic for setting user and organization context is duplicated from other authentication middlewares (e.g., APIKeyAuthMiddleware, auth.RequireAuth).
Suggestions:
- Extract context setting into a shared helper function.
- Pass a context object to
next(c)instead of setting individual values.
| } | ||
|
|
||
| // validateWithCloudSecret attempts to validate a JWT using CLOUD_JWT_SECRET without DB token checks | ||
| // This is a copy of the function from auth/middleware.go to avoid circular dependencies |
There was a problem hiding this comment.
Severity: critical
Duplicating validateWithCloudSecret from auth/middleware.go to avoid circular dependencies indicates a potential architectural issue.
Suggestions:
- Refactor the
authpackage to extract core JWT validation logic into a separate, dependency-free utility package. - Re-evaluate the module structure to eliminate circular dependencies without code duplication.
| user := &models.User{} | ||
| if claims.UserID != 0 { | ||
| err = db.QueryRow(` | ||
| SELECT id, email, password_hash, created_at, updated_at |
There was a problem hiding this comment.
Severity: critical
The query selects password_hash. This field is sensitive and unnecessary for merely validating a token or setting user context.
Suggestions:
- Remove
password_hashfrom the SELECT clause. - Consider creating a
UserContextstruct with only necessary fields (ID, Email) to avoid retrieving sensitive data.
|
Severity: info |
LiveReview Pre-Commit Check: ran (iter:1, coverage:0%)
LiveReview Pre-Commit Check: vouched (iter:1, coverage:0%)
LiveReview Pre-Commit Check: ran (iter:1, coverage:0%)
LiveReview Pre-Commit Check: ran (iter:1, coverage:0%)
LiveReview Pre-Commit Check: vouched (iter:1, coverage:0%)