mnehmos.trace.mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (339) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1662 -0
  3. package/dist/adapters/bootstrap.d.ts +29 -0
  4. package/dist/adapters/bootstrap.d.ts.map +1 -0
  5. package/dist/adapters/bootstrap.js +46 -0
  6. package/dist/adapters/bootstrap.js.map +1 -0
  7. package/dist/adapters/errors.d.ts +94 -0
  8. package/dist/adapters/errors.d.ts.map +1 -0
  9. package/dist/adapters/errors.js +107 -0
  10. package/dist/adapters/errors.js.map +1 -0
  11. package/dist/adapters/graphql/index.d.ts +9 -0
  12. package/dist/adapters/graphql/index.d.ts.map +1 -0
  13. package/dist/adapters/graphql/index.js +9 -0
  14. package/dist/adapters/graphql/index.js.map +1 -0
  15. package/dist/adapters/graphql/sdl-parser.d.ts +74 -0
  16. package/dist/adapters/graphql/sdl-parser.d.ts.map +1 -0
  17. package/dist/adapters/graphql/sdl-parser.js +559 -0
  18. package/dist/adapters/graphql/sdl-parser.js.map +1 -0
  19. package/dist/adapters/grpc/adapter.d.ts +76 -0
  20. package/dist/adapters/grpc/adapter.d.ts.map +1 -0
  21. package/dist/adapters/grpc/adapter.js +362 -0
  22. package/dist/adapters/grpc/adapter.js.map +1 -0
  23. package/dist/adapters/grpc/index.d.ts +10 -0
  24. package/dist/adapters/grpc/index.d.ts.map +1 -0
  25. package/dist/adapters/grpc/index.js +12 -0
  26. package/dist/adapters/grpc/index.js.map +1 -0
  27. package/dist/adapters/grpc/proto-parser.d.ts +76 -0
  28. package/dist/adapters/grpc/proto-parser.d.ts.map +1 -0
  29. package/dist/adapters/grpc/proto-parser.js +523 -0
  30. package/dist/adapters/grpc/proto-parser.js.map +1 -0
  31. package/dist/adapters/grpc/type-converter.d.ts +43 -0
  32. package/dist/adapters/grpc/type-converter.d.ts.map +1 -0
  33. package/dist/adapters/grpc/type-converter.js +270 -0
  34. package/dist/adapters/grpc/type-converter.js.map +1 -0
  35. package/dist/adapters/grpc/types.d.ts +85 -0
  36. package/dist/adapters/grpc/types.d.ts.map +1 -0
  37. package/dist/adapters/grpc/types.js +7 -0
  38. package/dist/adapters/grpc/types.js.map +1 -0
  39. package/dist/adapters/index.d.ts +39 -0
  40. package/dist/adapters/index.d.ts.map +1 -0
  41. package/dist/adapters/index.js +50 -0
  42. package/dist/adapters/index.js.map +1 -0
  43. package/dist/adapters/mcp.d.ts +23 -0
  44. package/dist/adapters/mcp.d.ts.map +1 -0
  45. package/dist/adapters/mcp.js +293 -0
  46. package/dist/adapters/mcp.js.map +1 -0
  47. package/dist/adapters/openapi/adapter.d.ts +213 -0
  48. package/dist/adapters/openapi/adapter.d.ts.map +1 -0
  49. package/dist/adapters/openapi/adapter.js +557 -0
  50. package/dist/adapters/openapi/adapter.js.map +1 -0
  51. package/dist/adapters/openapi/convert.d.ts +120 -0
  52. package/dist/adapters/openapi/convert.d.ts.map +1 -0
  53. package/dist/adapters/openapi/convert.js +363 -0
  54. package/dist/adapters/openapi/convert.js.map +1 -0
  55. package/dist/adapters/openapi/index.d.ts +39 -0
  56. package/dist/adapters/openapi/index.d.ts.map +1 -0
  57. package/dist/adapters/openapi/index.js +48 -0
  58. package/dist/adapters/openapi/index.js.map +1 -0
  59. package/dist/adapters/openapi/parser.d.ts +95 -0
  60. package/dist/adapters/openapi/parser.d.ts.map +1 -0
  61. package/dist/adapters/openapi/parser.js +171 -0
  62. package/dist/adapters/openapi/parser.js.map +1 -0
  63. package/dist/adapters/registry.d.ts +116 -0
  64. package/dist/adapters/registry.d.ts.map +1 -0
  65. package/dist/adapters/registry.js +246 -0
  66. package/dist/adapters/registry.js.map +1 -0
  67. package/dist/adapters/trpc/adapter.d.ts +159 -0
  68. package/dist/adapters/trpc/adapter.d.ts.map +1 -0
  69. package/dist/adapters/trpc/adapter.js +223 -0
  70. package/dist/adapters/trpc/adapter.js.map +1 -0
  71. package/dist/adapters/trpc/extractor.d.ts +218 -0
  72. package/dist/adapters/trpc/extractor.d.ts.map +1 -0
  73. package/dist/adapters/trpc/extractor.js +708 -0
  74. package/dist/adapters/trpc/extractor.js.map +1 -0
  75. package/dist/adapters/trpc/index.d.ts +31 -0
  76. package/dist/adapters/trpc/index.d.ts.map +1 -0
  77. package/dist/adapters/trpc/index.js +40 -0
  78. package/dist/adapters/trpc/index.js.map +1 -0
  79. package/dist/adapters/trpc/parser.d.ts +119 -0
  80. package/dist/adapters/trpc/parser.d.ts.map +1 -0
  81. package/dist/adapters/trpc/parser.js +128 -0
  82. package/dist/adapters/trpc/parser.js.map +1 -0
  83. package/dist/compare/index.d.ts +33 -0
  84. package/dist/compare/index.d.ts.map +1 -0
  85. package/dist/compare/index.js +261 -0
  86. package/dist/compare/index.js.map +1 -0
  87. package/dist/core/types.d.ts +188 -0
  88. package/dist/core/types.d.ts.map +1 -0
  89. package/dist/core/types.js +9 -0
  90. package/dist/core/types.js.map +1 -0
  91. package/dist/extract/index.d.ts +26 -0
  92. package/dist/extract/index.d.ts.map +1 -0
  93. package/dist/extract/index.js +44 -0
  94. package/dist/extract/index.js.map +1 -0
  95. package/dist/index.d.ts +9 -0
  96. package/dist/index.d.ts.map +1 -0
  97. package/dist/index.js +674 -0
  98. package/dist/index.js.map +1 -0
  99. package/dist/languages/base.d.ts +57 -0
  100. package/dist/languages/base.d.ts.map +1 -0
  101. package/dist/languages/base.js +6 -0
  102. package/dist/languages/base.js.map +1 -0
  103. package/dist/languages/bootstrap.d.ts +10 -0
  104. package/dist/languages/bootstrap.d.ts.map +1 -0
  105. package/dist/languages/bootstrap.js +25 -0
  106. package/dist/languages/bootstrap.js.map +1 -0
  107. package/dist/languages/go/handlers/chi.d.ts +24 -0
  108. package/dist/languages/go/handlers/chi.d.ts.map +1 -0
  109. package/dist/languages/go/handlers/chi.js +205 -0
  110. package/dist/languages/go/handlers/chi.js.map +1 -0
  111. package/dist/languages/go/handlers/gin.d.ts +24 -0
  112. package/dist/languages/go/handlers/gin.d.ts.map +1 -0
  113. package/dist/languages/go/handlers/gin.js +156 -0
  114. package/dist/languages/go/handlers/gin.js.map +1 -0
  115. package/dist/languages/go/handlers/stdlib.d.ts +19 -0
  116. package/dist/languages/go/handlers/stdlib.d.ts.map +1 -0
  117. package/dist/languages/go/handlers/stdlib.js +112 -0
  118. package/dist/languages/go/handlers/stdlib.js.map +1 -0
  119. package/dist/languages/go/index.d.ts +18 -0
  120. package/dist/languages/go/index.d.ts.map +1 -0
  121. package/dist/languages/go/index.js +20 -0
  122. package/dist/languages/go/index.js.map +1 -0
  123. package/dist/languages/go/parser.d.ts +33 -0
  124. package/dist/languages/go/parser.d.ts.map +1 -0
  125. package/dist/languages/go/parser.js +95 -0
  126. package/dist/languages/go/parser.js.map +1 -0
  127. package/dist/languages/go/struct-extractor.d.ts +59 -0
  128. package/dist/languages/go/struct-extractor.d.ts.map +1 -0
  129. package/dist/languages/go/struct-extractor.js +483 -0
  130. package/dist/languages/go/struct-extractor.js.map +1 -0
  131. package/dist/languages/go/tag-parser.d.ts +62 -0
  132. package/dist/languages/go/tag-parser.d.ts.map +1 -0
  133. package/dist/languages/go/tag-parser.js +108 -0
  134. package/dist/languages/go/tag-parser.js.map +1 -0
  135. package/dist/languages/go/type-converter.d.ts +32 -0
  136. package/dist/languages/go/type-converter.d.ts.map +1 -0
  137. package/dist/languages/go/type-converter.js +226 -0
  138. package/dist/languages/go/type-converter.js.map +1 -0
  139. package/dist/languages/go/types.d.ts +153 -0
  140. package/dist/languages/go/types.d.ts.map +1 -0
  141. package/dist/languages/go/types.js +6 -0
  142. package/dist/languages/go/types.js.map +1 -0
  143. package/dist/languages/import-resolver.d.ts +645 -0
  144. package/dist/languages/import-resolver.d.ts.map +1 -0
  145. package/dist/languages/import-resolver.js +1278 -0
  146. package/dist/languages/import-resolver.js.map +1 -0
  147. package/dist/languages/index.d.ts +34 -0
  148. package/dist/languages/index.d.ts.map +1 -0
  149. package/dist/languages/index.js +93 -0
  150. package/dist/languages/index.js.map +1 -0
  151. package/dist/languages/json-schema.d.ts +40 -0
  152. package/dist/languages/json-schema.d.ts.map +1 -0
  153. package/dist/languages/json-schema.js +188 -0
  154. package/dist/languages/json-schema.js.map +1 -0
  155. package/dist/languages/python-ast/index.d.ts +8 -0
  156. package/dist/languages/python-ast/index.d.ts.map +1 -0
  157. package/dist/languages/python-ast/index.js +7 -0
  158. package/dist/languages/python-ast/index.js.map +1 -0
  159. package/dist/languages/python-ast/parser.d.ts +174 -0
  160. package/dist/languages/python-ast/parser.d.ts.map +1 -0
  161. package/dist/languages/python-ast/parser.js +1205 -0
  162. package/dist/languages/python-ast/parser.js.map +1 -0
  163. package/dist/languages/python-ast/type-resolver.d.ts +75 -0
  164. package/dist/languages/python-ast/type-resolver.d.ts.map +1 -0
  165. package/dist/languages/python-ast/type-resolver.js +421 -0
  166. package/dist/languages/python-ast/type-resolver.js.map +1 -0
  167. package/dist/languages/python-ast/types.d.ts +216 -0
  168. package/dist/languages/python-ast/types.d.ts.map +1 -0
  169. package/dist/languages/python-ast/types.js +6 -0
  170. package/dist/languages/python-ast/types.js.map +1 -0
  171. package/dist/languages/python.d.ts +55 -0
  172. package/dist/languages/python.d.ts.map +1 -0
  173. package/dist/languages/python.js +311 -0
  174. package/dist/languages/python.js.map +1 -0
  175. package/dist/languages/typescript.d.ts +272 -0
  176. package/dist/languages/typescript.d.ts.map +1 -0
  177. package/dist/languages/typescript.js +1381 -0
  178. package/dist/languages/typescript.js.map +1 -0
  179. package/dist/patterns/base.d.ts +146 -0
  180. package/dist/patterns/base.d.ts.map +1 -0
  181. package/dist/patterns/base.js +89 -0
  182. package/dist/patterns/base.js.map +1 -0
  183. package/dist/patterns/errors.d.ts +172 -0
  184. package/dist/patterns/errors.d.ts.map +1 -0
  185. package/dist/patterns/errors.js +185 -0
  186. package/dist/patterns/errors.js.map +1 -0
  187. package/dist/patterns/extractors.d.ts +170 -0
  188. package/dist/patterns/extractors.d.ts.map +1 -0
  189. package/dist/patterns/extractors.js +305 -0
  190. package/dist/patterns/extractors.js.map +1 -0
  191. package/dist/patterns/graphql/apollo-client.d.ts +80 -0
  192. package/dist/patterns/graphql/apollo-client.d.ts.map +1 -0
  193. package/dist/patterns/graphql/apollo-client.js +800 -0
  194. package/dist/patterns/graphql/apollo-client.js.map +1 -0
  195. package/dist/patterns/graphql/apollo-server.d.ts +55 -0
  196. package/dist/patterns/graphql/apollo-server.d.ts.map +1 -0
  197. package/dist/patterns/graphql/apollo-server.js +523 -0
  198. package/dist/patterns/graphql/apollo-server.js.map +1 -0
  199. package/dist/patterns/graphql/index.d.ts +11 -0
  200. package/dist/patterns/graphql/index.d.ts.map +1 -0
  201. package/dist/patterns/graphql/index.js +12 -0
  202. package/dist/patterns/graphql/index.js.map +1 -0
  203. package/dist/patterns/graphql/types.d.ts +213 -0
  204. package/dist/patterns/graphql/types.d.ts.map +1 -0
  205. package/dist/patterns/graphql/types.js +16 -0
  206. package/dist/patterns/graphql/types.js.map +1 -0
  207. package/dist/patterns/http-clients/axios.d.ts +148 -0
  208. package/dist/patterns/http-clients/axios.d.ts.map +1 -0
  209. package/dist/patterns/http-clients/axios.js +652 -0
  210. package/dist/patterns/http-clients/axios.js.map +1 -0
  211. package/dist/patterns/http-clients/fetch.d.ts +88 -0
  212. package/dist/patterns/http-clients/fetch.d.ts.map +1 -0
  213. package/dist/patterns/http-clients/fetch.js +364 -0
  214. package/dist/patterns/http-clients/fetch.js.map +1 -0
  215. package/dist/patterns/http-clients/index.d.ts +36 -0
  216. package/dist/patterns/http-clients/index.d.ts.map +1 -0
  217. package/dist/patterns/http-clients/index.js +50 -0
  218. package/dist/patterns/http-clients/index.js.map +1 -0
  219. package/dist/patterns/http-clients/property-access.d.ts +46 -0
  220. package/dist/patterns/http-clients/property-access.d.ts.map +1 -0
  221. package/dist/patterns/http-clients/property-access.js +818 -0
  222. package/dist/patterns/http-clients/property-access.js.map +1 -0
  223. package/dist/patterns/http-clients/type-inference.d.ts +48 -0
  224. package/dist/patterns/http-clients/type-inference.d.ts.map +1 -0
  225. package/dist/patterns/http-clients/type-inference.js +293 -0
  226. package/dist/patterns/http-clients/type-inference.js.map +1 -0
  227. package/dist/patterns/http-clients/types.d.ts +168 -0
  228. package/dist/patterns/http-clients/types.d.ts.map +1 -0
  229. package/dist/patterns/http-clients/types.js +10 -0
  230. package/dist/patterns/http-clients/types.js.map +1 -0
  231. package/dist/patterns/http-clients/url-extractor.d.ts +53 -0
  232. package/dist/patterns/http-clients/url-extractor.d.ts.map +1 -0
  233. package/dist/patterns/http-clients/url-extractor.js +338 -0
  234. package/dist/patterns/http-clients/url-extractor.js.map +1 -0
  235. package/dist/patterns/index.d.ts +44 -0
  236. package/dist/patterns/index.d.ts.map +1 -0
  237. package/dist/patterns/index.js +49 -0
  238. package/dist/patterns/index.js.map +1 -0
  239. package/dist/patterns/python/aiohttp.d.ts +21 -0
  240. package/dist/patterns/python/aiohttp.d.ts.map +1 -0
  241. package/dist/patterns/python/aiohttp.js +188 -0
  242. package/dist/patterns/python/aiohttp.js.map +1 -0
  243. package/dist/patterns/python/httpx.d.ts +20 -0
  244. package/dist/patterns/python/httpx.d.ts.map +1 -0
  245. package/dist/patterns/python/httpx.js +183 -0
  246. package/dist/patterns/python/httpx.js.map +1 -0
  247. package/dist/patterns/python/index.d.ts +32 -0
  248. package/dist/patterns/python/index.d.ts.map +1 -0
  249. package/dist/patterns/python/index.js +63 -0
  250. package/dist/patterns/python/index.js.map +1 -0
  251. package/dist/patterns/python/property-access.d.ts +27 -0
  252. package/dist/patterns/python/property-access.d.ts.map +1 -0
  253. package/dist/patterns/python/property-access.js +132 -0
  254. package/dist/patterns/python/property-access.js.map +1 -0
  255. package/dist/patterns/python/requests.d.ts +19 -0
  256. package/dist/patterns/python/requests.d.ts.map +1 -0
  257. package/dist/patterns/python/requests.js +239 -0
  258. package/dist/patterns/python/requests.js.map +1 -0
  259. package/dist/patterns/python/types.d.ts +95 -0
  260. package/dist/patterns/python/types.d.ts.map +1 -0
  261. package/dist/patterns/python/types.js +43 -0
  262. package/dist/patterns/python/types.js.map +1 -0
  263. package/dist/patterns/registry.d.ts +181 -0
  264. package/dist/patterns/registry.d.ts.map +1 -0
  265. package/dist/patterns/registry.js +304 -0
  266. package/dist/patterns/registry.js.map +1 -0
  267. package/dist/patterns/rest/express.d.ts +78 -0
  268. package/dist/patterns/rest/express.d.ts.map +1 -0
  269. package/dist/patterns/rest/express.js +289 -0
  270. package/dist/patterns/rest/express.js.map +1 -0
  271. package/dist/patterns/rest/fastify.d.ts +93 -0
  272. package/dist/patterns/rest/fastify.d.ts.map +1 -0
  273. package/dist/patterns/rest/fastify.js +420 -0
  274. package/dist/patterns/rest/fastify.js.map +1 -0
  275. package/dist/patterns/rest/index.d.ts +31 -0
  276. package/dist/patterns/rest/index.d.ts.map +1 -0
  277. package/dist/patterns/rest/index.js +45 -0
  278. package/dist/patterns/rest/index.js.map +1 -0
  279. package/dist/patterns/rest/middleware.d.ts +25 -0
  280. package/dist/patterns/rest/middleware.d.ts.map +1 -0
  281. package/dist/patterns/rest/middleware.js +219 -0
  282. package/dist/patterns/rest/middleware.js.map +1 -0
  283. package/dist/patterns/rest/path-parser.d.ts +50 -0
  284. package/dist/patterns/rest/path-parser.d.ts.map +1 -0
  285. package/dist/patterns/rest/path-parser.js +137 -0
  286. package/dist/patterns/rest/path-parser.js.map +1 -0
  287. package/dist/patterns/rest/response-inference.d.ts +44 -0
  288. package/dist/patterns/rest/response-inference.d.ts.map +1 -0
  289. package/dist/patterns/rest/response-inference.js +218 -0
  290. package/dist/patterns/rest/response-inference.js.map +1 -0
  291. package/dist/patterns/rest/types.d.ts +102 -0
  292. package/dist/patterns/rest/types.d.ts.map +1 -0
  293. package/dist/patterns/rest/types.js +10 -0
  294. package/dist/patterns/rest/types.js.map +1 -0
  295. package/dist/patterns/types.d.ts +105 -0
  296. package/dist/patterns/types.d.ts.map +1 -0
  297. package/dist/patterns/types.js +11 -0
  298. package/dist/patterns/types.js.map +1 -0
  299. package/dist/report/index.d.ts +11 -0
  300. package/dist/report/index.d.ts.map +1 -0
  301. package/dist/report/index.js +55 -0
  302. package/dist/report/index.js.map +1 -0
  303. package/dist/tools/contract-comments.d.ts +48 -0
  304. package/dist/tools/contract-comments.d.ts.map +1 -0
  305. package/dist/tools/contract-comments.js +130 -0
  306. package/dist/tools/contract-comments.js.map +1 -0
  307. package/dist/tools/index.d.ts +6 -0
  308. package/dist/tools/index.d.ts.map +1 -0
  309. package/dist/tools/index.js +6 -0
  310. package/dist/tools/index.js.map +1 -0
  311. package/dist/tools/scaffold.d.ts +38 -0
  312. package/dist/tools/scaffold.d.ts.map +1 -0
  313. package/dist/tools/scaffold.js +373 -0
  314. package/dist/tools/scaffold.js.map +1 -0
  315. package/dist/trace/index.d.ts +28 -0
  316. package/dist/trace/index.d.ts.map +1 -0
  317. package/dist/trace/index.js +45 -0
  318. package/dist/trace/index.js.map +1 -0
  319. package/dist/types.d.ts +135 -0
  320. package/dist/types.d.ts.map +1 -0
  321. package/dist/types.js +22 -0
  322. package/dist/types.js.map +1 -0
  323. package/dist/watch/cache.d.ts +41 -0
  324. package/dist/watch/cache.d.ts.map +1 -0
  325. package/dist/watch/cache.js +230 -0
  326. package/dist/watch/cache.js.map +1 -0
  327. package/dist/watch/index.d.ts +9 -0
  328. package/dist/watch/index.d.ts.map +1 -0
  329. package/dist/watch/index.js +7 -0
  330. package/dist/watch/index.js.map +1 -0
  331. package/dist/watch/project.d.ts +128 -0
  332. package/dist/watch/project.d.ts.map +1 -0
  333. package/dist/watch/project.js +152 -0
  334. package/dist/watch/project.js.map +1 -0
  335. package/dist/watch/watcher.d.ts +76 -0
  336. package/dist/watch/watcher.d.ts.map +1 -0
  337. package/dist/watch/watcher.js +235 -0
  338. package/dist/watch/watcher.js.map +1 -0
  339. package/package.json +70 -0
package/README.md ADDED
@@ -0,0 +1,1662 @@
1
+ # mnehmos.trace.mcp
2
+
3
+ > Static analysis engine for detecting schema mismatches between data producers and consumers.
4
+
5
+ ## What It Does
6
+
7
+ Trace MCP finds mismatches between:
8
+
9
+ - Backend API responses and frontend expectations
10
+ - MCP tool outputs and client code that uses them
11
+ - Service A's events and Service B's handlers
12
+ - REST endpoints and HTTP client calls
13
+ - GraphQL schemas and Apollo Client hooks
14
+
15
+ ```
16
+ Producer returns: { characterClass: "Fighter", hitPoints: 45 }
17
+ Consumer expects: { class: "Fighter", hp: 45 }
18
+ Result: ❌ Mismatch detected before runtime
19
+ ```
20
+
21
+ ## Features
22
+
23
+ ### Core Capabilities
24
+
25
+ | Feature | Description |
26
+ |---------|-------------|
27
+ | **Schema Extraction** | Extract schemas from MCP tools, OpenAPI, TypeScript, tRPC, REST endpoints, GraphQL |
28
+ | **Usage Tracing** | Track how client code consumes schemas via property access patterns |
29
+ | **Mismatch Detection** | Compare producer schemas against consumer expectations |
30
+ | **Code Generation** | Scaffold consumer code from producer schemas (and vice versa) |
31
+ | **Watch Mode** | Continuous validation on file changes |
32
+
33
+ ### Phase 2 Capabilities
34
+
35
+ | Feature | Description |
36
+ |---------|-------------|
37
+ | **Pattern Matcher** | Extensible pattern detection supporting call, decorator, property, export, and chain patterns |
38
+ | **Import Resolution** | Cross-file type resolution with import graph building and circular dependency handling |
39
+ | **REST Detection** | Express and Fastify endpoint extraction with validation middleware support |
40
+ | **HTTP Client Tracing** | fetch() and axios call detection with URL extraction and type inference |
41
+ | **GraphQL Support** | SDL schema parsing, Apollo Server resolvers, and Apollo Client hook tracing |
42
+
43
+ ### Phase 3 Capabilities
44
+
45
+ | Feature | Description |
46
+ |---------|-------------|
47
+ | **Python AST Parser** | FastAPI, Flask, and MCP tool extraction with Pydantic model support |
48
+ | **Go Language Parser** | Struct/interface extraction with Chi, Gin, and stdlib HTTP handler detection |
49
+ | **gRPC/Protobuf Support** | Proto3 parsing with message, enum, service, and streaming RPC extraction |
50
+ | **Python HTTP Clients** | requests, httpx, and aiohttp library detection with response property tracing |
51
+
52
+ ### Test Coverage
53
+
54
+ **1047 tests passing** across 16 test suites:
55
+
56
+ | Test Suite | Tests |
57
+ |------------|-------|
58
+ | Pattern Matcher | 85 |
59
+ | REST Detection | 87 |
60
+ | HTTP Client Tracing | 90 |
61
+ | GraphQL Support | 109 |
62
+ | Import Resolution | 56 |
63
+ | Core (adapters, OpenAPI, tRPC) | 234 |
64
+ | Python AST | 121 |
65
+ | gRPC/Protobuf | 124 |
66
+ | Go Parser | 106 |
67
+ | Python HTTP Clients | 35 |
68
+
69
+ ## Installation
70
+
71
+ ```bash
72
+ # Clone the repository
73
+ git clone https://github.com/Mnehmos/mnehmos.trace.mcp.git
74
+
75
+ # Navigate to the directory
76
+ cd mnehmos.trace.mcp
77
+
78
+ # Install dependencies
79
+ npm install
80
+
81
+ # Build the project
82
+ npm run build
83
+ ```
84
+
85
+ ## Configuration
86
+
87
+ Add to your MCP client configuration (e.g., `claude_desktop_config.json` or Roo-Code settings):
88
+
89
+ ```json
90
+ {
91
+ "mcpServers": {
92
+ "trace-mcp": {
93
+ "command": "node",
94
+ "args": ["/path/to/trace-mcp/dist/index.js"],
95
+ "env": {}
96
+ }
97
+ }
98
+ }
99
+ ```
100
+
101
+ ## Supported Formats
102
+
103
+ Trace MCP supports schema extraction and comparison across multiple specification formats through a pluggable adapter registry.
104
+
105
+ ### Summary of Supported Frameworks
106
+
107
+ | Category | Frameworks |
108
+ |----------|------------|
109
+ | **API Specs** | OpenAPI 3.0+, Swagger |
110
+ | **RPC** | MCP (Zod), tRPC, gRPC/Protobuf |
111
+ | **REST Servers** | Express, Fastify, FastAPI, Flask, Chi, Gin, Go stdlib |
112
+ | **HTTP Clients** | fetch(), axios, requests, httpx, aiohttp |
113
+ | **GraphQL** | SDL schemas, Apollo Server, Apollo Client |
114
+ | **Type Systems** | TypeScript interfaces, Zod schemas, Pydantic models, Go structs |
115
+
116
+ ### Supported Languages
117
+
118
+ | Language | Producer Detection | Consumer Tracing |
119
+ |----------|-------------------|------------------|
120
+ | **TypeScript** | MCP tools, tRPC, Express, Fastify, GraphQL resolvers | callTool(), fetch, axios, Apollo Client |
121
+ | **Python** | FastAPI, Flask, MCP tools, Pydantic models | requests, httpx, aiohttp |
122
+ | **Go** | Chi, Gin, stdlib handlers, structs, interfaces | — |
123
+ | **Protobuf** | Messages, enums, services, streaming RPCs | — |
124
+
125
+ ---
126
+
127
+ ### MCP Server Schemas (Zod)
128
+
129
+ Extract MCP tool definitions from server source code using Zod schemas.
130
+
131
+ ```typescript
132
+ server.tool(
133
+ "get_character",
134
+ "Fetch character data",
135
+ {
136
+ characterId: z.string().describe("Character ID"),
137
+ },
138
+ async (args) => {
139
+ // implementation
140
+ }
141
+ );
142
+ ```
143
+
144
+ **Schema ID Format**: `endpoint:GET:/tools/get_character@./server.ts`
145
+
146
+ ---
147
+
148
+ ### OpenAPI / Swagger Specifications
149
+
150
+ Extract schemas from OpenAPI 3.0+ specifications, supporting endpoints, request bodies, responses, and component schemas.
151
+
152
+ ```yaml
153
+ openapi: 3.0.0
154
+ info:
155
+ title: Character API
156
+ version: 1.0.0
157
+ paths:
158
+ /characters/{id}:
159
+ get:
160
+ parameters:
161
+ - name: id
162
+ in: path
163
+ schema:
164
+ type: string
165
+ responses:
166
+ '200':
167
+ content:
168
+ application/json:
169
+ schema:
170
+ $ref: '#/components/schemas/Character'
171
+ components:
172
+ schemas:
173
+ Character:
174
+ type: object
175
+ properties:
176
+ id:
177
+ type: string
178
+ name:
179
+ type: string
180
+ class:
181
+ type: string
182
+ required:
183
+ - id
184
+ - name
185
+ - class
186
+ ```
187
+
188
+ **Schema ID Format**: `endpoint:GET:/characters/{id}@./api.yaml`
189
+
190
+ **Usage Example:**
191
+
192
+ ```typescript
193
+ const result = await client.callTool("extract_schemas", {
194
+ rootDir: "./backend",
195
+ include: ["**/*.openapi.yaml", "**/*.swagger.json"],
196
+ });
197
+ ```
198
+
199
+ ---
200
+
201
+ ### TypeScript Interfaces & Types
202
+
203
+ Extract exported interfaces, type aliases, and enums from TypeScript source files. Supports utility types including `Pick`, `Omit`, `Partial`, `Required`, and `Record`.
204
+
205
+ ```typescript
206
+ export interface Character {
207
+ id: string;
208
+ name: string;
209
+ class: "Fighter" | "Wizard" | "Rogue";
210
+ hitPoints: number;
211
+ stats: {
212
+ strength: number;
213
+ dexterity: number;
214
+ constitution: number;
215
+ };
216
+ }
217
+
218
+ export type ReadonlyCharacter = Readonly<Character>;
219
+
220
+ export enum CharacterClass {
221
+ Fighter = "Fighter",
222
+ Wizard = "Wizard",
223
+ Rogue = "Rogue",
224
+ }
225
+ ```
226
+
227
+ **Schema ID Format**: `interface:Character@./types.ts`
228
+
229
+ **Supported Utility Types:**
230
+ - `Pick<T, K>` - Select properties from interface
231
+ - `Omit<T, K>` - Exclude properties from interface
232
+ - `Partial<T>` - Make all properties optional
233
+ - `Required<T>` - Make all properties required
234
+ - `Record<K, T>` - Object with specific keys and value type
235
+
236
+ **Usage Example:**
237
+
238
+ ```typescript
239
+ const result = await client.callTool("extract_schemas", {
240
+ rootDir: "./shared",
241
+ include: ["**/*.ts", "**/*.tsx"],
242
+ });
243
+ // Returns interfaces with ID format: interface:CharacterClass@./types.ts
244
+ ```
245
+
246
+ ---
247
+
248
+ ### tRPC Routers
249
+
250
+ Extract procedure schemas from tRPC routers, including input/output types, query, mutation, and subscription handlers. Handles nested routers and middleware.
251
+
252
+ ```typescript
253
+ import { z } from "zod";
254
+ import { publicProcedure, router } from "./trpc";
255
+
256
+ export const appRouter = router({
257
+ users: router({
258
+ getById: publicProcedure
259
+ .input(z.string())
260
+ .output(z.object({
261
+ id: z.string(),
262
+ name: z.string(),
263
+ email: z.string().email(),
264
+ }))
265
+ .query(async ({ input }) => {
266
+ // implementation
267
+ }),
268
+
269
+ create: publicProcedure
270
+ .input(z.object({
271
+ name: z.string(),
272
+ email: z.string().email(),
273
+ }))
274
+ .output(z.object({
275
+ id: z.string(),
276
+ name: z.string(),
277
+ email: z.string(),
278
+ }))
279
+ .mutation(async ({ input }) => {
280
+ // implementation
281
+ }),
282
+
283
+ onChange: publicProcedure
284
+ .output(z.object({
285
+ userId: z.string(),
286
+ action: z.enum(["created", "updated", "deleted"]),
287
+ }))
288
+ .subscription(async () => {
289
+ // implementation
290
+ }),
291
+ }),
292
+ });
293
+ ```
294
+
295
+ **Schema ID Format**: `trpc:users.getById@./router.ts`
296
+
297
+ **Detected Elements:**
298
+ - Router definitions (`router({ ... })`)
299
+ - Nested routers (`users: router({ ... })`)
300
+ - Procedures (`.query()`, `.mutation()`, `.subscription()`)
301
+ - Input schemas (`.input(zod_schema)`)
302
+ - Output schemas (`.output(zod_schema)`)
303
+
304
+ **Usage Example:**
305
+
306
+ ```typescript
307
+ const result = await client.callTool("extract_schemas", {
308
+ rootDir: "./backend/trpc",
309
+ include: ["**/*.router.ts"],
310
+ });
311
+ // Returns procedures with ID format: trpc:users.getById@./router.ts
312
+ ```
313
+
314
+ ---
315
+
316
+ ### REST Endpoints (Express & Fastify)
317
+
318
+ Extract endpoint schemas from Express and Fastify applications, including route parameters, request bodies, response types, and validation middleware.
319
+
320
+ #### Express
321
+
322
+ ```typescript
323
+ import express from "express";
324
+ import { z } from "zod";
325
+
326
+ const app = express();
327
+
328
+ // Basic route with typed response
329
+ app.get("/users/:id", (req, res) => {
330
+ const user: User = getUserById(req.params.id);
331
+ res.json(user);
332
+ });
333
+
334
+ // Route with Zod validation middleware
335
+ app.post("/users",
336
+ validate(z.object({
337
+ name: z.string(),
338
+ email: z.string().email(),
339
+ })),
340
+ (req, res) => {
341
+ res.status(201).json({ id: "123", ...req.body });
342
+ }
343
+ );
344
+
345
+ // Router-based routes
346
+ const router = express.Router();
347
+ router.get("/health", (req, res) => res.json({ status: "ok" }));
348
+ app.use("/api", router);
349
+ ```
350
+
351
+ **Schema ID Format**: `rest:GET:/users/:id@./app.ts`
352
+
353
+ #### Fastify
354
+
355
+ ```typescript
356
+ import Fastify from "fastify";
357
+
358
+ const fastify = Fastify();
359
+
360
+ // Route with JSON Schema validation
361
+ fastify.post("/users", {
362
+ schema: {
363
+ body: {
364
+ type: "object",
365
+ properties: {
366
+ name: { type: "string" },
367
+ email: { type: "string", format: "email" },
368
+ },
369
+ required: ["name", "email"],
370
+ },
371
+ response: {
372
+ 201: {
373
+ type: "object",
374
+ properties: {
375
+ id: { type: "string" },
376
+ name: { type: "string" },
377
+ },
378
+ },
379
+ },
380
+ },
381
+ }, async (request, reply) => {
382
+ return { id: "123", name: request.body.name };
383
+ });
384
+
385
+ // Shorthand methods
386
+ fastify.get("/health", async () => ({ status: "ok" }));
387
+ ```
388
+
389
+ **Schema ID Format**: `rest:POST:/users@./server.ts`
390
+
391
+ **Detected Elements:**
392
+ - HTTP methods: GET, POST, PUT, PATCH, DELETE
393
+ - Path parameters (`:id`, `:userId`)
394
+ - Request body schemas (Zod, Joi, celebrate, JSON Schema)
395
+ - Response type inference
396
+ - Router prefixes and mounting
397
+
398
+ **Usage Example:**
399
+
400
+ ```typescript
401
+ const result = await client.callTool("extract_schemas", {
402
+ rootDir: "./backend",
403
+ include: ["**/*.ts"],
404
+ });
405
+ // Returns endpoints with ID format: rest:GET:/users/:id@./routes.ts
406
+ ```
407
+
408
+ ---
409
+
410
+ ### HTTP Clients (fetch & axios)
411
+
412
+ Trace HTTP client calls to detect consumer expectations for API responses.
413
+
414
+ #### fetch() API
415
+
416
+ ```typescript
417
+ // Basic fetch with type assertion
418
+ const response = await fetch("/api/users");
419
+ const users: User[] = await response.json();
420
+
421
+ // fetch with request options
422
+ const newUser = await fetch("/api/users", {
423
+ method: "POST",
424
+ headers: { "Content-Type": "application/json" },
425
+ body: JSON.stringify({ name: "Alice" }),
426
+ }).then(res => res.json()) as CreateUserResponse;
427
+
428
+ // Template literal URLs
429
+ const userId = "123";
430
+ const user = await fetch(`/api/users/${userId}`).then(r => r.json());
431
+
432
+ // Property access tracking
433
+ console.log(user.name, user.email, user.profile.avatar);
434
+ ```
435
+
436
+ **Detected Elements:**
437
+ - URL extraction (static strings, template literals, variables)
438
+ - HTTP method detection
439
+ - Type assertions and generics
440
+ - Property access patterns on response data
441
+
442
+ #### axios
443
+
444
+ ```typescript
445
+ import axios from "axios";
446
+
447
+ // Basic GET request
448
+ const { data: users } = await axios.get<User[]>("/api/users");
449
+
450
+ // POST with typed response
451
+ const response = await axios.post<CreateUserResponse>("/api/users", {
452
+ name: "Bob",
453
+ email: "bob@example.com",
454
+ });
455
+
456
+ // Instance with base URL
457
+ const api = axios.create({ baseURL: "https://api.example.com" });
458
+ const profile = await api.get<Profile>("/me");
459
+
460
+ // Destructured property access
461
+ const { name, email } = response.data;
462
+ ```
463
+
464
+ **Schema ID Format**: `http-client:GET:/api/users@./client.ts`
465
+
466
+ **Detected Elements:**
467
+ - axios methods: `.get()`, `.post()`, `.put()`, `.patch()`, `.delete()`
468
+ - Generic type parameters (`axios.get<User>`)
469
+ - Instance creation with `axios.create()`
470
+ - Base URL resolution
471
+ - Response data property access
472
+
473
+ **Usage Example:**
474
+
475
+ ```typescript
476
+ const result = await client.callTool("trace_usage", {
477
+ rootDir: "./frontend/src",
478
+ include: ["**/*.ts", "**/*.tsx"],
479
+ });
480
+ // Returns HTTP client calls with ID format: http-client:GET:/api/users@./api.ts
481
+ ```
482
+
483
+ ---
484
+
485
+ ### GraphQL (SDL & Apollo)
486
+
487
+ Extract schemas from GraphQL SDL files and trace Apollo Server resolvers and Apollo Client hooks.
488
+
489
+ #### SDL Schema Files
490
+
491
+ ```graphql
492
+ # schema.graphql
493
+ type User {
494
+ id: ID!
495
+ name: String!
496
+ email: String!
497
+ posts: [Post!]!
498
+ }
499
+
500
+ type Post {
501
+ id: ID!
502
+ title: String!
503
+ content: String!
504
+ author: User!
505
+ }
506
+
507
+ type Query {
508
+ user(id: ID!): User
509
+ users: [User!]!
510
+ post(id: ID!): Post
511
+ }
512
+
513
+ type Mutation {
514
+ createUser(name: String!, email: String!): User!
515
+ createPost(title: String!, content: String!, authorId: ID!): Post!
516
+ }
517
+ ```
518
+
519
+ **Schema ID Format**: `graphql:Query.user@./schema.graphql`
520
+
521
+ #### Apollo Server Resolvers
522
+
523
+ ```typescript
524
+ import { ApolloServer } from "@apollo/server";
525
+
526
+ const resolvers = {
527
+ Query: {
528
+ user: async (_, { id }) => {
529
+ return db.users.findById(id);
530
+ },
531
+ users: async () => {
532
+ return db.users.findAll();
533
+ },
534
+ },
535
+ Mutation: {
536
+ createUser: async (_, { name, email }) => {
537
+ return db.users.create({ name, email });
538
+ },
539
+ },
540
+ User: {
541
+ posts: async (parent) => {
542
+ return db.posts.findByAuthor(parent.id);
543
+ },
544
+ },
545
+ };
546
+
547
+ const server = new ApolloServer({ typeDefs, resolvers });
548
+ ```
549
+
550
+ **Schema ID Format**: `graphql-resolver:Query.user@./resolvers.ts`
551
+
552
+ #### Apollo Client Hooks
553
+
554
+ ```typescript
555
+ import { useQuery, useMutation, gql } from "@apollo/client";
556
+
557
+ const GET_USER = gql`
558
+ query GetUser($id: ID!) {
559
+ user(id: $id) {
560
+ id
561
+ name
562
+ email
563
+ }
564
+ }
565
+ `;
566
+
567
+ const CREATE_USER = gql`
568
+ mutation CreateUser($name: String!, $email: String!) {
569
+ createUser(name: $name, email: $email) {
570
+ id
571
+ name
572
+ }
573
+ }
574
+ `;
575
+
576
+ function UserProfile({ userId }: { userId: string }) {
577
+ const { data, loading, error } = useQuery(GET_USER, {
578
+ variables: { id: userId },
579
+ });
580
+
581
+ const [createUser] = useMutation(CREATE_USER);
582
+
583
+ if (loading) return <Spinner />;
584
+ if (error) return <Error message={error.message} />;
585
+
586
+ return <div>{data.user.name}</div>;
587
+ }
588
+ ```
589
+
590
+ **Schema ID Format**: `graphql-client:GetUser@./UserProfile.tsx`
591
+
592
+ **Detected Elements:**
593
+ - SDL types: scalar, object, input, enum, interface, union
594
+ - Query and Mutation definitions
595
+ - Field arguments and return types
596
+ - Apollo Client hooks: `useQuery`, `useMutation`, `useLazyQuery`, `useSubscription`
597
+ - Operation names and variables
598
+ - Selected fields in queries
599
+
600
+ **Usage Example:**
601
+
602
+ ```typescript
603
+ // Extract GraphQL schemas
604
+ const schemas = await client.callTool("extract_schemas", {
605
+ rootDir: "./backend",
606
+ include: ["**/*.graphql", "**/resolvers.ts"],
607
+ });
608
+
609
+ // Trace Apollo Client usage
610
+ const usage = await client.callTool("trace_usage", {
611
+ rootDir: "./frontend/src",
612
+ include: ["**/*.tsx"],
613
+ });
614
+
615
+ // Compare for mismatches
616
+ const report = await client.callTool("compare", {
617
+ producerDir: "./backend",
618
+ consumerDir: "./frontend/src",
619
+ format: "markdown",
620
+ });
621
+ ```
622
+
623
+ ---
624
+
625
+ ### Python (FastAPI, Flask, MCP Tools)
626
+
627
+ Extract endpoint schemas from Python web frameworks and MCP tool definitions with full Pydantic model support.
628
+
629
+ #### FastAPI
630
+
631
+ ```python
632
+ from fastapi import FastAPI, APIRouter
633
+ from pydantic import BaseModel
634
+ from typing import Optional, List
635
+
636
+ class Character(BaseModel):
637
+ id: str
638
+ name: str
639
+ character_class: str
640
+ level: int = 1
641
+ skills: List[str] = []
642
+
643
+ class CreateCharacterRequest(BaseModel):
644
+ name: str
645
+ character_class: str
646
+ background: Optional[str] = None
647
+
648
+ app = FastAPI()
649
+ router = APIRouter(prefix="/api/v1")
650
+
651
+ @app.get("/characters/{character_id}")
652
+ async def get_character(character_id: str) -> Character:
653
+ return Character(id=character_id, name="Hero", character_class="Fighter")
654
+
655
+ @router.post("/characters")
656
+ async def create_character(request: CreateCharacterRequest) -> Character:
657
+ return Character(id="123", name=request.name, character_class=request.character_class)
658
+
659
+ app.include_router(router)
660
+ ```
661
+
662
+ **Schema ID Format**: `python:GET:/characters/{character_id}@./main.py`
663
+
664
+ #### Flask
665
+
666
+ ```python
667
+ from flask import Flask, Blueprint, request, jsonify
668
+
669
+ app = Flask(__name__)
670
+ api = Blueprint("api", __name__, url_prefix="/api")
671
+
672
+ @app.route("/health")
673
+ def health_check():
674
+ return jsonify({"status": "ok"})
675
+
676
+ @api.route("/users/<user_id>", methods=["GET"])
677
+ def get_user(user_id):
678
+ return jsonify({"id": user_id, "name": "Alice"})
679
+
680
+ @api.route("/users", methods=["POST"])
681
+ def create_user():
682
+ data = request.get_json()
683
+ return jsonify({"id": "123", **data}), 201
684
+
685
+ app.register_blueprint(api)
686
+ ```
687
+
688
+ **Schema ID Format**: `python:GET:/api/users/<user_id>@./app.py`
689
+
690
+ #### MCP Tools (Python)
691
+
692
+ ```python
693
+ from mcp import Server
694
+
695
+ server = Server("character-tools")
696
+
697
+ @server.tool()
698
+ async def get_character(character_id: str) -> dict:
699
+ """Fetch character data by ID."""
700
+ return {"id": character_id, "name": "Hero", "class": "Fighter"}
701
+
702
+ @mcp.tool()
703
+ def roll_dice(dice: str, modifier: int = 0) -> dict:
704
+ """Roll dice with optional modifier."""
705
+ return {"result": 15, "expression": dice, "modifier": modifier}
706
+ ```
707
+
708
+ **Schema ID Format**: `python-mcp:get_character@./tools.py`
709
+
710
+ #### Pydantic Models
711
+
712
+ ```python
713
+ from pydantic import BaseModel, Field
714
+ from typing import Optional, List, Dict, Union, Literal
715
+ from enum import Enum
716
+
717
+ class CharacterClass(str, Enum):
718
+ FIGHTER = "Fighter"
719
+ WIZARD = "Wizard"
720
+ ROGUE = "Rogue"
721
+
722
+ class Stats(BaseModel):
723
+ strength: int = Field(ge=1, le=20)
724
+ dexterity: int = Field(ge=1, le=20)
725
+ constitution: int = Field(ge=1, le=20)
726
+
727
+ class Character(BaseModel):
728
+ id: str
729
+ name: str
730
+ character_class: CharacterClass
731
+ level: int = Field(default=1, ge=1, le=20)
732
+ stats: Stats
733
+ equipment: List[str] = []
734
+ metadata: Optional[Dict[str, str]] = None
735
+ ```
736
+
737
+ **Detected Elements:**
738
+ - Decorators: `@app.get()`, `@app.post()`, `@router.*`, `@app.route()`, `@blueprint.route()`
739
+ - MCP decorators: `@mcp.tool()`, `@server.tool()`
740
+ - Pydantic `BaseModel` classes with field extraction
741
+ - Type annotations: `Optional`, `Union`, `List`, `Dict`, `Literal`
742
+ - Enum types
743
+
744
+ **Usage Example:**
745
+
746
+ ```typescript
747
+ const result = await client.callTool("extract_schemas", {
748
+ rootDir: "./backend",
749
+ include: ["**/*.py"],
750
+ });
751
+ // Returns endpoints with ID format: python:GET:/characters/{id}@./main.py
752
+ ```
753
+
754
+ ---
755
+
756
+ ### Go Language (Chi, Gin, stdlib)
757
+
758
+ Extract struct definitions, interfaces, and HTTP endpoint schemas from Go source files.
759
+
760
+ #### Structs with JSON Tags
761
+
762
+ ```go
763
+ package models
764
+
765
+ type Character struct {
766
+ ID string `json:"id"`
767
+ Name string `json:"name"`
768
+ Class string `json:"class"`
769
+ Level int `json:"level"`
770
+ HitPoints int `json:"hp"`
771
+ Skills []string `json:"skills,omitempty"`
772
+ }
773
+
774
+ type Stats struct {
775
+ Strength int `json:"str"`
776
+ Dexterity int `json:"dex"`
777
+ Constitution int `json:"con"`
778
+ }
779
+
780
+ // Embedded struct
781
+ type CharacterWithStats struct {
782
+ Character
783
+ Stats Stats `json:"stats"`
784
+ }
785
+ ```
786
+
787
+ **Schema ID Format**: `go-struct:Character@./models/character.go`
788
+
789
+ #### Interfaces
790
+
791
+ ```go
792
+ package services
793
+
794
+ type CharacterService interface {
795
+ GetByID(id string) (*Character, error)
796
+ Create(req CreateRequest) (*Character, error)
797
+ Update(id string, req UpdateRequest) (*Character, error)
798
+ Delete(id string) error
799
+ }
800
+
801
+ type Repository interface {
802
+ Find(query Query) ([]Character, error)
803
+ Save(character *Character) error
804
+ }
805
+ ```
806
+
807
+ **Schema ID Format**: `go-interface:CharacterService@./services/character.go`
808
+
809
+ #### stdlib HTTP Handlers
810
+
811
+ ```go
812
+ package main
813
+
814
+ import (
815
+ "encoding/json"
816
+ "net/http"
817
+ )
818
+
819
+ func main() {
820
+ http.HandleFunc("/health", healthHandler)
821
+ http.HandleFunc("/api/characters", charactersHandler)
822
+ http.HandleFunc("/api/characters/", characterByIDHandler)
823
+ http.ListenAndServe(":8080", nil)
824
+ }
825
+
826
+ func healthHandler(w http.ResponseWriter, r *http.Request) {
827
+ json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
828
+ }
829
+
830
+ func charactersHandler(w http.ResponseWriter, r *http.Request) {
831
+ switch r.Method {
832
+ case http.MethodGet:
833
+ // List characters
834
+ case http.MethodPost:
835
+ // Create character
836
+ }
837
+ }
838
+ ```
839
+
840
+ **Schema ID Format**: `go-http:GET:/health@./main.go`
841
+
842
+ #### Chi Router
843
+
844
+ ```go
845
+ package main
846
+
847
+ import (
848
+ "github.com/go-chi/chi/v5"
849
+ "net/http"
850
+ )
851
+
852
+ func main() {
853
+ r := chi.NewRouter()
854
+
855
+ r.Get("/health", healthHandler)
856
+
857
+ r.Route("/api/characters", func(r chi.Router) {
858
+ r.Get("/", listCharacters)
859
+ r.Post("/", createCharacter)
860
+ r.Get("/{id}", getCharacter) // Chi param: {id}
861
+ r.Put("/{id}", updateCharacter)
862
+ r.Delete("/{id}", deleteCharacter)
863
+ })
864
+
865
+ http.ListenAndServe(":8080", r)
866
+ }
867
+ ```
868
+
869
+ **Schema ID Format**: `go-http:GET:/api/characters/{id}@./main.go`
870
+
871
+ #### Gin Framework
872
+
873
+ ```go
874
+ package main
875
+
876
+ import "github.com/gin-gonic/gin"
877
+
878
+ func main() {
879
+ r := gin.Default()
880
+
881
+ r.GET("/health", healthHandler)
882
+
883
+ api := r.Group("/api")
884
+ {
885
+ api.GET("/characters", listCharacters)
886
+ api.POST("/characters", createCharacter)
887
+ api.GET("/characters/:id", getCharacter) // Gin param: :id
888
+ api.PUT("/characters/:id", updateCharacter)
889
+ api.DELETE("/characters/:id", deleteCharacter)
890
+ }
891
+
892
+ r.Run(":8080")
893
+ }
894
+ ```
895
+
896
+ **Schema ID Format**: `go-http:GET:/api/characters/:id@./main.go`
897
+
898
+ **Detected Elements:**
899
+ - Struct definitions with JSON tags
900
+ - Embedded structs
901
+ - Interface definitions
902
+ - `http.HandleFunc()` patterns
903
+ - Chi router: `r.Get()`, `r.Post()`, `r.Route()`, `{param}` syntax
904
+ - Gin framework: `r.GET()`, `r.POST()`, `r.Group()`, `:param` syntax
905
+
906
+ **Usage Example:**
907
+
908
+ ```typescript
909
+ const result = await client.callTool("extract_schemas", {
910
+ rootDir: "./backend",
911
+ include: ["**/*.go"],
912
+ });
913
+ // Returns structs, interfaces, and endpoints
914
+ ```
915
+
916
+ ---
917
+
918
+ ### gRPC / Protobuf
919
+
920
+ Parse Protocol Buffer definitions (proto3) to extract message types, enums, services, and RPC methods.
921
+
922
+ #### Basic Messages
923
+
924
+ ```protobuf
925
+ syntax = "proto3";
926
+
927
+ package character;
928
+
929
+ message Character {
930
+ string id = 1;
931
+ string name = 2;
932
+ CharacterClass character_class = 3;
933
+ int32 level = 4;
934
+ Stats stats = 5;
935
+ repeated string skills = 6;
936
+ }
937
+
938
+ message Stats {
939
+ int32 strength = 1;
940
+ int32 dexterity = 2;
941
+ int32 constitution = 3;
942
+ }
943
+ ```
944
+
945
+ **Schema ID Format**: `proto-message:character.Character@./character.proto`
946
+
947
+ #### Enums
948
+
949
+ ```protobuf
950
+ enum CharacterClass {
951
+ CHARACTER_CLASS_UNSPECIFIED = 0;
952
+ CHARACTER_CLASS_FIGHTER = 1;
953
+ CHARACTER_CLASS_WIZARD = 2;
954
+ CHARACTER_CLASS_ROGUE = 3;
955
+ }
956
+
957
+ enum DamageType {
958
+ DAMAGE_TYPE_UNSPECIFIED = 0;
959
+ DAMAGE_TYPE_SLASHING = 1;
960
+ DAMAGE_TYPE_PIERCING = 2;
961
+ DAMAGE_TYPE_FIRE = 3;
962
+ }
963
+ ```
964
+
965
+ **Schema ID Format**: `proto-enum:character.CharacterClass@./character.proto`
966
+
967
+ #### Oneof and Map Fields
968
+
969
+ ```protobuf
970
+ message Equipment {
971
+ string id = 1;
972
+ string name = 2;
973
+
974
+ oneof item_type {
975
+ Weapon weapon = 10;
976
+ Armor armor = 11;
977
+ Consumable consumable = 12;
978
+ }
979
+ }
980
+
981
+ message Inventory {
982
+ string character_id = 1;
983
+ map<string, int32> item_counts = 2;
984
+ map<string, Equipment> equipped = 3;
985
+ }
986
+ ```
987
+
988
+ **Schema ID Format**: `proto-message:character.Equipment@./equipment.proto`
989
+
990
+ #### Services and RPCs
991
+
992
+ ```protobuf
993
+ service CharacterService {
994
+ // Unary RPC
995
+ rpc GetCharacter(GetCharacterRequest) returns (Character);
996
+
997
+ // Server streaming
998
+ rpc ListCharacters(ListRequest) returns (stream Character);
999
+
1000
+ // Client streaming
1001
+ rpc UploadInventory(stream Item) returns (UploadResponse);
1002
+
1003
+ // Bidirectional streaming
1004
+ rpc Chat(stream ChatMessage) returns (stream ChatMessage);
1005
+ }
1006
+
1007
+ message GetCharacterRequest {
1008
+ string id = 1;
1009
+ }
1010
+
1011
+ message ListRequest {
1012
+ int32 page_size = 1;
1013
+ string page_token = 2;
1014
+ }
1015
+ ```
1016
+
1017
+ **Schema ID Format**: `proto-service:character.CharacterService@./character.proto`
1018
+ **RPC Format**: `proto-rpc:CharacterService.GetCharacter@./character.proto`
1019
+
1020
+ #### Well-Known Types
1021
+
1022
+ ```protobuf
1023
+ import "google/protobuf/timestamp.proto";
1024
+ import "google/protobuf/duration.proto";
1025
+ import "google/protobuf/any.proto";
1026
+ import "google/protobuf/struct.proto";
1027
+
1028
+ message CharacterEvent {
1029
+ string character_id = 1;
1030
+ string event_type = 2;
1031
+ google.protobuf.Timestamp created_at = 3;
1032
+ google.protobuf.Duration duration = 4;
1033
+ google.protobuf.Any payload = 5;
1034
+ google.protobuf.Struct metadata = 6;
1035
+ }
1036
+ ```
1037
+
1038
+ **Detected Elements:**
1039
+ - Messages with all field types (scalar, message, enum, repeated)
1040
+ - Enums with numeric values
1041
+ - `oneof` field groups
1042
+ - `map<K, V>` fields
1043
+ - Nested message definitions
1044
+ - Service definitions with all streaming modes:
1045
+ - Unary: `rpc Method(Request) returns (Response)`
1046
+ - Server streaming: `rpc Method(Request) returns (stream Response)`
1047
+ - Client streaming: `rpc Method(stream Request) returns (Response)`
1048
+ - Bidirectional: `rpc Method(stream Request) returns (stream Response)`
1049
+ - Well-known types: `Timestamp`, `Duration`, `Any`, `Struct`
1050
+
1051
+ **Usage Example:**
1052
+
1053
+ ```typescript
1054
+ const result = await client.callTool("extract_schemas", {
1055
+ rootDir: "./proto",
1056
+ include: ["**/*.proto"],
1057
+ });
1058
+ // Returns messages, enums, and services
1059
+ ```
1060
+
1061
+ ---
1062
+
1063
+ ### Python HTTP Clients (requests, httpx, aiohttp)
1064
+
1065
+ Trace HTTP client calls in Python code to detect consumer expectations.
1066
+
1067
+ #### requests Library
1068
+
1069
+ ```python
1070
+ import requests
1071
+
1072
+ # Basic GET
1073
+ response = requests.get("https://api.example.com/characters")
1074
+ characters = response.json()
1075
+
1076
+ # GET with path parameter
1077
+ character = requests.get(f"https://api.example.com/characters/{char_id}").json()
1078
+
1079
+ # POST with JSON body
1080
+ new_char = requests.post(
1081
+ "https://api.example.com/characters",
1082
+ json={"name": "Hero", "class": "Fighter"}
1083
+ ).json()
1084
+
1085
+ # Session with base URL
1086
+ session = requests.Session()
1087
+ session.headers.update({"Authorization": "Bearer token"})
1088
+ user = session.get("https://api.example.com/me").json()
1089
+
1090
+ # Property access tracking
1091
+ print(character["name"], character["stats"]["strength"])
1092
+ ```
1093
+
1094
+ **Schema ID Format**: `python-http:GET:/characters@./client.py`
1095
+
1096
+ #### httpx Library
1097
+
1098
+ ```python
1099
+ import httpx
1100
+
1101
+ # Sync client
1102
+ response = httpx.get("https://api.example.com/characters")
1103
+ data = response.json()
1104
+
1105
+ # Async client
1106
+ async with httpx.AsyncClient(base_url="https://api.example.com") as client:
1107
+ response = await client.get("/characters")
1108
+ characters = response.json()
1109
+
1110
+ response = await client.post("/characters", json={"name": "Hero"})
1111
+ new_char = response.json()
1112
+ ```
1113
+
1114
+ **Schema ID Format**: `python-http:GET:/characters@./client.py`
1115
+
1116
+ #### aiohttp Library
1117
+
1118
+ ```python
1119
+ import aiohttp
1120
+
1121
+ async with aiohttp.ClientSession() as session:
1122
+ # GET request
1123
+ async with session.get("https://api.example.com/characters") as response:
1124
+ characters = await response.json()
1125
+
1126
+ # POST request
1127
+ async with session.post(
1128
+ "https://api.example.com/characters",
1129
+ json={"name": "Hero", "class": "Fighter"}
1130
+ ) as response:
1131
+ new_char = await response.json()
1132
+
1133
+ # Property access
1134
+ print(new_char["id"], new_char["name"])
1135
+ ```
1136
+
1137
+ **Schema ID Format**: `python-http:POST:/characters@./client.py`
1138
+
1139
+ **Detected Elements:**
1140
+ - `requests.get()`, `requests.post()`, etc.
1141
+ - `httpx.get()`, `httpx.post()`, `AsyncClient` methods
1142
+ - `aiohttp.ClientSession` methods
1143
+ - URL extraction (static strings, f-strings)
1144
+ - HTTP method detection
1145
+ - Response property access (dictionary key access)
1146
+
1147
+ **Usage Example:**
1148
+
1149
+ ```typescript
1150
+ const result = await client.callTool("trace_usage", {
1151
+ rootDir: "./python-client",
1152
+ include: ["**/*.py"],
1153
+ });
1154
+ // Returns HTTP client calls with property access patterns
1155
+ ```
1156
+
1157
+ ---
1158
+
1159
+ ## Architecture
1160
+
1161
+ ### Pattern Matcher Framework
1162
+
1163
+ The pattern matcher provides an extensible system for detecting code patterns across different frameworks. Located in [`src/patterns/`](src/patterns/):
1164
+
1165
+ ```
1166
+ src/patterns/
1167
+ ├── base.ts # BasePattern abstract class
1168
+ ├── types.ts # PatternMatch, PatternContext interfaces
1169
+ ├── registry.ts # PatternRegistry for plugin management
1170
+ ├── extractors.ts # Node extractors for AST traversal
1171
+ ├── errors.ts # Pattern-specific error types
1172
+ ├── rest/ # Express, Fastify patterns
1173
+ ├── http-clients/ # fetch, axios patterns
1174
+ └── graphql/ # Apollo patterns
1175
+ ```
1176
+
1177
+ **Supported Pattern Types:**
1178
+ - **Call patterns**: Function/method calls (`app.get()`, `fetch()`)
1179
+ - **Decorator patterns**: TypeScript/Python decorators (`@Controller()`)
1180
+ - **Property patterns**: Object property assignments
1181
+ - **Export patterns**: Module exports (`export const router = ...`)
1182
+ - **Chain patterns**: Method chaining (`router.get().post()`)
1183
+
1184
+ ### Import Resolution
1185
+
1186
+ Cross-file type resolution with import graph building. Located in [`src/languages/import-resolver.ts`](src/languages/import-resolver.ts):
1187
+
1188
+ - Resolves `import { Type } from "./types"`
1189
+ - Handles barrel exports (`export * from`)
1190
+ - Supports path aliases via tsconfig.json
1191
+ - Detects and handles circular dependencies
1192
+ - Caches resolved types for performance
1193
+
1194
+ ---
1195
+
1196
+ ## Tools Reference
1197
+
1198
+ Trace MCP provides 11 tools organized into three categories:
1199
+
1200
+ ### Core Analysis Tools
1201
+
1202
+ | Tool | Description |
1203
+ | ----------------- | ---------------------------------------------------- |
1204
+ | `extract_schemas` | Extract MCP tool definitions from server source code |
1205
+ | `extract_file` | Extract schemas from a single file |
1206
+ | `trace_usage` | Trace how client code uses MCP tools |
1207
+ | `trace_file` | Trace tool usage in a single file |
1208
+ | `compare` | Full pipeline: extract → trace → compare → report |
1209
+
1210
+ ### Code Generation Tools
1211
+
1212
+ | Tool | Description |
1213
+ | ------------------- | ----------------------------------------------- |
1214
+ | `scaffold_consumer` | Generate client code from producer schema |
1215
+ | `scaffold_producer` | Generate server stub from client usage |
1216
+ | `comment_contract` | Add cross-reference comments to validated pairs |
1217
+
1218
+ ### Project Management Tools
1219
+
1220
+ | Tool | Description |
1221
+ | -------------------- | ------------------------------------------------------- |
1222
+ | `init_project` | Initialize a trace project with `.trace-mcp` config |
1223
+ | `watch` | Watch files for changes and auto-revalidate |
1224
+ | `get_project_status` | Get project config, cache state, and validation results |
1225
+
1226
+ ---
1227
+
1228
+ ## Tool Details
1229
+
1230
+ ### `extract_schemas`
1231
+
1232
+ Extract MCP tool definitions (ProducerSchemas) from server source code. Scans for `server.tool()` calls and parses their Zod schemas. Also supports OpenAPI, TypeScript interfaces, tRPC routers, REST endpoints, and GraphQL schemas.
1233
+
1234
+ **Parameters:**
1235
+
1236
+ - `rootDir` (required): Root directory of server source code
1237
+ - `include`: Glob patterns to include (default: `**/*.ts`)
1238
+ - `exclude`: Glob patterns to exclude (default: `node_modules`, `dist`)
1239
+
1240
+ **Example:**
1241
+
1242
+ ```typescript
1243
+ const result = await client.callTool("extract_schemas", {
1244
+ rootDir: "./backend/src",
1245
+ });
1246
+ // Returns: { success: true, count: 12, schemas: [...] }
1247
+ ```
1248
+
1249
+ ---
1250
+
1251
+ ### `extract_file`
1252
+
1253
+ Extract MCP tool definitions from a single TypeScript file.
1254
+
1255
+ **Parameters:**
1256
+
1257
+ - `filePath` (required): Path to a TypeScript file
1258
+
1259
+ ---
1260
+
1261
+ ### `trace_usage`
1262
+
1263
+ Trace how client code uses MCP tools. Finds `callTool()` invocations, HTTP client calls, and GraphQL hooks, tracking which properties are accessed on results.
1264
+
1265
+ **Parameters:**
1266
+
1267
+ - `rootDir` (required): Root directory of consumer source code
1268
+ - `include`: Glob patterns to include
1269
+ - `exclude`: Glob patterns to exclude
1270
+
1271
+ ---
1272
+
1273
+ ### `trace_file`
1274
+
1275
+ Trace MCP tool usage in a single TypeScript file.
1276
+
1277
+ **Parameters:**
1278
+
1279
+ - `filePath` (required): Path to a TypeScript file
1280
+
1281
+ ---
1282
+
1283
+ ### `compare`
1284
+
1285
+ Full analysis pipeline: extract producer schemas, trace consumer usage, and compare them to find mismatches.
1286
+
1287
+ **Parameters:**
1288
+
1289
+ - `producerDir` (required): Path to MCP server source directory
1290
+ - `consumerDir` (required): Path to consumer/client source directory
1291
+ - `format`: Output format (`json`, `markdown`, `summary`)
1292
+ - `strict`: Strict mode - treat missing optional properties as warnings
1293
+ - `direction`: Data flow direction (`producer_to_consumer`, `consumer_to_producer`, `bidirectional`)
1294
+
1295
+ **Example Output (Markdown):**
1296
+
1297
+ ```markdown
1298
+ # mnehmos.trace.mcp Analysis Report
1299
+
1300
+ **Generated**: 2025-12-11T02:11:48.624Z
1301
+
1302
+ ## Summary
1303
+
1304
+ | Metric | Count |
1305
+ | ----------- | ----- |
1306
+ | Total Tools | 12 |
1307
+ | Total Calls | 34 |
1308
+ | Matches | 31 |
1309
+ | Mismatches | 3 |
1310
+
1311
+ ## Mismatches
1312
+
1313
+ ### get_character
1314
+
1315
+ - **Type**: MISSING_PROPERTY
1316
+ - **Description**: Consumer expects "characterClass" but producer has "class"
1317
+ - **Consumer**: ./components/CharacterSheet.tsx:45
1318
+ - **Producer**: ./tools/character.ts:23
1319
+ ```
1320
+
1321
+ ---
1322
+
1323
+ ### `scaffold_consumer`
1324
+
1325
+ Generate consumer code from a producer schema. Creates TypeScript functions, React hooks, or Zustand actions that correctly call MCP tools.
1326
+
1327
+ **Parameters:**
1328
+
1329
+ - `producerDir` (required): Path to MCP server source directory
1330
+ - `toolName` (required): Name of the tool to scaffold
1331
+ - `target`: Output format (`typescript`, `javascript`, `react-hook`, `zustand-action`)
1332
+ - `includeErrorHandling`: Include try/catch error handling (default: true)
1333
+ - `includeTypes`: Include TypeScript type definitions (default: true)
1334
+
1335
+ **Example Output:**
1336
+
1337
+ ```typescript
1338
+ /**
1339
+ * Get character data
1340
+ * @trace-contract CONSUMER
1341
+ * Producer: ./server/character-tools.ts:23
1342
+ */
1343
+ export async function getCharacter(
1344
+ client: McpClient,
1345
+ args: GetCharacterArgs
1346
+ ): Promise<GetCharacterResult> {
1347
+ try {
1348
+ const result = await client.callTool("get_character", args);
1349
+ return JSON.parse(result.content[0].text);
1350
+ } catch (error) {
1351
+ console.error("Error calling get_character:", error);
1352
+ throw error;
1353
+ }
1354
+ }
1355
+ ```
1356
+
1357
+ ---
1358
+
1359
+ ### `scaffold_producer`
1360
+
1361
+ Generate producer schema stub from consumer usage. Creates MCP tool definition based on how client code calls it.
1362
+
1363
+ **Parameters:**
1364
+
1365
+ - `consumerDir` (required): Path to consumer source directory
1366
+ - `toolName` (required): Name of the tool to scaffold
1367
+ - `includeHandler`: Include handler stub (default: true)
1368
+
1369
+ **Example Output:**
1370
+
1371
+ ```typescript
1372
+ import { z } from "zod";
1373
+
1374
+ // Tool: get_character
1375
+ // Scaffolded from consumer at ./components/CharacterSheet.tsx:14
1376
+ // @trace-contract PRODUCER (scaffolded)
1377
+
1378
+ server.tool(
1379
+ "get_character",
1380
+ "TODO: Add description",
1381
+ {
1382
+ characterId: z.string(),
1383
+ },
1384
+ async (args) => {
1385
+ // TODO: Implement handler
1386
+ // Consumer expects: name, race, level, stats, characterClass
1387
+ return {
1388
+ content: [
1389
+ {
1390
+ type: "text",
1391
+ text: JSON.stringify({
1392
+ name: null, // TODO
1393
+ race: null, // TODO
1394
+ level: null, // TODO
1395
+ }),
1396
+ },
1397
+ ],
1398
+ };
1399
+ }
1400
+ );
1401
+ ```
1402
+
1403
+ ---
1404
+
1405
+ ### `comment_contract`
1406
+
1407
+ Add cross-reference comments to validated producer/consumer pairs. Documents the contract relationship in both files.
1408
+
1409
+ **Parameters:**
1410
+
1411
+ - `producerDir` (required): Path to MCP server source directory
1412
+ - `consumerDir` (required): Path to consumer source directory
1413
+ - `toolName` (required): Name of the validated tool
1414
+ - `dryRun`: Preview without writing (default: true)
1415
+ - `style`: Comment style (`jsdoc`, `inline`, `block`)
1416
+
1417
+ **Example Preview:**
1418
+
1419
+ ```javascript
1420
+ // Producer comment:
1421
+ /*
1422
+ * @trace-contract PRODUCER
1423
+ * Tool: get_character
1424
+ * Consumer: ./components/CharacterSheet.tsx:14
1425
+ * Args: characterId
1426
+ * Validated: 2025-12-11
1427
+ */
1428
+
1429
+ // Consumer comment:
1430
+ /*
1431
+ * @trace-contract CONSUMER
1432
+ * Tool: get_character
1433
+ * Producer: ./server/character-tools.ts:23
1434
+ * Required Args: characterId
1435
+ * Validated: 2025-12-11
1436
+ */
1437
+ ```
1438
+
1439
+ ---
1440
+
1441
+ ### `init_project`
1442
+
1443
+ Initialize a trace project with `.trace-mcp` config directory for watch mode and caching.
1444
+
1445
+ **Parameters:**
1446
+
1447
+ - `projectDir` (required): Root directory for the trace project
1448
+ - `producerPath` (required): Relative path to producer/server code
1449
+ - `consumerPath` (required): Relative path to consumer/client code
1450
+ - `producerLanguage`: Language (`typescript`, `python`, `go`, `rust`, `json_schema`)
1451
+ - `consumerLanguage`: Language (`typescript`, `python`, `go`, `rust`, `json_schema`)
1452
+
1453
+ **Example:**
1454
+
1455
+ ```typescript
1456
+ const result = await client.callTool("init_project", {
1457
+ projectDir: "./my-app",
1458
+ producerPath: "./backend/src",
1459
+ consumerPath: "./frontend/src",
1460
+ });
1461
+ // Creates: ./my-app/.trace-mcp/config.json
1462
+ ```
1463
+
1464
+ ---
1465
+
1466
+ ### `watch`
1467
+
1468
+ Watch project files for changes and auto-revalidate contracts.
1469
+
1470
+ **Parameters:**
1471
+
1472
+ - `projectDir` (required): Root directory with `.trace-mcp` config
1473
+ - `action`: `start`, `stop`, `status`, or `poll`
1474
+
1475
+ **Actions:**
1476
+
1477
+ - `start`: Begin watching for file changes
1478
+ - `stop`: Stop watching
1479
+ - `status`: Check current watcher state
1480
+ - `poll`: Get pending events and last validation result
1481
+
1482
+ ---
1483
+
1484
+ ### `get_project_status`
1485
+
1486
+ Get the status of a trace project including config, cache state, and last validation result.
1487
+
1488
+ **Parameters:**
1489
+
1490
+ - `projectDir` (required): Root directory with `.trace-mcp` config
1491
+
1492
+ **Example Output:**
1493
+
1494
+ ```json
1495
+ {
1496
+ "success": true,
1497
+ "exists": true,
1498
+ "projectDir": "/path/to/project",
1499
+ "config": {
1500
+ "producer": { "path": "./server", "language": "typescript" },
1501
+ "consumer": { "path": "./client", "language": "typescript" }
1502
+ },
1503
+ "isWatching": true,
1504
+ "watcherStatus": { "running": true, "pendingChanges": 0 }
1505
+ }
1506
+ ```
1507
+
1508
+ ---
1509
+
1510
+ ## Typical Workflow
1511
+
1512
+ ### 1. Quick One-Off Analysis
1513
+
1514
+ ```typescript
1515
+ // Compare backend vs frontend, get markdown report
1516
+ const result = await client.callTool("compare", {
1517
+ producerDir: "./backend/src",
1518
+ consumerDir: "./frontend/src",
1519
+ format: "markdown",
1520
+ });
1521
+ ```
1522
+
1523
+ ### 2. Continuous Validation (Watch Mode)
1524
+
1525
+ ```typescript
1526
+ // Initialize project
1527
+ await client.callTool("init_project", {
1528
+ projectDir: ".",
1529
+ producerPath: "./server",
1530
+ consumerPath: "./client",
1531
+ });
1532
+
1533
+ // Start watching
1534
+ await client.callTool("watch", {
1535
+ projectDir: ".",
1536
+ action: "start",
1537
+ });
1538
+
1539
+ // Later: poll for results
1540
+ const status = await client.callTool("watch", {
1541
+ projectDir: ".",
1542
+ action: "poll",
1543
+ });
1544
+ ```
1545
+
1546
+ ### 3. Generate Missing Code
1547
+
1548
+ ```typescript
1549
+ // Generate client code from server schema
1550
+ const consumer = await client.callTool("scaffold_consumer", {
1551
+ producerDir: "./server",
1552
+ toolName: "get_character",
1553
+ target: "react-hook",
1554
+ });
1555
+
1556
+ // Or generate server stub from client usage
1557
+ const producer = await client.callTool("scaffold_producer", {
1558
+ consumerDir: "./client",
1559
+ toolName: "save_settings",
1560
+ });
1561
+ ```
1562
+
1563
+ ### 4. Extract Multiple Formats
1564
+
1565
+ ```typescript
1566
+ // Extract from MCP server
1567
+ const mcpSchemas = await client.callTool("extract_schemas", {
1568
+ rootDir: "./backend/mcp",
1569
+ include: ["**/*.ts"],
1570
+ });
1571
+
1572
+ // Extract from OpenAPI specification
1573
+ const openApiSchemas = await client.callTool("extract_schemas", {
1574
+ rootDir: "./backend",
1575
+ include: ["**/*.openapi.yaml"],
1576
+ });
1577
+
1578
+ // Extract from tRPC router
1579
+ const trpcSchemas = await client.callTool("extract_schemas", {
1580
+ rootDir: "./backend/trpc",
1581
+ include: ["**/*.router.ts"],
1582
+ });
1583
+
1584
+ // Extract TypeScript interfaces
1585
+ const interfaceSchemas = await client.callTool("extract_schemas", {
1586
+ rootDir: "./shared",
1587
+ include: ["**/*.types.ts"],
1588
+ });
1589
+
1590
+ // Extract REST endpoints (Express/Fastify)
1591
+ const restSchemas = await client.callTool("extract_schemas", {
1592
+ rootDir: "./backend/routes",
1593
+ include: ["**/*.ts"],
1594
+ });
1595
+
1596
+ // Extract GraphQL schemas
1597
+ const graphqlSchemas = await client.callTool("extract_schemas", {
1598
+ rootDir: "./backend/graphql",
1599
+ include: ["**/*.graphql", "**/resolvers.ts"],
1600
+ });
1601
+ ```
1602
+
1603
+ ### 5. Full-Stack GraphQL Validation
1604
+
1605
+ ```typescript
1606
+ // Extract GraphQL schema and resolvers
1607
+ const producer = await client.callTool("extract_schemas", {
1608
+ rootDir: "./backend",
1609
+ include: ["**/*.graphql", "**/resolvers/**/*.ts"],
1610
+ });
1611
+
1612
+ // Trace Apollo Client hooks
1613
+ const consumer = await client.callTool("trace_usage", {
1614
+ rootDir: "./frontend/src",
1615
+ include: ["**/*.tsx"],
1616
+ });
1617
+
1618
+ // Compare for schema drift
1619
+ const report = await client.callTool("compare", {
1620
+ producerDir: "./backend",
1621
+ consumerDir: "./frontend/src",
1622
+ format: "markdown",
1623
+ });
1624
+ ```
1625
+
1626
+ ---
1627
+
1628
+ ## Roadmap
1629
+
1630
+ ### Completed
1631
+
1632
+ - [x] MCP tool schema extraction
1633
+ - [x] Consumer usage tracing
1634
+ - [x] Basic mismatch detection
1635
+ - [x] Code scaffolding (consumer & producer)
1636
+ - [x] Contract comments
1637
+ - [x] Watch mode with auto-revalidation
1638
+ - [x] OpenAPI/Swagger adapter support
1639
+ - [x] TypeScript interface extraction
1640
+ - [x] tRPC router support
1641
+ - [x] Pluggable adapter registry
1642
+ - [x] Pattern Matcher abstraction (Phase 2)
1643
+ - [x] Cross-file import resolution (Phase 2)
1644
+ - [x] REST endpoint detection - Express & Fastify (Phase 2)
1645
+ - [x] HTTP client tracing - fetch & axios (Phase 2)
1646
+ - [x] GraphQL support - SDL, Apollo Server, Apollo Client (Phase 2)
1647
+ - [x] Python language support - FastAPI, Flask, MCP tools, Pydantic (Phase 3)
1648
+ - [x] Go language support - Chi, Gin, stdlib handlers, structs (Phase 3)
1649
+ - [x] gRPC/Protobuf support - proto3, messages, services, streaming (Phase 3)
1650
+ - [x] Python HTTP client tracing - requests, httpx, aiohttp (Phase 3)
1651
+
1652
+ ### Planned
1653
+
1654
+ - [ ] JSON Schema adapter
1655
+ - [ ] WebSocket message tracing
1656
+ - [ ] OpenTelemetry integration
1657
+ - [ ] Rust language support
1658
+ - [ ] Java/Kotlin language support
1659
+
1660
+ ## License
1661
+
1662
+ MIT