Skip to content

Commit 769c564

Browse files
authored
Merge pull request #3 from gaarutyunov/claude/issue-1-20260331-0731
feat: TASK-01 Repository Scaffold
2 parents e1009f6 + 7d36963 commit 769c564

21 files changed

Lines changed: 390 additions & 1 deletion

File tree

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
bin/
2+
*.test
3+
*.out
4+
.env
5+
.env.*
6+
vendor/

.golangci.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
version: "2"
2+
linters:
3+
enable:
4+
- errcheck
5+
- gosimple
6+
- govet
7+
- ineffassign
8+
- staticcheck
9+
- unused
10+
- gofmt
11+
- goimports
12+
- misspell
13+
- revive
14+
- exhaustive
15+
- noctx
16+
- bodyclose
17+
- contextcheck
18+
linters-settings:
19+
goimports:
20+
local-prefixes: github.com/your-org/mcp-anything
21+
revive:
22+
rules:
23+
- name: exported
24+
- name: error-return
25+
- name: error-strings
26+
issues:
27+
exclude-use-default: false
28+
max-issues-per-linter: 0
29+
max-same-issues: 0

CLAUDE.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# CLAUDE.md — AI Agent Instructions for mcp-anything
2+
3+
## Project
4+
mcp-anything is a stateless Go proxy that converts HTTP REST APIs into MCP (Model Context Protocol) tools.
5+
Full design: SPEC.md
6+
7+
## Module
8+
github.com/your-org/mcp-anything
9+
10+
## Commands
11+
12+
### Build
13+
make build # go build ./cmd/proxy
14+
15+
### Lint (must pass before every commit)
16+
make lint # golangci-lint run ./...
17+
18+
### Vet (must pass before every commit)
19+
make vet # go vet ./...
20+
21+
### Unit tests (must pass before every commit)
22+
make test # go test -race -count=1 ./...
23+
24+
### Integration tests (require Docker + TC_CLOUD_TOKEN env var)
25+
make integration # go test -tags integration -race -count=1 -timeout 300s ./...
26+
27+
### All checks (run before every commit)
28+
make check # runs lint + vet + test + build in sequence
29+
30+
## Pre-commit checklist
31+
Run `make check` and fix all failures before committing. Never commit with failing lint, vet, or unit tests. Integration tests are run in CI but should also pass locally if Docker is available.
32+
33+
## Code conventions
34+
- All errors must be wrapped with context: `fmt.Errorf("loading spec: %w", err)`
35+
- No `panic()` in library code; only in `main()` for unrecoverable startup failures
36+
- Structured logging via `log/slog` with `slog.Default()`; keys are snake_case
37+
- No global mutable state; pass dependencies explicitly
38+
- Interfaces are defined in the package that uses them, not the package that implements them
39+
- Use `context.Context` as the first argument in all functions that do I/O or call other services
40+
- All config fields that reference secrets use `${ENV_VAR}` syntax; never log expanded values
41+
- Integration tests live in files named `*_integration_test.go` with build tag `//go:build integration`
42+
- Unit tests live in files named `*_test.go` with no build tag
43+
44+
## Testcontainers
45+
Set `TC_CLOUD_TOKEN` environment variable to use Testcontainers Cloud. Without it, tests use the local Docker daemon. The library auto-detects.
46+
47+
## Active development
48+
This project has no public users. There is no backward compatibility requirement. Interfaces, config schemas, and APIs may change freely between tasks.
49+
50+
## No stubs
51+
Implementation tasks must produce complete, working code. Do not write placeholder functions that return `nil, nil` or `errors.New("not implemented")`. If a feature is not yet needed, do not create the function at all.

Makefile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
.PHONY: build lint vet test integration check clean
2+
3+
BINARY := bin/proxy
4+
GOFLAGS := -race
5+
INTEGRATION_TIMEOUT := 300s
6+
7+
build:
8+
go build -o $(BINARY) ./cmd/proxy
9+
10+
lint:
11+
golangci-lint run ./...
12+
13+
vet:
14+
go vet ./...
15+
16+
test:
17+
go test $(GOFLAGS) -count=1 ./...
18+
19+
integration:
20+
go test $(GOFLAGS) -tags integration -count=1 -timeout $(INTEGRATION_TIMEOUT) ./...
21+
22+
check: lint vet test build
23+
24+
clean:
25+
rm -rf bin/

README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,20 @@
11
# mcp-anything
2-
A configurable gateway that transforms any API into MCP server
2+
3+
A stateless Kubernetes-native proxy that converts any HTTP REST API into an MCP (Model Context Protocol) server. Define your upstream API via an OpenAPI 3.0 spec, optionally apply an OpenAPI Overlay to filter and rename operations, and the proxy automatically generates MCP tools — no code required.
4+
5+
## Status
6+
Active development. No stability guarantees.
7+
8+
## Design
9+
See [SPEC.md](SPEC.md) for the full architecture and design decisions.
10+
11+
## Quick start
12+
(To be filled in when the MVP proxy is working — see TASK-03)
13+
14+
## Development
15+
Requirements: Go 1.23+, Docker (for integration tests)
16+
17+
make check # lint + vet + unit tests + build
18+
make integration # integration tests (requires Docker)
19+
20+
Set `TC_CLOUD_TOKEN` to run integration tests via Testcontainers Cloud.

cmd/proxy/main.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
)
7+
8+
func main() {
9+
fmt.Fprintln(os.Stderr, "mcp-anything: not yet implemented")
10+
os.Exit(1)
11+
}

deploy/example/config.yaml

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
server:
2+
port: 8080
3+
read_timeout: 30s
4+
write_timeout: 60s
5+
shutdown_timeout: 10s
6+
max_request_body: 1MB
7+
startup_validation_timeout: 30s # per-upstream timeout for jq dry-run at startup
8+
# on hot-reload: exceeded → abandon reload, keep old config
9+
transport: # list of enabled transports
10+
- streamable-http # primary: POST+GET on group endpoint paths
11+
- sse # legacy: GET on {endpoint}/sse paths
12+
13+
telemetry:
14+
otlp_endpoint: "otel-collector:4317"
15+
service_name: "mcp-anything"
16+
service_version: "v0.1.0"
17+
insecure: false
18+
19+
# Default inbound auth — applies to all operations unless x-mcp-auth-required: false
20+
inbound_auth:
21+
strategy: jwt # jwt | introspection | apikey | lua | none
22+
jwt:
23+
issuer: "https://idp.example.com"
24+
audience: "https://mcp.example.com"
25+
jwks_url: "" # optional; if empty, uses issuer discovery
26+
introspection:
27+
issuer: "https://idp.example.com"
28+
client_id: "${INTROSPECTION_CLIENT_ID}"
29+
client_secret: "${INTROSPECTION_CLIENT_SECRET}"
30+
audience: "https://mcp.example.com"
31+
apikey:
32+
header: "X-API-Key"
33+
keys_env: "MCP_API_KEYS" # comma-separated list in env var
34+
lua:
35+
script_path: "/etc/mcp-anything/auth.lua"
36+
timeout: 500ms
37+
38+
naming:
39+
separator: "__"
40+
max_length: 128
41+
conflict_resolution: error # error | first_wins | skip
42+
description_max_length: 1024 # 0 = no truncation
43+
description_truncation_suffix: "..."
44+
default_slug_rules:
45+
replace_slashes: true
46+
replace_braces: true
47+
lowercase: true
48+
collapse_separators: true
49+
50+
upstreams:
51+
- name: petstore
52+
enabled: true
53+
tool_prefix: pets
54+
base_url: "https://api.petstore.io/v2"
55+
max_response_body: 10MB
56+
timeout: 10s
57+
tls_skip_verify: false
58+
headers:
59+
X-Proxy-Source: "mcp-anything"
60+
61+
openapi:
62+
source: "/etc/mcp-anything/specs/petstore.yaml" # file path or https:// URL
63+
auth_header: "" # "Bearer ${TOKEN}" for private docs
64+
refresh_interval: 0 # 0 = no refresh; >0 = background URL refresh
65+
max_refresh_failures: 5
66+
allow_external_refs: false
67+
version: "3.0"
68+
69+
# Overlay is always applied after spec load and re-applied on every refresh.
70+
# source may be a file path or https:// URL.
71+
# auth_header and refresh_interval are independent of the spec's values.
72+
overlay:
73+
source: "/etc/mcp-anything/overlays/petstore-overlay.yaml"
74+
auth_header: ""
75+
refresh_interval: 0 # 0 = refresh together with openapi.refresh_interval
76+
77+
outbound_auth:
78+
strategy: oauth2_client_credentials
79+
oauth2_client_credentials:
80+
token_url: "https://idp.example.com/oauth/token"
81+
client_id: "${PETSTORE_CLIENT_ID}"
82+
client_secret: "${PETSTORE_CLIENT_SECRET}"
83+
scopes: ["read:pets", "write:pets"]
84+
bearer:
85+
token_env: "UPSTREAM_TOKEN"
86+
api_key:
87+
header: "X-API-Key"
88+
value_env: "UPSTREAM_API_KEY"
89+
prefix: "" # prepended to env value, e.g. "ApiKey "
90+
lua:
91+
script_path: "/etc/mcp-anything/upstream-auth.lua"
92+
timeout: 500ms
93+
94+
validation:
95+
validate_request: true
96+
validate_response: true
97+
response_validation_failure: warn # warn | fail
98+
success_status: [200, 201, 202, 204]
99+
error_status: [400, 401, 403, 404, 422, 429, 500, 502, 503]
100+
101+
- name: github
102+
enabled: true
103+
tool_prefix: gh
104+
base_url: "https://api.github.com"
105+
openapi:
106+
source: "https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.qkg1.top.yaml"
107+
refresh_interval: 1h
108+
overlay:
109+
source: "https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/mcp-overlay.yaml"
110+
refresh_interval: 1h
111+
outbound_auth:
112+
strategy: bearer
113+
bearer:
114+
token_env: "GITHUB_TOKEN"
115+
116+
groups:
117+
- name: all
118+
endpoint: /mcp
119+
upstreams: [petstore, github]
120+
# no filter = all tools from all listed upstreams
121+
122+
- name: readonly
123+
endpoint: /mcp/readonly
124+
upstreams: [petstore]
125+
# RFC 9535 JSONPath filter evaluated against each operation node
126+
filter: "$.paths.*.get[?(@['x-mcp-safe'] == true)]"
127+
128+
- name: premium
129+
endpoint: /mcp/premium
130+
upstreams: [petstore, github]
131+
filter: "$.paths.*.*[?(@['x-mcp-tier'] == 'premium')]"
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
overlay: 1.0.0
2+
info:
3+
title: Pet Store MCP Overlay
4+
version: 1.0.0
5+
x-speakeasy-jsonpath: rfc9535
6+
7+
actions:
8+
# Remove internal endpoints entirely
9+
- target: $.paths['/internal/metrics']
10+
remove: true
11+
12+
# Disable destructive operation — stays in spec but excluded from tools
13+
- target: $.paths['/pets/{petId}'].delete
14+
update:
15+
x-mcp-enabled: false
16+
17+
# Public health endpoint — no auth required
18+
- target: $.paths['/health'].get
19+
update:
20+
x-mcp-auth-required: false
21+
22+
# Override tool names and descriptions
23+
- target: $.paths['/pets'].get
24+
update:
25+
x-mcp-tool-name: list_pets
26+
description: "List all available pets with optional status filter."
27+
x-mcp-safe: true
28+
29+
# Mark premium operations
30+
- target: $.paths['/pets'].post
31+
update:
32+
x-mcp-tier: premium

deploy/helm/.gitkeep

Whitespace-only changes.

go.mod

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
module github.com/your-org/mcp-anything
2+
3+
go 1.23
4+
5+
require (
6+
github.com/brianvoe/gofakeit/v7 v7.2.1
7+
github.com/coreos/go-oidc/v3 v3.17.0
8+
github.com/fsnotify/fsnotify v1.9.0
9+
github.com/getkin/kin-openapi v0.134.0
10+
github.com/go-chi/chi/v5 v5.2.0
11+
github.com/itchyny/gojq v0.12.18
12+
github.com/knadh/koanf/parsers/yaml v0.1.0
13+
github.com/knadh/koanf/providers/file v1.1.2
14+
github.com/knadh/koanf/v2 v2.1.2
15+
github.com/lucasjones/reggen v0.0.0-20200904144131-37352a28cb6b
16+
github.com/modelcontextprotocol/go-sdk v1.3.0
17+
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2
18+
github.com/speakeasy-api/openapi-overlay v0.10.3
19+
github.com/testcontainers/testcontainers-go v0.36.0
20+
github.com/yuin/gopher-lua v1.1.1
21+
github.com/zitadel/oidc/v3 v3.45.1
22+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0
23+
go.opentelemetry.io/otel v1.35.0
24+
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0
25+
go.opentelemetry.io/otel/exporters/prometheus v0.57.0
26+
go.opentelemetry.io/otel/metric v1.35.0
27+
go.opentelemetry.io/otel/sdk v1.35.0
28+
go.opentelemetry.io/otel/sdk/metric v1.35.0
29+
go.opentelemetry.io/otel/trace v1.35.0
30+
golang.org/x/oauth2 v0.33.0
31+
gopkg.in/yaml.v3 v3.0.1
32+
)

0 commit comments

Comments
 (0)