An MCP server for Upwind that exposes a read-only security and inventory surface over the official Go MCP SDK.
The first release is intended to cover:
- Inventory search and asset lookups
- Threat story search and detail views
- Vulnerability findings
- Configuration findings, frameworks, and rules
- SBOM package queries
- API security endpoint listing
This repository contains the server source under cmd/upwind-mcp.
Requirements:
- Go
1.26.x
Run over stdio directly from source:
go run ./cmd/upwind-mcpBuild a local binary:
go build -o upwind-mcp ./cmd/upwind-mcp
./upwind-mcp
./upwind-mcp versionIf you prefer just over a Makefile:
just build
just run
just run-http
just docker-build
just docker-runjust loads .env automatically when present. just docker-run starts Streamable HTTP on 127.0.0.1:8080 with a hardened docker run profile and requires UPWIND_MCP_HTTP_BEARER_TOKEN.
stdio is the default transport.
go run ./cmd/upwind-mcpStreamable HTTP is opt-in for local integrations and tooling.
go run ./cmd/upwind-mcp serve-httpBy default, HTTP mode only allows loopback binds such as 127.0.0.1:8080 or localhost:8080. If you set UPWIND_MCP_HTTP_ADDR to a non-loopback address, you must also pass --public-bind.
go run ./cmd/upwind-mcp serve-http --public-bindLegacy standalone SSE is intentionally not supported.
Configure Upwind access and server behavior with environment variables. upwind-mcp also reads a local .env file automatically when present. For each setting, the process environment takes precedence and .env is used only as a fallback.
UPWIND_REGIONdefaultus; supported values areus,eu, andmeUPWIND_BASE_URLoptional override for the Upwind API base URLUPWIND_ORGANIZATION_IDUPWIND_CLIENT_IDUPWIND_CLIENT_SECRETUPWIND_REQUEST_TIMEOUTdefault30sUPWIND_MCP_HTTP_ADDRdefault127.0.0.1:8080UPWIND_MCP_HTTP_PATHdefault/mcpUPWIND_MCP_HTTP_BEARER_TOKENrequired for HTTP modeUPWIND_MCP_LOGdefaultdisabled; supported values aredisabled,text, andjsonUPWIND_MCP_LOG_LEVELdefaultinfo; supported values aredebug,info,warn, anderror
stdio:
cat > .env <<'EOF'
UPWIND_ORGANIZATION_ID=org_...
UPWIND_CLIENT_ID=...
UPWIND_CLIENT_SECRET=...
UPWIND_MCP_LOG=text
UPWIND_MCP_LOG_LEVEL=info
EOF
go run ./cmd/upwind-mcpHTTP:
cat > .env <<'EOF'
UPWIND_ORGANIZATION_ID=org_...
UPWIND_CLIENT_ID=...
UPWIND_CLIENT_SECRET=...
UPWIND_MCP_HTTP_BEARER_TOKEN=local-dev-token
UPWIND_MCP_LOG=json
UPWIND_MCP_LOG_LEVEL=debug
EOF
go run ./cmd/upwind-mcp serve-httpHTTP mode is local-first and protected by a shared bearer token. Upwind credentials stay in environment variables only and are never printed back by the server.
See docs/security.md for the transport and deployment guidance.
Releases are automated with GoReleaser and GitHub Actions.
To publish a release, create and push a semantic version tag:
git tag v0.1.0
git push origin v0.1.0That tag triggers the release workflow in .github/workflows/release.yml, which:
- runs the test suite
- builds
upwind-mcpfor Linux, macOS, and Windows onamd64andarm64 - packages archives and uploads them to the GitHub Release
- builds and pushes a multi-architecture container image to
ghcr.io/oneslash/upwind-mcp - publishes a
checksums.txtfile alongside the artifacts
The tag is the release trigger. If a draft GitHub release already exists for the same tag, GoReleaser reuses it and attaches the built artifacts there.
Pre-release tags such as v0.2.0-rc.1 are published as GitHub pre-releases automatically.
For stable tags, the container image is pushed with both the Git tag and latest:
docker pull ghcr.io/oneslash/upwind-mcp:v0.1.0
docker pull ghcr.io/oneslash/upwind-mcp:latestFor pre-release tags, only the exact Git tag is published.