Skip to content

fix: escape proto comments correctly in generated descriptions and schemas (#100) - #101

Merged
erikist merged 2 commits into
mainfrom
factory/100-fix-escape-proto-comments-correctly-in
Oct 8, 2026
Merged

erikist merged 2 commits into
mainfrom
factory/100-fix-escape-proto-comments-correctly-in

Conversation

@erikist

@erikist erikist commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Closes #100

Summary

Two bugs in how proto comments become Go string literals and JSON Schema descriptions, both in processCommentToString (cmd/protoc-gen-go-mcp/mcp.go):

  1. A backslash in an RPC or message comment broke generation. processCommentToString only escaped ", so a comment like // matches \d+ produced Go source that didn't parse (strconv.Quote requires \\, not a bare \). Fixed by emitting the tool Description field with strconv.Quote(methodDescription) instead of hand-wrapping the raw string in "s.
  2. Quotes were double-escaped in schema descriptions. schema.go runs comments through processCommentToString, which escaped " to \", and then json.Marshal escaped the resulting backslash a second time, so clients saw \"quote\" in tool and field descriptions. Fixed by making processCommentToString return the raw comment text, untouched beyond whitespace normalization: each caller now does its own escaping exactly once (strconv.Quote for the Go literal in mcp.go, encoding/json for the schema description in schema.go).

processCommentToString's whitespace-normalization logic (joining lines, collapsing runs of spaces) also got a small rewrite so it strips both line-comment (// foo, with per-line // prefixes) and block-comment (/* foo */) markers uniformly, without relying on the two comment styles leaving inconsistent artifacts.

Decisions made

  • Added the required test characters (", \, a backtick, and a newline) to the existing example proto (examples/protos/example.proto) rather than a separate test proto, extending the SetVibeRequest.vibe field comment and the VibeService's block comment on SetVibe, since the golden-file and e2e tests already exercise that proto end to end.
  • Regenerated examples/gen/example/v1/*.pb.go with make generate (protoc v29.3, protoc-gen-go v1.36.6, protoc-gen-go-grpc v1.5.1 — matching what's already pinned in golden_test.go and used elsewhere in this repo) and updated the golden file.

Test evidence

$ gofmt -l .
(no output)

$ go vet ./...
(no output)

$ go build ./...
(no output)

$ go test ./...
ok      protoc-gen-go-mcp/cmd/protoc-gen-go-mcp        0.017s
ok      protoc-gen-go-mcp/examples/gen/example/v1      (cached)
?       protoc-gen-go-mcp/cmd/mcp-vibe  [no test files]

$ go test ./cmd/protoc-gen-go-mcp -run Golden -v
--- PASS: TestGolden (0.00s)
PASS

New unit test TestProcessCommentToString (cmd/protoc-gen-go-mcp/mcp_test.go) asserts the function passes through a double quote, a backslash, a backtick, multi-line joining, and a block comment unescaped. The existing end-to-end test TestToolsList (examples/gen/example/v1/e2e_test.go) was updated to assert the SetVibe tool's description and its vibe field's schema description match the new comment text exactly, as read off the real MCP JSON-RPC wire response.

Confirmed the backslash bug existed before this fix: before the fix, adding the backslash to the proto source made go build ./... fail (invalid Go string literal) and TestToolsList showed the double-escaped quote diff.

Notes for reviewers

  • Self-reviewed with the reviewer subagent against the issue's acceptance criteria; it found no blocking issues. One clarity nit about processCommentToString's internal doc comment was addressed in a follow-up commit.

  • No changes outside cmd/protoc-gen-go-mcp/mcp.go, its test, the example proto, and the regenerated example files.

  • Factory-authored

sf-factory-bot added 2 commits October 8, 2026 19:04
Two bugs in how proto comments become Go string literals and JSON
Schema descriptions:

- processCommentToString escaped only ", so a comment containing a
  backslash (e.g. "matches \d+") produced an invalid Go string
  literal. Tool descriptions are now emitted with strconv.Quote
  instead of hand-wrapping the raw text in quotes, so any character
  valid in the source comment round-trips correctly.
- processCommentToString also backslash-escaped " before the result
  was fed to schema.go's JSONSchema (later encoding/json-marshaled),
  so json.Marshal escaped it a second time and clients saw
  \\"quote\\" in schema descriptions. processCommentToString no
  longer escapes anything: callers are responsible for escaping the
  raw comment text for whatever they embed it in (strconv.Quote for a
  Go literal, encoding/json for a schema description).

Added comments with a double quote, a backslash, a backtick and a
newline to examples/protos/example.proto's SetVibeRequest.vibe field
and the VibeService's SetVibe RPC, regenerated the example and golden
file, and added a unit test (TestProcessCommentToString) covering
each character directly.
@erikist

erikist commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

🔍 Review (Claude, on behalf of @erikist): verified in the factory image.

  • Checks: make generate leaves no diff, and the golden and e2e tests pass.
  • Hostile comments: I put comments containing \d+, "quoted", a backtick, */, %s %v, \\, ${x}, \u0041 and non-ASCII on an RPC, a message and two fields. The generated code compiles, and in go-sdk tools/list every description came back exactly as written.
  • Escaping: backticks fall back to a quoted literal, and the double-escaping is gone.
  • Normalization: multi-line comments are still joined the same way.

Nits for later:

  • The doc comment at mcp.go:182-190 overstates what the trimming does: protoc already strips // and /* */.
  • The new unit cases use comment shapes protoc never produces.

Merging ✅

@erikist
erikist merged commit 5171bd7 into main Oct 8, 2026
9 checks passed
@erikist
erikist deleted the factory/100-fix-escape-proto-comments-correctly-in branch October 8, 2026 19:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: escape proto comments correctly in generated descriptions and schemas

1 participant