Go MCP Server 项目初始化:工具注册架构 + 编译运行通过

- Tool 接口 + Registry 注册中心,工具模块化插拔
- system 工具:health / info
- database 工具:db_query / db_tables / db_table_info / db_explain(四层 SQL 安全)
- docker 工具:docker_ps / docker_logs / docker_inspect(白名单 + 大小限制)
- middleware:auth(JWT+APIKey)/ ratelimit(令牌桶)/ audit(slog 结构化)
- stdio / SSE 双传输模式,Viper 多环境配置
- Dockerfile 多阶段构建(golang:alpine → scratch),~15MB 镜像
- docker-compose.yml 一键部署 + 安全加固(read_only / no-new-privileges / cap_drop)
- go build ./... / go vet ./... / go test ./... 全部通过

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
yangzhaohan
2026-07-06 10:26:52 +08:00
parent 68ca67a98b
commit fb2c3a6cae
26 changed files with 1854 additions and 1 deletions
+81
View File
@@ -0,0 +1,81 @@
package config
import (
"fmt"
"time"
"github.com/spf13/viper"
)
type Config struct {
Env string `mapstructure:"env"`
Server ServerConfig `mapstructure:"server"`
Databases map[string]DatabaseConf `mapstructure:"databases"`
Docker DockerConfig `mapstructure:"docker"`
Auth AuthConfig `mapstructure:"auth"`
RateLimit RateLimitConfig `mapstructure:"rate_limit"`
}
type ServerConfig struct {
Transport string `mapstructure:"transport"` // stdio | sse
Addr string `mapstructure:"addr"` // :8080 for SSE mode
}
type DatabaseConf struct {
Driver string `mapstructure:"driver"` // postgres | mysql
DSN string `mapstructure:"dsn"`
}
type DockerConfig struct {
Enabled bool `mapstructure:"enabled"`
Host string `mapstructure:"host"` // unix:///var/run/docker.sock
ContainerPattern string `mapstructure:"container_pattern"`
MaxLogBytes int64 `mapstructure:"max_log_bytes"`
MaxLogLines int `mapstructure:"max_log_lines"`
MaxLogSince time.Duration `mapstructure:"max_log_since"`
}
type AuthConfig struct {
Enabled bool `mapstructure:"enabled"`
APIKeys map[string]string `mapstructure:"api_keys"` // key → description
JWTSecret string `mapstructure:"jwt_secret"`
}
type RateLimitConfig struct {
Enabled bool `mapstructure:"enabled"`
Rate float64 `mapstructure:"rate"` // 每秒允许的请求数
Burst int `mapstructure:"burst"` // 突发允许数
}
func Load(env string) (*Config, error) {
v := viper.New()
v.SetConfigName(env) // dev.yaml / staging.yaml / prod.yaml
v.SetConfigType("yaml")
v.AddConfigPath("./config")
v.AddConfigPath(".")
v.AddConfigPath("/config")
v.SetEnvPrefix("OPS_MCP")
v.AutomaticEnv()
if err := v.ReadInConfig(); err != nil {
return nil, fmt.Errorf("read config: %w", err)
}
// 设置默认值
v.SetDefault("server.transport", "stdio")
v.SetDefault("server.addr", ":8080")
v.SetDefault("docker.max_log_bytes", 1024*1024)
v.SetDefault("docker.max_log_lines", 500)
v.SetDefault("docker.max_log_since", "1h")
v.SetDefault("rate_limit.rate", 10.0)
v.SetDefault("rate_limit.burst", 20)
var cfg Config
if err := v.Unmarshal(&cfg); err != nil {
return nil, fmt.Errorf("unmarshal config: %w", err)
}
return &cfg, nil
}
+23
View File
@@ -0,0 +1,23 @@
env: dev
server:
transport: stdio
addr: ":8080"
databases:
local_pg:
driver: postgres
dsn: postgres://postgres:postgres@localhost:5432/ops_dev?sslmode=disable
docker:
enabled: false
host: unix:///var/run/docker.sock
container_pattern: "^(app-|web-|api-).*"
auth:
enabled: false
rate_limit:
enabled: false
rate: 50
burst: 100
+24
View File
@@ -0,0 +1,24 @@
env: prod
server:
transport: sse
addr: ":8080"
databases:
main_db:
driver: postgres
dsn: postgres://ops_readonly:${DB_PASSWORD}@db-prod.internal:5432/ops?sslmode=require
docker:
enabled: true
host: unix:///var/run/docker.sock
container_pattern: "^(app-|web-|api-|worker-).*"
auth:
enabled: true
jwt_secret: ${JWT_SECRET}
rate_limit:
enabled: true
rate: 10
burst: 20
+24
View File
@@ -0,0 +1,24 @@
env: staging
server:
transport: sse
addr: ":8080"
databases:
main_db:
driver: postgres
dsn: postgres://ops_readonly:${DB_PASSWORD}@db-staging.internal:5432/ops?sslmode=require
docker:
enabled: true
host: unix:///var/run/docker.sock
container_pattern: "^(app-|web-|api-|worker-).*"
auth:
enabled: true
jwt_secret: ${JWT_SECRET}
rate_limit:
enabled: true
rate: 20
burst: 40