Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
62d3c1c
test(01-01): add JVM language option parser coverage
Yakwilik Apr 14, 2026
cab3b3e
feat(01-01): accept JVM generator language options
Yakwilik Apr 14, 2026
fee6428
feat(01-02): add shared JVM naming helpers
Yakwilik Apr 14, 2026
b4ea98d
feat(01-02): define shared JVM semantic model
Yakwilik Apr 14, 2026
a8eb069
feat(01-02): collect shared JVM model semantics
Yakwilik Apr 14, 2026
01d363c
feat(01-03): route JVM targets through shared model collection
Yakwilik Apr 14, 2026
48d7db9
test(01-03): prove JVM generation fails before output
Yakwilik Apr 14, 2026
44e7b50
docs(01-03): document shared JVM foundation status
Yakwilik Apr 14, 2026
63f7b1a
fix(01): close JVM foundation review findings
Yakwilik Apr 14, 2026
6440e36
feat(02-01): carry task support through JVM IR
Yakwilik Apr 15, 2026
1f9f4d5
feat(02-01): add JVM package resolver
Yakwilik Apr 15, 2026
f9a01f1
docs(02-01): clarify task support IR fields
Yakwilik Apr 15, 2026
ff2da0c
feat(02-02): add Kotlin MCP renderer contract
Yakwilik Apr 15, 2026
039d022
feat(02-03): wire Kotlin generation output
Yakwilik Apr 15, 2026
5b7d42f
test(04-01): add failing JVM outer class resolver coverage
Yakwilik Apr 15, 2026
f71ea5d
fix(04-01): align JVM outer class resolution with protoc
Yakwilik Apr 15, 2026
ea96f68
test(04-01): add failing Kotlin SDK and schema contract coverage
Yakwilik Apr 15, 2026
9036112
fix(04-01): harden generated Kotlin schema handling
Yakwilik Apr 15, 2026
608a43a
feat(04-01): add JVM Gradle compile gate foundation
Yakwilik Apr 15, 2026
974185b
feat: add Java and Kotlin MCP server generation
Yakwilik Apr 19, 2026
4e76aff
Add JVM standalone examples and Python execution metadata
Yakwilik May 1, 2026
4a270f8
Address Copilot review feedback
Yakwilik May 1, 2026
52a6d86
feat(07-01): add typescript target option plumbing
Yakwilik May 3, 2026
27d4bcd
feat(07-01): emit typescript sidecar foundation
Yakwilik May 3, 2026
8630f77
chore(07-02): add node sdk spike project
Yakwilik May 3, 2026
7382d8d
test(07-02): prove low-level typescript sdk seam
Yakwilik May 3, 2026
78e55ef
test(08-01): add failing test for typescript semantic model
Yakwilik May 3, 2026
99a972c
feat(08-01): implement typescript semantic model
Yakwilik May 3, 2026
e48dbad
test(08-01): add failing test for typescript names
Yakwilik May 3, 2026
936258e
feat(08-01): add typescript names and import checks
Yakwilik May 3, 2026
b9693bd
test(08-02): add failing TypeScript renderer contracts
Yakwilik May 3, 2026
b094174
feat(08-02): implement TypeScript public renderer API
Yakwilik May 3, 2026
43cae1e
test(08-02): refresh TypeScript public API golden
Yakwilik May 3, 2026
59055ca
test(08-03): add failing TypeScript compile smoke
Yakwilik May 4, 2026
d07e506
fix(08-03): make generated TypeScript compile smoke pass
Yakwilik May 4, 2026
6cc4312
docs(08-03): document TypeScript public API guidance
Yakwilik May 4, 2026
54da8ff
chore(08-03): run phase verification gates
Yakwilik May 4, 2026
f13186a
fix(08): normalize typescript public api names
Yakwilik May 4, 2026
35c8605
test(09-01): add TypeScript runtime list contract red tests
Yakwilik May 6, 2026
e30a38b
feat(09-01): install TypeScript low-level list handlers
Yakwilik May 6, 2026
db30f2f
test(09-01): refresh TypeScript runtime list golden
Yakwilik May 6, 2026
5b391f8
test(09-02): add TypeScript runtime contract red test
Yakwilik May 6, 2026
9bdd8f4
feat(09-02): implement TypeScript tools call dispatch
Yakwilik May 6, 2026
043b683
test(09-02): refresh TypeScript dispatch contracts
Yakwilik May 6, 2026
e634c47
test(09-03): add advanced TypeScript ProtoJSON red test
Yakwilik May 6, 2026
5368136
feat(09-03): complete TypeScript advanced ProtoJSON parity
Yakwilik May 6, 2026
62d4f91
test(09-03): refresh TypeScript advanced runtime contracts
Yakwilik May 6, 2026
f73f280
fix(09): share typescript registry across sidecars
Yakwilik May 6, 2026
d565729
test(10-03): add generated Node stdio verification
Yakwilik May 7, 2026
2e5d0bb
ci(10-04): add Node verification gate
Yakwilik May 7, 2026
8ee6a68
feat(11-01): add standalone TypeScript example scaffold
Yakwilik May 7, 2026
5e9138d
fix(11-01): include generated TypeScript WKT descriptors
Yakwilik May 7, 2026
0645ad1
feat(11-02): add standalone TypeScript stdio server
Yakwilik May 7, 2026
0335a94
feat(11-03): add standalone JavaScript consumption proof
Yakwilik May 7, 2026
1ea9154
fix(11-01): refresh standalone TypeScript protobuf output
Yakwilik May 7, 2026
9961e4d
docs(12-01): document TypeScript rollout
Yakwilik May 7, 2026
57863b8
fix(11-01): refresh TypeScript standalone descriptor
Yakwilik May 7, 2026
e921bd1
fix(11-01): stabilize TypeScript standalone generation
Yakwilik May 7, 2026
6773744
feat(13-01): add Python handler option parsing
Yakwilik May 8, 2026
7b67b27
feat(13-02): add protobuf Python handler surface
Yakwilik May 8, 2026
7e7c2fc
fix(13-02): skip protobuf-only public type sidecars
Yakwilik May 8, 2026
9d7c978
docs(13): document Python handler selection
Yakwilik May 8, 2026
4803fb7
test(14-01): prove protobuf Python runtime registration
Yakwilik May 9, 2026
ef9af6d
test(14-01): cover protobuf Python invalid input paths
Yakwilik May 9, 2026
4d74bea
test(14-01): verify protobuf Python output failures
Yakwilik May 9, 2026
3487e91
test(14-02): cover protobuf Python runtime parity edges
Yakwilik May 14, 2026
1f35850
test(14-02): cover protobuf Python metadata parity
Yakwilik May 14, 2026
2e5baf4
feat(15-01): add protobuf Python standalone example
Yakwilik May 14, 2026
9bcc74c
docs(15-02): document protobuf Python handler mode
Yakwilik May 14, 2026
4f92269
feat: support dual Python handler generation
Yakwilik May 14, 2026
6d87350
examples: demonstrate dual Python handler generation
Yakwilik May 14, 2026
2a9aabd
docs: clarify Python dual handler example output
Yakwilik May 14, 2026
961401a
chore: ignore local IDE files
Yakwilik May 14, 2026
4b0b24b
docs: update protoc-gen-mcp skill
Yakwilik May 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
449 changes: 212 additions & 237 deletions .github/skills/protoc-gen-mcp/SKILL.md

Large diffs are not rendered by default.

67 changes: 58 additions & 9 deletions .github/skills/protoc-gen-mcp/references/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,17 @@
- **Fix**: Check AGENTS.md for supported well-known types. Use a supported alternative or add support in `internal/schema/schema.go`.

### Generated code has compile errors after regeneration
- **Cause**: Usually a mismatch between `*.pb.go` and `*.mcp.go`
- **Fix**: Ensure both `protoc-gen-go` and `protoc-gen-mcp` are regenerated together via `easyp generate`.
- **Cause**: Usually a mismatch between protobuf output and MCP sidecar output.
- **Fix**: Regenerate the affected package through the matching `easyp` config,
then refresh the relevant golden snapshot. Do not patch generated files by
hand except while diagnosing the renderer.

### Unknown `protoc-gen-mcp` parameter
- **Cause**: Plugin params are parsed through a typed single-source option path.
- **Fix**: Use supported params only:
`lang=go|python|kotlin|java|typescript`,
`python_runtime=google.protobuf|betterproto|grpclib`, and
`python_handler=dataclass|protobuf|dataclass+protobuf`.

## Test Failures

Expand All @@ -25,8 +34,11 @@
- **Fix**:
```bash
easyp --cfg easyp.test.yaml generate -p internal/testproto -r .
cp internal/testproto/example/v1/example.mcp.go testdata/golden/example.mcp.go.golden
```
Then refresh the matching file under `testdata/golden/` for the language that
changed, such as `example.mcp.go.golden`, `example_mcp.py.golden`,
`example_mcp_pb.py.golden`, `example_mcp.java.golden`,
`example_mcp.kt.golden`, or `example_mcp.ts.golden`.

### Schema validation test failure
- **Cause**: JSON Schema doesn't match expected structure for a field type
Expand All @@ -36,6 +48,17 @@
- **Cause**: Tool list, schema, or response format changed
- **Fix**: Check `internal/examplemcp/server.go` handler implementations match the current proto definition. Verify expected tool names and payloads in `stdio_test.go`.

### Go tests fail because `protoc` is missing
- **Cause**: A test or helper reintroduced shelling out to external `protoc`.
- **Fix**: Generator tests should build descriptor requests in-process through
`github.com/bufbuild/protocompile`. Local `go test ./...` must not require a
`protoc` binary in `PATH`.

### Python tests fail because `protobuf` or `mcp` is missing globally
- **Cause**: A test bypassed the hermetic Python bootstrap.
- **Fix**: Use `internal/pythontest` so tests create an isolated virtualenv and
install pinned runtime dependencies instead of relying on global packages.

## Runtime Issues

### "duplicate tool name" error at registration
Expand All @@ -54,20 +77,46 @@
- `Timestamp` must be RFC 3339 format
- `bytes` must be base64 encoded

### Python raw protobuf handlers are missing
- **Cause**: The example or Easyp config generated only dataclass mode.
- **Fix**: Use `python_handler=protobuf` for protobuf-only output in
`*_mcp.py`, or `python_handler=dataclass+protobuf` for dataclass output in
`*_mcp.py` plus raw protobuf output in `*_mcp_pb.py`.

### JVM server compiles but behavior does not match Go/Python
- **Cause**: Renderer delegated schema or ProtoJSON behavior to SDK-level
helpers instead of the generator-owned low-level contract.
- **Fix**: Keep Java/Kotlin registration on the low-level request-handler seam
and reuse generated raw schema JSON plus ProtoJSON parse/marshal helpers.

### TypeScript NodeNext compile errors
- **Cause**: Generated imports are missing `.js` specifiers or mix type/value
imports under `verbatimModuleSyntax`.
- **Fix**: Keep Protobuf-ES imports `.js`-suffixed and split `import type`
from value imports in `render_typescript.go`.

## easyp Workflow Issues

### "plugin not found" during generation
- **Cause**: `protoc-gen-mcp` binary not built or not in PATH
- **Fix**: The easyp config uses `go run ./cmd/protoc-gen-mcp` to invoke the plugin directly. Ensure `go` is available and the module dependencies are resolved (`go mod download`).
- **Fix**: Repository Easyp configs should invoke the plugin through the local
Go module. Standalone examples may build or install the local binary as part
of their Makefile/Gradle/npm flow; run the example's documented `make setup`,
`make generate`, or `make build` target first.

### Lint failures on options.proto
- **Cause**: `go_package` declaration issue or import path mismatch
- **Fix**: `mcp/options/v1/options.proto` must declare its own `go_package`. Do not use Easyp `go_package_prefix` overrides for this package.

## Debugging Tips

1. **Inspect generated schema**: Find `<Service>_<Method>_ToolSpecInputSchemaJSON` constant in `*.mcp.go`, paste JSON into a formatter
2. **Trace schema generation**: Add logging in `internal/schema/schema.go` `GenerateFieldSchema()` for the specific field type
3. **Test a single schema**: `go test ./internal/testproto/example/v1/ -run TestSchema -v`
4. **Test stdio interaction**: `go test ./internal/examplemcp/ -run TestStdio -v`
5. **Validate easyp configs**: `easyp --cfg easyp.yaml validate-config` and `easyp --cfg easyp.test.yaml validate-config`
1. **Inspect generated schema**: find the generated schema JSON constant in the
sidecar for the target language and paste JSON into a formatter.
2. **Trace schema generation**: inspect `internal/schema` first; renderers
should consume schema semantics instead of recomputing them.
3. **Test one target**: run the focused `internal/codegen` contract test for
Python, Java, Kotlin, or TypeScript before running `go test ./...`.
4. **Test stdio interaction**: use `internal/examplemcp` tests, standalone
`examples` tests, or MCP Inspector for a user-facing check.
5. **Validate easyp configs**: `easyp --cfg easyp.yaml validate-config` and
`easyp --cfg easyp.test.yaml validate-config`.
46 changes: 42 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,23 @@ jobs:
with:
python-version: "3.10"

- name: Install Python runtime dependencies
run: |
python -m pip install --upgrade pip
python -m pip install "mcp>=1.27,<2" "protobuf>=6,<7" "jsonschema>=4,<5"
- name: Install JDK
uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: "17"

- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "24"
cache: npm
cache-dependency-path: examples/node/sdk-spike/package-lock.json

- name: Install Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-version: "9.2.1"

- name: Install easyp
run: go install github.com/easyp-tech/easyp/cmd/easyp@v0.15.2-rc1
Expand Down Expand Up @@ -60,5 +73,30 @@ jobs:
- name: Verify generated files are up to date
run: git diff --exit-code

- name: Install Node dependencies
working-directory: examples/node/sdk-spike
run: npm ci

- name: Typecheck generated TypeScript SDK spike
working-directory: examples/node/sdk-spike
run: npm run typecheck

- name: Build generated TypeScript SDK spike
working-directory: examples/node/sdk-spike
run: npm run build

- name: Run generated Node stdio tests
run: go test ./internal/codegen -run 'TestTypeScriptGeneratedNodeServer.*OverStdio|TestTypeScriptGeneratedNodeServerRejectsInvalid(Input|Output)OverStdio' -count=1

- name: Build JVM examples
run: |
gradle --no-daemon -p examples/jvm :java-server:compileJava :kotlin-server:compileKotlin
gradle --no-daemon -p examples/jvm :java-server:installDist :kotlin-server:installDist

- name: Run JVM stdio tests
run: |
go test ./internal/examplemcp -run 'TestJava.*OverStdio' -count=1
go test ./internal/examplemcp -run 'TestKotlin.*OverStdio' -count=1

- name: Run tests
run: go test ./...
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,13 @@ examples/1_helloworld/helloworld-server
examples/2_weather_api/weather-server
examples/3_file_manager/file-server
examples/4_crm_system/crm-server
examples/jvm/.gradle/
examples/jvm/*/build/
examples/node/**/node_modules/
examples/node/**/dist/
examples/6_java_standalone/.gradle/
examples/6_java_standalone/build/
examples/7_kotlin_standalone/.gradle/
examples/7_kotlin_standalone/build/
.DS_Store
.idea/*
Loading
Loading