add AGENTS.md, update deps, fix mcp
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
# AGENTS.md — go-server-with-otel (template)
|
||||
|
||||
A ready-to-fork template app for the `go-app` framework: HTTP + gRPC +
|
||||
grpc-gateway + MCP + OTEL/Prometheus, wired and building. Fork it, rename it,
|
||||
replace the `demo` domain with your service. See go-app's AGENTS.md for
|
||||
framework internals.
|
||||
|
||||
## Kick off a new app (do these in order)
|
||||
|
||||
1. **Rename via the Makefile** (rewrites module path, binary/app name,
|
||||
Dockerfile, helm, buf `merge_file_name`, main.go `appName`; deletes the old
|
||||
swagger file). GNU `sed` required (macOS: `brew install gnu-sed` or coreutils
|
||||
on PATH). The target is interactive, so pipe confirmation:
|
||||
```sh
|
||||
echo y | make rename NAME=your.gitremote/pathto/newapp APP=new-app-name
|
||||
```
|
||||
It does **not** rename the `demo` domain — that's steps 4–6. Afterward verify
|
||||
`git grep go-server-with-otel` is empty and update `.gitea/workflows/ci.yml`.
|
||||
|
||||
2. **Edit config** (`pkg/config/custom.go`): put app fields on `ServiceConfig`
|
||||
(keep the embedded `*config.AppConfig`). Add `env:"..."` tags for anything
|
||||
env-configurable — **and see the env gotcha below.** Update `config.yaml`,
|
||||
`env-sample`, and `helm/values.yaml` to match. Then `make schema`.
|
||||
|
||||
3. **Define your proto**: replace `proto/demo/app/v1alpha1/` with
|
||||
`proto/<domain>/v1alpha1/`, update `PROTO_DIRS` in the Makefile, and run
|
||||
`make proto` (buf; managed mode → generates into `api/<same path>`, so the
|
||||
proto `go_package` option is overridden — don't fight it). Delete `api/demo`.
|
||||
|
||||
4. **Implement `service.AppService`** (`Init`, `GetGRPC`, `GetHTTP`) in a new
|
||||
`pkg/<domain>/` package, mirroring `pkg/demo`:
|
||||
- `<domain>grpc/` — gRPC impl (embed `pb.Unimplemented...Server`); `GetServices`
|
||||
returns `*opts.GRPCService`; `GetDialOpts` adds the insecure creds the
|
||||
gateway needs.
|
||||
- `<domain>mcp/` — `mcp.NewServer` exposed as `HTTPHandler{Prefix:"/api/mcp"}`;
|
||||
tools via `mcp.AddTool`, typically delegating to the gRPC impl.
|
||||
- Remove `demohttp/` unless you actually need plain HTTP funcs.
|
||||
|
||||
5. **Register it in `main.go`**: set `appServices = []service.AppService{&yoursvc}`.
|
||||
This should be the only functional change in `main.go`.
|
||||
|
||||
6. **Delete `pkg/demo`** and any remaining `demo` references.
|
||||
|
||||
7. Build/verify: `go build ./... && go test ./...`, then run and hit `/metrics`,
|
||||
`/api/...` (REST), `:8081` (grpc + reflection), `/api/mcp`.
|
||||
|
||||
## Gotchas the template inherits from go-app
|
||||
|
||||
- **Custom-field env doesn't auto-apply.** `MustLoadConfigInto` only parses env
|
||||
for the embedded `AppConfig`. Add a `ServiceConfig.LoadEnv()` that runs
|
||||
`env.Parse` over the custom fields (nil the embedded `*AppConfig` first to keep
|
||||
go-app's precedence) and call it in `main.go` right after `MustLoadConfigInto`.
|
||||
- **REST gateway 404s** unless `grpcGatewayPathStrip: true` is set in the grpc
|
||||
config (default is false, so the `/api` prefix isn't stripped before matching).
|
||||
- **Prometheus double-unit suffix**: don't use `metric.WithUnit` for gauges whose
|
||||
names already carry the unit; the exporter appends another suffix.
|
||||
- MCP streamable HTTP: clients must POST to `/api/mcp/` (trailing slash); the
|
||||
bare path 307-redirects.
|
||||
|
||||
## What `make rename` does NOT touch
|
||||
|
||||
The `demo` domain naming: package dirs (`pkg/demo*`), `proto/demo`, `api/demo`,
|
||||
types (`DemoService`, `DemoAppService`, `DemoTool`, …), `PROTO_DIRS`, and the
|
||||
demo values in `config.yaml`/`helm`. Rename those by hand in steps 2–6.
|
||||
Reference in New Issue
Block a user