@vodailoc/kilo-kit-mcp 1.1.0 → 1.1.1

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 (570) hide show
  1. package/.mcp/kilo-kit.codex-windows.toml +5 -0
  2. package/LICENSE +190 -190
  3. package/QUICKSTART.md +265 -255
  4. package/README.md +290 -266
  5. package/mcp/README.md +29 -5
  6. package/mcp/dist/server.js +1 -1
  7. package/mcp/package.json +1 -2
  8. package/package.json +3 -2
  9. package/skills/README.md +647 -647
  10. package/skills/SKILLS_INDEX.md +139 -139
  11. package/skills/ai-media/ai-multimodal/.env.example +97 -97
  12. package/skills/ai-media/ai-multimodal/SKILL.md +357 -357
  13. package/skills/ai-media/ai-multimodal/references/audio-processing.md +373 -373
  14. package/skills/ai-media/ai-multimodal/references/image-generation.md +558 -558
  15. package/skills/ai-media/ai-multimodal/references/video-analysis.md +502 -502
  16. package/skills/ai-media/ai-multimodal/references/vision-understanding.md +483 -483
  17. package/skills/ai-media/ai-multimodal/scripts/document_converter.py +395 -395
  18. package/skills/ai-media/ai-multimodal/scripts/gemini_batch_process.py +480 -480
  19. package/skills/ai-media/ai-multimodal/scripts/media_optimizer.py +506 -506
  20. package/skills/ai-media/ai-multimodal/scripts/requirements.txt +26 -26
  21. package/skills/ai-media/ai-multimodal/scripts/tests/requirements.txt +20 -20
  22. package/skills/ai-media/ai-multimodal/scripts/tests/test_document_converter.py +299 -299
  23. package/skills/ai-media/ai-multimodal/scripts/tests/test_gemini_batch_process.py +362 -362
  24. package/skills/ai-media/ai-multimodal/scripts/tests/test_media_optimizer.py +373 -373
  25. package/skills/ai-media/media-processing/SKILL.md +358 -358
  26. package/skills/ai-media/media-processing/references/ffmpeg-encoding.md +358 -358
  27. package/skills/ai-media/media-processing/references/ffmpeg-filters.md +503 -503
  28. package/skills/ai-media/media-processing/references/ffmpeg-streaming.md +403 -403
  29. package/skills/ai-media/media-processing/references/format-compatibility.md +375 -375
  30. package/skills/ai-media/media-processing/references/imagemagick-batch.md +612 -612
  31. package/skills/ai-media/media-processing/references/imagemagick-editing.md +623 -623
  32. package/skills/ai-media/media-processing/scripts/batch_resize.py +342 -342
  33. package/skills/ai-media/media-processing/scripts/media_convert.py +311 -311
  34. package/skills/ai-media/media-processing/scripts/requirements.txt +24 -24
  35. package/skills/ai-media/media-processing/scripts/tests/requirements.txt +2 -2
  36. package/skills/ai-media/media-processing/scripts/tests/test_batch_resize.py +372 -372
  37. package/skills/ai-media/media-processing/scripts/tests/test_media_convert.py +259 -259
  38. package/skills/ai-media/media-processing/scripts/tests/test_video_optimize.py +397 -397
  39. package/skills/ai-media/media-processing/scripts/video_optimize.py +414 -414
  40. package/skills/ai-media/screenshot/LICENSE.txt +201 -201
  41. package/skills/ai-media/screenshot/SKILL.md +267 -267
  42. package/skills/ai-media/screenshot/agents/openai.yaml +6 -6
  43. package/skills/ai-media/screenshot/assets/screenshot-small.svg +5 -5
  44. package/skills/ai-media/screenshot/scripts/ensure_macos_permissions.sh +54 -54
  45. package/skills/ai-media/screenshot/scripts/macos_display_info.swift +22 -22
  46. package/skills/ai-media/screenshot/scripts/macos_permissions.swift +40 -40
  47. package/skills/ai-media/screenshot/scripts/macos_window_info.swift +126 -126
  48. package/skills/ai-media/screenshot/scripts/take_screenshot.ps1 +163 -163
  49. package/skills/ai-media/screenshot/scripts/take_screenshot.py +585 -585
  50. package/skills/ai-media/sora/LICENSE.txt +201 -201
  51. package/skills/ai-media/sora/SKILL.md +153 -153
  52. package/skills/ai-media/sora/agents/openai.yaml +6 -6
  53. package/skills/ai-media/sora/assets/sora-small.svg +4 -4
  54. package/skills/ai-media/sora/references/cinematic-shots.md +53 -53
  55. package/skills/ai-media/sora/references/cli.md +248 -248
  56. package/skills/ai-media/sora/references/codex-network.md +28 -28
  57. package/skills/ai-media/sora/references/prompting.md +137 -137
  58. package/skills/ai-media/sora/references/sample-prompts.md +95 -95
  59. package/skills/ai-media/sora/references/social-ads.md +42 -42
  60. package/skills/ai-media/sora/references/troubleshooting.md +58 -58
  61. package/skills/ai-media/sora/references/video-api.md +45 -45
  62. package/skills/ai-media/sora/scripts/sora.py +970 -970
  63. package/skills/design/aesthetic/SKILL.md +121 -121
  64. package/skills/design/aesthetic/assets/design-guideline-template.md +163 -163
  65. package/skills/design/aesthetic/assets/design-story-template.md +135 -135
  66. package/skills/design/aesthetic/references/design-principles.md +62 -62
  67. package/skills/design/aesthetic/references/design-resources.md +75 -75
  68. package/skills/design/aesthetic/references/micro-interactions.md +53 -53
  69. package/skills/design/aesthetic/references/storytelling-design.md +50 -50
  70. package/skills/design/figma/LICENSE.txt +202 -202
  71. package/skills/design/figma/SKILL.md +42 -42
  72. package/skills/design/figma/agents/openai.yaml +14 -14
  73. package/skills/design/figma/assets/figma-small.svg +3 -3
  74. package/skills/design/figma/assets/icon.svg +28 -28
  75. package/skills/design/figma/references/figma-mcp-config.md +35 -35
  76. package/skills/design/figma/references/figma-tools-and-prompts.md +34 -34
  77. package/skills/design/figma-implement-design/LICENSE.txt +202 -202
  78. package/skills/design/figma-implement-design/SKILL.md +264 -264
  79. package/skills/design/figma-implement-design/agents/openai.yaml +14 -14
  80. package/skills/design/figma-implement-design/assets/figma-small.svg +3 -3
  81. package/skills/design/figma-implement-design/assets/icon.svg +28 -28
  82. package/skills/design/frontend-design/SKILL.md +41 -41
  83. package/skills/design/frontend-design/references/animejs.md +395 -395
  84. package/skills/design/ui-styling/LICENSE.txt +201 -201
  85. package/skills/design/ui-styling/SKILL.md +321 -321
  86. package/skills/design/ui-styling/canvas-fonts/ArsenalSC-OFL.txt +93 -93
  87. package/skills/design/ui-styling/canvas-fonts/BigShoulders-OFL.txt +93 -93
  88. package/skills/design/ui-styling/canvas-fonts/Boldonse-OFL.txt +93 -93
  89. package/skills/design/ui-styling/canvas-fonts/BricolageGrotesque-OFL.txt +93 -93
  90. package/skills/design/ui-styling/canvas-fonts/CrimsonPro-OFL.txt +93 -93
  91. package/skills/design/ui-styling/canvas-fonts/DMMono-OFL.txt +93 -93
  92. package/skills/design/ui-styling/canvas-fonts/EricaOne-OFL.txt +94 -94
  93. package/skills/design/ui-styling/canvas-fonts/GeistMono-OFL.txt +93 -93
  94. package/skills/design/ui-styling/canvas-fonts/Gloock-OFL.txt +93 -93
  95. package/skills/design/ui-styling/canvas-fonts/IBMPlexMono-OFL.txt +93 -93
  96. package/skills/design/ui-styling/canvas-fonts/InstrumentSans-OFL.txt +93 -93
  97. package/skills/design/ui-styling/canvas-fonts/Italiana-OFL.txt +93 -93
  98. package/skills/design/ui-styling/canvas-fonts/JetBrainsMono-OFL.txt +93 -93
  99. package/skills/design/ui-styling/canvas-fonts/Jura-OFL.txt +93 -93
  100. package/skills/design/ui-styling/canvas-fonts/LibreBaskerville-OFL.txt +93 -93
  101. package/skills/design/ui-styling/canvas-fonts/Lora-OFL.txt +93 -93
  102. package/skills/design/ui-styling/canvas-fonts/NationalPark-OFL.txt +93 -93
  103. package/skills/design/ui-styling/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -93
  104. package/skills/design/ui-styling/canvas-fonts/Outfit-OFL.txt +93 -93
  105. package/skills/design/ui-styling/canvas-fonts/PixelifySans-OFL.txt +93 -93
  106. package/skills/design/ui-styling/canvas-fonts/PoiretOne-OFL.txt +93 -93
  107. package/skills/design/ui-styling/canvas-fonts/RedHatMono-OFL.txt +93 -93
  108. package/skills/design/ui-styling/canvas-fonts/Silkscreen-OFL.txt +93 -93
  109. package/skills/design/ui-styling/canvas-fonts/SmoochSans-OFL.txt +93 -93
  110. package/skills/design/ui-styling/canvas-fonts/Tektur-OFL.txt +93 -93
  111. package/skills/design/ui-styling/canvas-fonts/WorkSans-OFL.txt +93 -93
  112. package/skills/design/ui-styling/canvas-fonts/YoungSerif-OFL.txt +93 -93
  113. package/skills/design/ui-styling/references/canvas-design-system.md +320 -320
  114. package/skills/design/ui-styling/references/shadcn-accessibility.md +471 -471
  115. package/skills/design/ui-styling/references/shadcn-components.md +424 -424
  116. package/skills/design/ui-styling/references/shadcn-theming.md +373 -373
  117. package/skills/design/ui-styling/references/tailwind-customization.md +483 -483
  118. package/skills/design/ui-styling/references/tailwind-responsive.md +382 -382
  119. package/skills/design/ui-styling/references/tailwind-utilities.md +455 -455
  120. package/skills/design/ui-styling/scripts/requirements.txt +17 -17
  121. package/skills/design/ui-styling/scripts/shadcn_add.py +292 -292
  122. package/skills/design/ui-styling/scripts/tailwind_config_gen.py +456 -456
  123. package/skills/design/ui-styling/scripts/tests/requirements.txt +3 -3
  124. package/skills/design/ui-styling/scripts/tests/test_shadcn_add.py +266 -266
  125. package/skills/design/ui-styling/scripts/tests/test_tailwind_config_gen.py +336 -336
  126. package/skills/engineering/aspnet-core/LICENSE.txt +201 -201
  127. package/skills/engineering/aspnet-core/SKILL.md +61 -61
  128. package/skills/engineering/aspnet-core/agents/openai.yaml +5 -5
  129. package/skills/engineering/aspnet-core/references/_sections.md +40 -40
  130. package/skills/engineering/aspnet-core/references/apis-minimal-and-controllers.md +81 -81
  131. package/skills/engineering/aspnet-core/references/data-state-and-services.md +69 -69
  132. package/skills/engineering/aspnet-core/references/program-and-pipeline.md +103 -103
  133. package/skills/engineering/aspnet-core/references/realtime-grpc-and-background-work.md +58 -58
  134. package/skills/engineering/aspnet-core/references/security-and-identity.md +75 -75
  135. package/skills/engineering/aspnet-core/references/source-map.md +43 -43
  136. package/skills/engineering/aspnet-core/references/stack-selection.md +63 -63
  137. package/skills/engineering/aspnet-core/references/testing-performance-and-operations.md +92 -92
  138. package/skills/engineering/aspnet-core/references/ui-blazor.md +53 -53
  139. package/skills/engineering/aspnet-core/references/ui-mvc.md +56 -56
  140. package/skills/engineering/aspnet-core/references/ui-razor-pages.md +55 -55
  141. package/skills/engineering/aspnet-core/references/versioning-and-upgrades.md +51 -51
  142. package/skills/engineering/backend-development/SKILL.md +95 -95
  143. package/skills/engineering/backend-development/references/backend-api-design.md +495 -495
  144. package/skills/engineering/backend-development/references/backend-architecture.md +454 -454
  145. package/skills/engineering/backend-development/references/backend-authentication.md +338 -338
  146. package/skills/engineering/backend-development/references/backend-code-quality.md +659 -659
  147. package/skills/engineering/backend-development/references/backend-debugging.md +904 -904
  148. package/skills/engineering/backend-development/references/backend-devops.md +494 -494
  149. package/skills/engineering/backend-development/references/backend-mindset.md +387 -387
  150. package/skills/engineering/backend-development/references/backend-performance.md +397 -397
  151. package/skills/engineering/backend-development/references/backend-security.md +290 -290
  152. package/skills/engineering/backend-development/references/backend-technologies.md +256 -256
  153. package/skills/engineering/backend-development/references/backend-testing.md +429 -429
  154. package/skills/engineering/better-auth/SKILL.md +204 -204
  155. package/skills/engineering/better-auth/references/advanced-features.md +553 -553
  156. package/skills/engineering/better-auth/references/database-integration.md +577 -577
  157. package/skills/engineering/better-auth/references/email-password-auth.md +416 -416
  158. package/skills/engineering/better-auth/references/oauth-providers.md +430 -430
  159. package/skills/engineering/better-auth/scripts/better_auth_init.py +521 -521
  160. package/skills/engineering/better-auth/scripts/requirements.txt +15 -15
  161. package/skills/engineering/better-auth/scripts/tests/test_better_auth_init.py +421 -421
  162. package/skills/engineering/code-review/SKILL.md +140 -140
  163. package/skills/engineering/code-review/references/code-review-reception.md +208 -208
  164. package/skills/engineering/code-review/references/requesting-code-review.md +104 -104
  165. package/skills/engineering/code-review/references/verification-before-completion.md +138 -138
  166. package/skills/engineering/context-engineering/SKILL.md +86 -86
  167. package/skills/engineering/context-engineering/references/context-compression.md +84 -84
  168. package/skills/engineering/context-engineering/references/context-degradation.md +93 -93
  169. package/skills/engineering/context-engineering/references/context-fundamentals.md +75 -75
  170. package/skills/engineering/context-engineering/references/context-optimization.md +82 -82
  171. package/skills/engineering/context-engineering/references/evaluation.md +89 -89
  172. package/skills/engineering/context-engineering/references/memory-systems.md +88 -88
  173. package/skills/engineering/context-engineering/references/multi-agent-patterns.md +90 -90
  174. package/skills/engineering/context-engineering/references/project-development.md +97 -97
  175. package/skills/engineering/context-engineering/references/tool-design.md +86 -86
  176. package/skills/engineering/context-engineering/scripts/compression_evaluator.py +329 -329
  177. package/skills/engineering/context-engineering/scripts/context_analyzer.py +294 -294
  178. package/skills/engineering/databases/SKILL.md +232 -232
  179. package/skills/engineering/databases/references/mongodb-aggregation.md +447 -447
  180. package/skills/engineering/databases/references/mongodb-atlas.md +465 -465
  181. package/skills/engineering/databases/references/mongodb-crud.md +408 -408
  182. package/skills/engineering/databases/references/mongodb-indexing.md +442 -442
  183. package/skills/engineering/databases/references/postgresql-administration.md +594 -594
  184. package/skills/engineering/databases/references/postgresql-performance.md +527 -527
  185. package/skills/engineering/databases/references/postgresql-psql-cli.md +467 -467
  186. package/skills/engineering/databases/references/postgresql-queries.md +475 -475
  187. package/skills/engineering/databases/scripts/db_backup.py +502 -502
  188. package/skills/engineering/databases/scripts/db_migrate.py +414 -414
  189. package/skills/engineering/databases/scripts/db_performance_check.py +444 -444
  190. package/skills/engineering/databases/scripts/requirements.txt +20 -20
  191. package/skills/engineering/databases/scripts/tests/requirements.txt +4 -4
  192. package/skills/engineering/databases/scripts/tests/test_db_backup.py +340 -340
  193. package/skills/engineering/databases/scripts/tests/test_db_migrate.py +277 -277
  194. package/skills/engineering/databases/scripts/tests/test_db_performance_check.py +370 -370
  195. package/skills/engineering/diagnose/SKILL.md +117 -117
  196. package/skills/engineering/diagnose/scripts/hitl-loop.template.sh +41 -41
  197. package/skills/engineering/docs-seeker/SKILL.md +207 -207
  198. package/skills/engineering/docs-seeker/WORKFLOWS.md +505 -505
  199. package/skills/engineering/docs-seeker/references/best-practices.md +632 -632
  200. package/skills/engineering/docs-seeker/references/documentation-sources.md +461 -461
  201. package/skills/engineering/docs-seeker/references/error-handling.md +621 -621
  202. package/skills/engineering/docs-seeker/references/limitations.md +821 -821
  203. package/skills/engineering/docs-seeker/references/performance.md +574 -574
  204. package/skills/engineering/docs-seeker/references/tool-selection.md +262 -262
  205. package/skills/engineering/frontend-development/SKILL.md +398 -398
  206. package/skills/engineering/frontend-development/resources/common-patterns.md +330 -330
  207. package/skills/engineering/frontend-development/resources/complete-examples.md +871 -871
  208. package/skills/engineering/frontend-development/resources/component-patterns.md +501 -501
  209. package/skills/engineering/frontend-development/resources/data-fetching.md +766 -766
  210. package/skills/engineering/frontend-development/resources/file-organization.md +501 -501
  211. package/skills/engineering/frontend-development/resources/loading-and-error-states.md +500 -500
  212. package/skills/engineering/frontend-development/resources/performance.md +405 -405
  213. package/skills/engineering/frontend-development/resources/routing-guide.md +363 -363
  214. package/skills/engineering/frontend-development/resources/styling-guide.md +427 -427
  215. package/skills/engineering/frontend-development/resources/typescript-standards.md +417 -417
  216. package/skills/engineering/improve-codebase-architecture/DEEPENING.md +37 -37
  217. package/skills/engineering/improve-codebase-architecture/INTERFACE-DESIGN.md +44 -44
  218. package/skills/engineering/improve-codebase-architecture/LANGUAGE.md +53 -53
  219. package/skills/engineering/improve-codebase-architecture/SKILL.md +71 -71
  220. package/skills/engineering/openai-docs/LICENSE.txt +201 -201
  221. package/skills/engineering/openai-docs/SKILL.md +69 -69
  222. package/skills/engineering/openai-docs/agents/openai.yaml +14 -14
  223. package/skills/engineering/openai-docs/assets/openai-small.svg +3 -3
  224. package/skills/engineering/openai-docs/references/gpt-5p4-prompting-guide.md +433 -433
  225. package/skills/engineering/openai-docs/references/latest-model.md +35 -35
  226. package/skills/engineering/openai-docs/references/upgrading-to-gpt-5p4.md +164 -164
  227. package/skills/engineering/playwright/LICENSE.txt +201 -201
  228. package/skills/engineering/playwright/NOTICE.txt +14 -14
  229. package/skills/engineering/playwright/SKILL.md +147 -147
  230. package/skills/engineering/playwright/agents/openai.yaml +6 -6
  231. package/skills/engineering/playwright/assets/playwright-small.svg +3 -3
  232. package/skills/engineering/playwright/references/cli.md +116 -116
  233. package/skills/engineering/playwright/references/workflows.md +95 -95
  234. package/skills/engineering/playwright/scripts/playwright_cli.sh +25 -25
  235. package/skills/engineering/playwright-interactive/LICENSE.txt +201 -201
  236. package/skills/engineering/playwright-interactive/NOTICE.txt +13 -13
  237. package/skills/engineering/playwright-interactive/SKILL.md +689 -689
  238. package/skills/engineering/playwright-interactive/agents/openai.yaml +6 -6
  239. package/skills/engineering/playwright-interactive/assets/playwright-small.svg +3 -3
  240. package/skills/engineering/render-deploy/LICENSE.txt +201 -201
  241. package/skills/engineering/render-deploy/SKILL.md +479 -479
  242. package/skills/engineering/render-deploy/agents/openai.yaml +14 -14
  243. package/skills/engineering/render-deploy/assets/docker.yaml +62 -62
  244. package/skills/engineering/render-deploy/assets/go-api.yaml +35 -35
  245. package/skills/engineering/render-deploy/assets/nextjs-postgres.yaml +35 -35
  246. package/skills/engineering/render-deploy/assets/node-express.yaml +25 -25
  247. package/skills/engineering/render-deploy/assets/python-django.yaml +89 -89
  248. package/skills/engineering/render-deploy/assets/render-small.svg +3 -3
  249. package/skills/engineering/render-deploy/assets/static-site.yaml +54 -54
  250. package/skills/engineering/render-deploy/references/blueprint-spec.md +718 -718
  251. package/skills/engineering/render-deploy/references/codebase-analysis.md +49 -49
  252. package/skills/engineering/render-deploy/references/configuration-guide.md +603 -603
  253. package/skills/engineering/render-deploy/references/deployment-details.md +224 -224
  254. package/skills/engineering/render-deploy/references/direct-creation.md +113 -113
  255. package/skills/engineering/render-deploy/references/error-patterns.md +13 -13
  256. package/skills/engineering/render-deploy/references/post-deploy-checks.md +36 -36
  257. package/skills/engineering/render-deploy/references/runtimes.md +473 -473
  258. package/skills/engineering/render-deploy/references/service-types.md +450 -450
  259. package/skills/engineering/render-deploy/references/troubleshooting-basics.md +36 -36
  260. package/skills/engineering/repomix/SKILL.md +215 -215
  261. package/skills/engineering/repomix/references/configuration.md +211 -211
  262. package/skills/engineering/repomix/references/usage-patterns.md +232 -232
  263. package/skills/engineering/repomix/scripts/README.md +179 -179
  264. package/skills/engineering/repomix/scripts/repomix_batch.py +455 -455
  265. package/skills/engineering/repomix/scripts/repos.example.json +15 -15
  266. package/skills/engineering/repomix/scripts/requirements.txt +15 -15
  267. package/skills/engineering/repomix/scripts/tests/test_repomix_batch.py +531 -531
  268. package/skills/engineering/setup-matt-pocock-skills/SKILL.md +121 -121
  269. package/skills/engineering/setup-matt-pocock-skills/domain.md +51 -51
  270. package/skills/engineering/setup-matt-pocock-skills/issue-tracker-github.md +22 -22
  271. package/skills/engineering/setup-matt-pocock-skills/issue-tracker-gitlab.md +23 -23
  272. package/skills/engineering/setup-matt-pocock-skills/issue-tracker-local.md +19 -19
  273. package/skills/engineering/setup-matt-pocock-skills/triage-labels.md +15 -15
  274. package/skills/engineering/shopify/README.md +66 -66
  275. package/skills/engineering/shopify/SKILL.md +319 -319
  276. package/skills/engineering/shopify/references/app-development.md +470 -470
  277. package/skills/engineering/shopify/references/extensions.md +493 -493
  278. package/skills/engineering/shopify/references/themes.md +498 -498
  279. package/skills/engineering/shopify/scripts/requirements.txt +19 -19
  280. package/skills/engineering/shopify/scripts/shopify_init.py +423 -423
  281. package/skills/engineering/shopify/scripts/tests/test_shopify_init.py +385 -385
  282. package/skills/engineering/tdd/SKILL.md +109 -109
  283. package/skills/engineering/tdd/deep-modules.md +33 -33
  284. package/skills/engineering/tdd/interface-design.md +31 -31
  285. package/skills/engineering/tdd/mocking.md +59 -59
  286. package/skills/engineering/tdd/refactoring.md +10 -10
  287. package/skills/engineering/tdd/tests.md +61 -61
  288. package/skills/engineering/to-issues/SKILL.md +81 -81
  289. package/skills/engineering/to-prd/SKILL.md +74 -74
  290. package/skills/engineering/triage/AGENT-BRIEF.md +168 -168
  291. package/skills/engineering/triage/OUT-OF-SCOPE.md +101 -101
  292. package/skills/engineering/triage/SKILL.md +103 -103
  293. package/skills/engineering/web-frameworks/SKILL.md +324 -324
  294. package/skills/engineering/web-frameworks/references/nextjs-app-router.md +465 -465
  295. package/skills/engineering/web-frameworks/references/nextjs-data-fetching.md +459 -459
  296. package/skills/engineering/web-frameworks/references/nextjs-optimization.md +511 -511
  297. package/skills/engineering/web-frameworks/references/nextjs-server-components.md +495 -495
  298. package/skills/engineering/web-frameworks/references/remix-icon-integration.md +603 -603
  299. package/skills/engineering/web-frameworks/references/turborepo-caching.md +551 -551
  300. package/skills/engineering/web-frameworks/references/turborepo-pipelines.md +517 -517
  301. package/skills/engineering/web-frameworks/references/turborepo-setup.md +542 -542
  302. package/skills/engineering/web-frameworks/scripts/nextjs_init.py +547 -547
  303. package/skills/engineering/web-frameworks/scripts/requirements.txt +16 -16
  304. package/skills/engineering/web-frameworks/scripts/tests/requirements.txt +3 -3
  305. package/skills/engineering/web-frameworks/scripts/tests/test_nextjs_init.py +319 -319
  306. package/skills/engineering/web-frameworks/scripts/tests/test_turborepo_migrate.py +374 -374
  307. package/skills/engineering/web-frameworks/scripts/turborepo_migrate.py +394 -394
  308. package/skills/engineering/write-a-skill/SKILL.md +117 -117
  309. package/skills/kilo-kit/SKILL.md +346 -346
  310. package/skills/kilo-kit/_template/SKILL.md +185 -185
  311. package/skills/kilo-kit/debugging/root-cause/SKILL.md +360 -360
  312. package/skills/kilo-kit/debugging/systematic/SKILL.md +339 -339
  313. package/skills/kilo-kit/debugging/verification/SKILL.md +424 -424
  314. package/skills/kilo-kit/development/backend/SKILL.md +540 -540
  315. package/skills/kilo-kit/development/security/SKILL.md +529 -529
  316. package/skills/kilo-kit/quality/code-review/SKILL.md +297 -297
  317. package/skills/kilo-kit/quality/testing/SKILL.md +540 -540
  318. package/skills/kilo-kit/references/output-formats.md +204 -204
  319. package/skills/kilo-kit/references/patterns.md +156 -156
  320. package/skills/kilo-kit/references/performance-benchmarks.md +90 -90
  321. package/skills/operations/chrome-devtools/SKILL.md +392 -392
  322. package/skills/operations/chrome-devtools/references/cdp-domains.md +694 -694
  323. package/skills/operations/chrome-devtools/references/performance-guide.md +940 -940
  324. package/skills/operations/chrome-devtools/references/puppeteer-reference.md +953 -953
  325. package/skills/operations/chrome-devtools/scripts/PERSISTENT-BROWSER.md +107 -107
  326. package/skills/operations/chrome-devtools/scripts/README.md +213 -213
  327. package/skills/operations/chrome-devtools/scripts/__tests__/selector.test.js +210 -210
  328. package/skills/operations/chrome-devtools/scripts/click.js +79 -79
  329. package/skills/operations/chrome-devtools/scripts/close-persistent.js +36 -36
  330. package/skills/operations/chrome-devtools/scripts/console.js +75 -75
  331. package/skills/operations/chrome-devtools/scripts/evaluate.js +49 -49
  332. package/skills/operations/chrome-devtools/scripts/fill.js +72 -72
  333. package/skills/operations/chrome-devtools/scripts/install-deps.sh +181 -181
  334. package/skills/operations/chrome-devtools/scripts/install.sh +83 -83
  335. package/skills/operations/chrome-devtools/scripts/launch-persistent.js +71 -71
  336. package/skills/operations/chrome-devtools/scripts/lib/browser.js +144 -144
  337. package/skills/operations/chrome-devtools/scripts/lib/selector.js +178 -178
  338. package/skills/operations/chrome-devtools/scripts/navigate.js +46 -46
  339. package/skills/operations/chrome-devtools/scripts/network.js +102 -102
  340. package/skills/operations/chrome-devtools/scripts/package-lock.json +1206 -1206
  341. package/skills/operations/chrome-devtools/scripts/package.json +15 -15
  342. package/skills/operations/chrome-devtools/scripts/performance.js +145 -145
  343. package/skills/operations/chrome-devtools/scripts/screenshot.js +180 -180
  344. package/skills/operations/chrome-devtools/scripts/snapshot.js +131 -131
  345. package/skills/operations/devops/.env.example +76 -76
  346. package/skills/operations/devops/SKILL.md +285 -285
  347. package/skills/operations/devops/references/browser-rendering.md +305 -305
  348. package/skills/operations/devops/references/cloudflare-d1-kv.md +123 -123
  349. package/skills/operations/devops/references/cloudflare-platform.md +271 -271
  350. package/skills/operations/devops/references/cloudflare-r2-storage.md +280 -280
  351. package/skills/operations/devops/references/cloudflare-workers-advanced.md +312 -312
  352. package/skills/operations/devops/references/cloudflare-workers-apis.md +309 -309
  353. package/skills/operations/devops/references/cloudflare-workers-basics.md +418 -418
  354. package/skills/operations/devops/references/docker-basics.md +297 -297
  355. package/skills/operations/devops/references/docker-compose.md +292 -292
  356. package/skills/operations/devops/references/gcloud-platform.md +297 -297
  357. package/skills/operations/devops/references/gcloud-services.md +304 -304
  358. package/skills/operations/devops/scripts/cloudflare_deploy.py +269 -269
  359. package/skills/operations/devops/scripts/docker_optimize.py +320 -320
  360. package/skills/operations/devops/scripts/requirements.txt +20 -20
  361. package/skills/operations/devops/scripts/tests/requirements.txt +3 -3
  362. package/skills/operations/devops/scripts/tests/test_cloudflare_deploy.py +285 -285
  363. package/skills/operations/devops/scripts/tests/test_docker_optimize.py +436 -436
  364. package/skills/operations/mcp-builder/LICENSE.txt +201 -201
  365. package/skills/operations/mcp-builder/SKILL.md +328 -328
  366. package/skills/operations/mcp-builder/reference/evaluation.md +601 -601
  367. package/skills/operations/mcp-builder/reference/mcp_best_practices.md +915 -915
  368. package/skills/operations/mcp-builder/reference/node_mcp_server.md +915 -915
  369. package/skills/operations/mcp-builder/reference/python_mcp_server.md +751 -751
  370. package/skills/operations/mcp-builder/scripts/connections.py +151 -151
  371. package/skills/operations/mcp-builder/scripts/evaluation.py +373 -373
  372. package/skills/operations/mcp-builder/scripts/example_evaluation.xml +22 -22
  373. package/skills/operations/mcp-builder/scripts/requirements.txt +2 -2
  374. package/skills/operations/mcp-management/README.md +219 -219
  375. package/skills/operations/mcp-management/SKILL.md +175 -175
  376. package/skills/operations/mcp-management/assets/tools.json +3043 -3043
  377. package/skills/operations/mcp-management/references/configuration.md +114 -114
  378. package/skills/operations/mcp-management/references/gemini-cli-integration.md +201 -201
  379. package/skills/operations/mcp-management/references/mcp-protocol.md +116 -116
  380. package/skills/operations/mcp-management/scripts/.env.example +10 -10
  381. package/skills/operations/mcp-management/scripts/cli.ts +155 -155
  382. package/skills/operations/mcp-management/scripts/dist/analyze-tools.js +70 -70
  383. package/skills/operations/mcp-management/scripts/dist/cli.js +131 -131
  384. package/skills/operations/mcp-management/scripts/dist/mcp-client.js +115 -115
  385. package/skills/operations/mcp-management/scripts/mcp-client.ts +163 -163
  386. package/skills/operations/mcp-management/scripts/package.json +18 -18
  387. package/skills/operations/mcp-management/scripts/tsconfig.json +15 -15
  388. package/skills/problem-solving/collision-zone-thinking/SKILL.md +62 -62
  389. package/skills/problem-solving/defense-in-depth/SKILL.md +130 -130
  390. package/skills/problem-solving/inversion-exercise/SKILL.md +58 -58
  391. package/skills/problem-solving/meta-pattern-recognition/SKILL.md +54 -54
  392. package/skills/problem-solving/root-cause-tracing/SKILL.md +177 -177
  393. package/skills/problem-solving/root-cause-tracing/find-polluter.sh +63 -63
  394. package/skills/problem-solving/scale-game/SKILL.md +63 -63
  395. package/skills/problem-solving/sequential-thinking/README.md +118 -118
  396. package/skills/problem-solving/sequential-thinking/SKILL.md +93 -93
  397. package/skills/problem-solving/sequential-thinking/references/advanced.md +122 -122
  398. package/skills/problem-solving/sequential-thinking/references/examples.md +274 -274
  399. package/skills/problem-solving/simplification-cascades/SKILL.md +76 -76
  400. package/skills/problem-solving/when-stuck/SKILL.md +88 -88
  401. package/skills/productivity/caveman/SKILL.md +49 -49
  402. package/skills/productivity/grill-me/SKILL.md +10 -10
  403. package/skills/productivity/grill-with-docs/ADR-FORMAT.md +47 -47
  404. package/skills/productivity/grill-with-docs/CONTEXT-FORMAT.md +77 -77
  405. package/skills/productivity/grill-with-docs/SKILL.md +88 -88
  406. package/skills/productivity/writing-skills/graphviz-conventions.dot +171 -171
  407. package/skills/productivity/zoom-out/SKILL.md +7 -7
  408. package/skills/writing-docs/doc/LICENSE.txt +201 -201
  409. package/skills/writing-docs/doc/SKILL.md +80 -80
  410. package/skills/writing-docs/doc/agents/openai.yaml +6 -6
  411. package/skills/writing-docs/doc/assets/doc-small.svg +3 -3
  412. package/skills/writing-docs/doc/scripts/render_docx.py +296 -296
  413. package/skills/writing-docs/docx/LICENSE.txt +30 -30
  414. package/skills/writing-docs/docx/SKILL.md +196 -196
  415. package/skills/writing-docs/docx/docx-js.md +349 -349
  416. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -1499
  417. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -146
  418. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -1085
  419. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -11
  420. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -3081
  421. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -23
  422. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -185
  423. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -287
  424. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -1676
  425. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -28
  426. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -144
  427. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -174
  428. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -25
  429. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -18
  430. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -59
  431. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -56
  432. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -195
  433. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -582
  434. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -25
  435. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -4439
  436. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -570
  437. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -509
  438. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -12
  439. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -108
  440. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -96
  441. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -3646
  442. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -116
  443. package/skills/writing-docs/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -42
  444. package/skills/writing-docs/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -50
  445. package/skills/writing-docs/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -49
  446. package/skills/writing-docs/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -33
  447. package/skills/writing-docs/docx/ooxml/schemas/mce/mc.xsd +75 -75
  448. package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -560
  449. package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -67
  450. package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -14
  451. package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -20
  452. package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -13
  453. package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -4
  454. package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -8
  455. package/skills/writing-docs/docx/ooxml/scripts/pack.py +159 -159
  456. package/skills/writing-docs/docx/ooxml/scripts/unpack.py +29 -29
  457. package/skills/writing-docs/docx/ooxml/scripts/validate.py +69 -69
  458. package/skills/writing-docs/docx/ooxml/scripts/validation/__init__.py +15 -15
  459. package/skills/writing-docs/docx/ooxml/scripts/validation/base.py +951 -951
  460. package/skills/writing-docs/docx/ooxml/scripts/validation/docx.py +274 -274
  461. package/skills/writing-docs/docx/ooxml/scripts/validation/pptx.py +315 -315
  462. package/skills/writing-docs/docx/ooxml/scripts/validation/redlining.py +279 -279
  463. package/skills/writing-docs/docx/ooxml.md +609 -609
  464. package/skills/writing-docs/docx/scripts/__init__.py +1 -1
  465. package/skills/writing-docs/docx/scripts/document.py +1276 -1276
  466. package/skills/writing-docs/docx/scripts/templates/comments.xml +2 -2
  467. package/skills/writing-docs/docx/scripts/templates/commentsExtended.xml +2 -2
  468. package/skills/writing-docs/docx/scripts/templates/commentsExtensible.xml +2 -2
  469. package/skills/writing-docs/docx/scripts/templates/commentsIds.xml +2 -2
  470. package/skills/writing-docs/docx/scripts/templates/people.xml +2 -2
  471. package/skills/writing-docs/docx/scripts/utilities.py +374 -374
  472. package/skills/writing-docs/mermaidjs-v11/SKILL.md +115 -115
  473. package/skills/writing-docs/mermaidjs-v11/references/cli-usage.md +228 -228
  474. package/skills/writing-docs/mermaidjs-v11/references/configuration.md +232 -232
  475. package/skills/writing-docs/mermaidjs-v11/references/diagram-types.md +315 -315
  476. package/skills/writing-docs/mermaidjs-v11/references/examples.md +344 -344
  477. package/skills/writing-docs/mermaidjs-v11/references/integration.md +310 -310
  478. package/skills/writing-docs/pdf/LICENSE.txt +30 -30
  479. package/skills/writing-docs/pdf/SKILL.md +294 -294
  480. package/skills/writing-docs/pdf/forms.md +205 -205
  481. package/skills/writing-docs/pdf/reference.md +611 -611
  482. package/skills/writing-docs/pdf/scripts/check_bounding_boxes.py +70 -70
  483. package/skills/writing-docs/pdf/scripts/check_bounding_boxes_test.py +226 -226
  484. package/skills/writing-docs/pdf/scripts/check_fillable_fields.py +12 -12
  485. package/skills/writing-docs/pdf/scripts/convert_pdf_to_images.py +35 -35
  486. package/skills/writing-docs/pdf/scripts/create_validation_image.py +41 -41
  487. package/skills/writing-docs/pdf/scripts/extract_form_field_info.py +152 -152
  488. package/skills/writing-docs/pdf/scripts/fill_fillable_fields.py +114 -114
  489. package/skills/writing-docs/pdf/scripts/fill_pdf_form_with_annotations.py +107 -107
  490. package/skills/writing-docs/pptx/LICENSE.txt +30 -30
  491. package/skills/writing-docs/pptx/SKILL.md +483 -483
  492. package/skills/writing-docs/pptx/html2pptx.md +624 -624
  493. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -1499
  494. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -146
  495. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -1085
  496. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -11
  497. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -3081
  498. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -23
  499. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -185
  500. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -287
  501. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -1676
  502. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -28
  503. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -144
  504. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -174
  505. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -25
  506. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -18
  507. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -59
  508. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -56
  509. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -195
  510. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -582
  511. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -25
  512. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -4439
  513. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -570
  514. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -509
  515. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -12
  516. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -108
  517. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -96
  518. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -3646
  519. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -116
  520. package/skills/writing-docs/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -42
  521. package/skills/writing-docs/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -50
  522. package/skills/writing-docs/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -49
  523. package/skills/writing-docs/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -33
  524. package/skills/writing-docs/pptx/ooxml/schemas/mce/mc.xsd +75 -75
  525. package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -560
  526. package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -67
  527. package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -14
  528. package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -20
  529. package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -13
  530. package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -4
  531. package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -8
  532. package/skills/writing-docs/pptx/ooxml/scripts/pack.py +159 -159
  533. package/skills/writing-docs/pptx/ooxml/scripts/unpack.py +29 -29
  534. package/skills/writing-docs/pptx/ooxml/scripts/validate.py +69 -69
  535. package/skills/writing-docs/pptx/ooxml/scripts/validation/__init__.py +15 -15
  536. package/skills/writing-docs/pptx/ooxml/scripts/validation/base.py +951 -951
  537. package/skills/writing-docs/pptx/ooxml/scripts/validation/docx.py +274 -274
  538. package/skills/writing-docs/pptx/ooxml/scripts/validation/pptx.py +315 -315
  539. package/skills/writing-docs/pptx/ooxml/scripts/validation/redlining.py +279 -279
  540. package/skills/writing-docs/pptx/ooxml.md +426 -426
  541. package/skills/writing-docs/pptx/scripts/html2pptx.js +978 -978
  542. package/skills/writing-docs/pptx/scripts/inventory.py +1020 -1020
  543. package/skills/writing-docs/pptx/scripts/rearrange.py +231 -231
  544. package/skills/writing-docs/pptx/scripts/replace.py +385 -385
  545. package/skills/writing-docs/pptx/scripts/thumbnail.py +450 -450
  546. package/skills/writing-docs/slides/LICENSE.txt +201 -201
  547. package/skills/writing-docs/slides/SKILL.md +71 -71
  548. package/skills/writing-docs/slides/agents/openai.yaml +6 -6
  549. package/skills/writing-docs/slides/assets/pptxgenjs_helpers/code.js +104 -104
  550. package/skills/writing-docs/slides/assets/pptxgenjs_helpers/image.js +333 -333
  551. package/skills/writing-docs/slides/assets/pptxgenjs_helpers/index.js +33 -33
  552. package/skills/writing-docs/slides/assets/pptxgenjs_helpers/latex.js +51 -51
  553. package/skills/writing-docs/slides/assets/pptxgenjs_helpers/layout.js +643 -643
  554. package/skills/writing-docs/slides/assets/pptxgenjs_helpers/layout_builders.js +358 -358
  555. package/skills/writing-docs/slides/assets/pptxgenjs_helpers/svg.js +36 -36
  556. package/skills/writing-docs/slides/assets/pptxgenjs_helpers/text.js +789 -789
  557. package/skills/writing-docs/slides/assets/pptxgenjs_helpers/util.js +24 -24
  558. package/skills/writing-docs/slides/assets/slides-small.svg +3 -3
  559. package/skills/writing-docs/slides/references/pptxgenjs-helpers.md +61 -61
  560. package/skills/writing-docs/slides/scripts/create_montage.py +300 -300
  561. package/skills/writing-docs/slides/scripts/detect_font.py +873 -873
  562. package/skills/writing-docs/slides/scripts/ensure_raster_image.py +202 -202
  563. package/skills/writing-docs/slides/scripts/render_slides.py +273 -273
  564. package/skills/writing-docs/slides/scripts/slides_test.py +201 -201
  565. package/skills/writing-docs/template-skill/SKILL.md +26 -26
  566. package/skills/writing-docs/xlsx/LICENSE.txt +30 -30
  567. package/skills/writing-docs/xlsx/SKILL.md +288 -288
  568. package/skills/writing-docs/xlsx/recalc.py +177 -177
  569. package/src/core/KILO_MASTER.md +448 -448
  570. package/src/tools/validate-skill.js +421 -421
@@ -1,916 +1,916 @@
1
- # Node/TypeScript MCP Server Implementation Guide
2
-
3
- ## Overview
4
-
5
- This document provides Node/TypeScript-specific best practices and examples for implementing MCP servers using the MCP TypeScript SDK. It covers project structure, server setup, tool registration patterns, input validation with Zod, error handling, and complete working examples.
6
-
7
- ---
8
-
9
- ## Quick Reference
10
-
11
- ### Key Imports
12
- ```typescript
13
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
14
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
15
- import { z } from "zod";
16
- import axios, { AxiosError } from "axios";
17
- ```
18
-
19
- ### Server Initialization
20
- ```typescript
21
- const server = new McpServer({
22
- name: "service-mcp-server",
23
- version: "1.0.0"
24
- });
25
- ```
26
-
27
- ### Tool Registration Pattern
28
- ```typescript
29
- server.registerTool("tool_name", {...config}, async (params) => {
30
- // Implementation
31
- });
32
- ```
33
-
34
- ---
35
-
36
- ## MCP TypeScript SDK
37
-
38
- The official MCP TypeScript SDK provides:
39
- - `McpServer` class for server initialization
40
- - `registerTool` method for tool registration
41
- - Zod schema integration for runtime input validation
42
- - Type-safe tool handler implementations
43
-
44
- See the MCP SDK documentation in the references for complete details.
45
-
46
- ## Server Naming Convention
47
-
48
- Node/TypeScript MCP servers must follow this naming pattern:
49
- - **Format**: `{service}-mcp-server` (lowercase with hyphens)
50
- - **Examples**: `github-mcp-server`, `jira-mcp-server`, `stripe-mcp-server`
51
-
52
- The name should be:
53
- - General (not tied to specific features)
54
- - Descriptive of the service/API being integrated
55
- - Easy to infer from the task description
56
- - Without version numbers or dates
57
-
58
- ## Project Structure
59
-
60
- Create the following structure for Node/TypeScript MCP servers:
61
-
62
- ```
63
- {service}-mcp-server/
64
- ├── package.json
65
- ├── tsconfig.json
66
- ├── README.md
67
- ├── src/
68
- │ ├── index.ts # Main entry point with McpServer initialization
69
- │ ├── types.ts # TypeScript type definitions and interfaces
70
- │ ├── tools/ # Tool implementations (one file per domain)
71
- │ ├── services/ # API clients and shared utilities
72
- │ ├── schemas/ # Zod validation schemas
73
- │ └── constants.ts # Shared constants (API_URL, CHARACTER_LIMIT, etc.)
74
- └── dist/ # Built JavaScript files (entry point: dist/index.js)
75
- ```
76
-
77
- ## Tool Implementation
78
-
79
- ### Tool Naming
80
-
81
- Use snake_case for tool names (e.g., "search_users", "create_project", "get_channel_info") with clear, action-oriented names.
82
-
83
- **Avoid Naming Conflicts**: Include the service context to prevent overlaps:
84
- - Use "slack_send_message" instead of just "send_message"
85
- - Use "github_create_issue" instead of just "create_issue"
86
- - Use "asana_list_tasks" instead of just "list_tasks"
87
-
88
- ### Tool Structure
89
-
90
- Tools are registered using the `registerTool` method with the following requirements:
91
- - Use Zod schemas for runtime input validation and type safety
92
- - The `description` field must be explicitly provided - JSDoc comments are NOT automatically extracted
93
- - Explicitly provide `title`, `description`, `inputSchema`, and `annotations`
94
- - The `inputSchema` must be a Zod schema object (not a JSON schema)
95
- - Type all parameters and return values explicitly
96
-
97
- ```typescript
98
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
99
- import { z } from "zod";
100
-
101
- const server = new McpServer({
102
- name: "example-mcp",
103
- version: "1.0.0"
104
- });
105
-
106
- // Zod schema for input validation
107
- const UserSearchInputSchema = z.object({
108
- query: z.string()
109
- .min(2, "Query must be at least 2 characters")
110
- .max(200, "Query must not exceed 200 characters")
111
- .describe("Search string to match against names/emails"),
112
- limit: z.number()
113
- .int()
114
- .min(1)
115
- .max(100)
116
- .default(20)
117
- .describe("Maximum results to return"),
118
- offset: z.number()
119
- .int()
120
- .min(0)
121
- .default(0)
122
- .describe("Number of results to skip for pagination"),
123
- response_format: z.nativeEnum(ResponseFormat)
124
- .default(ResponseFormat.MARKDOWN)
125
- .describe("Output format: 'markdown' for human-readable or 'json' for machine-readable")
126
- }).strict();
127
-
128
- // Type definition from Zod schema
129
- type UserSearchInput = z.infer<typeof UserSearchInputSchema>;
130
-
131
- server.registerTool(
132
- "example_search_users",
133
- {
134
- title: "Search Example Users",
135
- description: `Search for users in the Example system by name, email, or team.
136
-
137
- This tool searches across all user profiles in the Example platform, supporting partial matches and various search filters. It does NOT create or modify users, only searches existing ones.
138
-
139
- Args:
140
- - query (string): Search string to match against names/emails
141
- - limit (number): Maximum results to return, between 1-100 (default: 20)
142
- - offset (number): Number of results to skip for pagination (default: 0)
143
- - response_format ('markdown' | 'json'): Output format (default: 'markdown')
144
-
145
- Returns:
146
- For JSON format: Structured data with schema:
147
- {
148
- "total": number, // Total number of matches found
149
- "count": number, // Number of results in this response
150
- "offset": number, // Current pagination offset
151
- "users": [
152
- {
153
- "id": string, // User ID (e.g., "U123456789")
154
- "name": string, // Full name (e.g., "John Doe")
155
- "email": string, // Email address
156
- "team": string, // Team name (optional)
157
- "active": boolean // Whether user is active
158
- }
159
- ],
160
- "has_more": boolean, // Whether more results are available
161
- "next_offset": number // Offset for next page (if has_more is true)
162
- }
163
-
164
- Examples:
165
- - Use when: "Find all marketing team members" -> params with query="team:marketing"
166
- - Use when: "Search for John's account" -> params with query="john"
167
- - Don't use when: You need to create a user (use example_create_user instead)
168
-
169
- Error Handling:
170
- - Returns "Error: Rate limit exceeded" if too many requests (429 status)
171
- - Returns "No users found matching '<query>'" if search returns empty`,
172
- inputSchema: UserSearchInputSchema,
173
- annotations: {
174
- readOnlyHint: true,
175
- destructiveHint: false,
176
- idempotentHint: true,
177
- openWorldHint: true
178
- }
179
- },
180
- async (params: UserSearchInput) => {
181
- try {
182
- // Input validation is handled by Zod schema
183
- // Make API request using validated parameters
184
- const data = await makeApiRequest<any>(
185
- "users/search",
186
- "GET",
187
- undefined,
188
- {
189
- q: params.query,
190
- limit: params.limit,
191
- offset: params.offset
192
- }
193
- );
194
-
195
- const users = data.users || [];
196
- const total = data.total || 0;
197
-
198
- if (!users.length) {
199
- return {
200
- content: [{
201
- type: "text",
202
- text: `No users found matching '${params.query}'`
203
- }]
204
- };
205
- }
206
-
207
- // Format response based on requested format
208
- let result: string;
209
-
210
- if (params.response_format === ResponseFormat.MARKDOWN) {
211
- // Human-readable markdown format
212
- const lines: string[] = [`# User Search Results: '${params.query}'`, ""];
213
- lines.push(`Found ${total} users (showing ${users.length})`);
214
- lines.push("");
215
-
216
- for (const user of users) {
217
- lines.push(`## ${user.name} (${user.id})`);
218
- lines.push(`- **Email**: ${user.email}`);
219
- if (user.team) {
220
- lines.push(`- **Team**: ${user.team}`);
221
- }
222
- lines.push("");
223
- }
224
-
225
- result = lines.join("\n");
226
-
227
- } else {
228
- // Machine-readable JSON format
229
- const response: any = {
230
- total,
231
- count: users.length,
232
- offset: params.offset,
233
- users: users.map((user: any) => ({
234
- id: user.id,
235
- name: user.name,
236
- email: user.email,
237
- ...(user.team ? { team: user.team } : {}),
238
- active: user.active ?? true
239
- }))
240
- };
241
-
242
- // Add pagination info if there are more results
243
- if (total > params.offset + users.length) {
244
- response.has_more = true;
245
- response.next_offset = params.offset + users.length;
246
- }
247
-
248
- result = JSON.stringify(response, null, 2);
249
- }
250
-
251
- return {
252
- content: [{
253
- type: "text",
254
- text: result
255
- }]
256
- };
257
- } catch (error) {
258
- return {
259
- content: [{
260
- type: "text",
261
- text: handleApiError(error)
262
- }]
263
- };
264
- }
265
- }
266
- );
267
- ```
268
-
269
- ## Zod Schemas for Input Validation
270
-
271
- Zod provides runtime type validation:
272
-
273
- ```typescript
274
- import { z } from "zod";
275
-
276
- // Basic schema with validation
277
- const CreateUserSchema = z.object({
278
- name: z.string()
279
- .min(1, "Name is required")
280
- .max(100, "Name must not exceed 100 characters"),
281
- email: z.string()
282
- .email("Invalid email format"),
283
- age: z.number()
284
- .int("Age must be a whole number")
285
- .min(0, "Age cannot be negative")
286
- .max(150, "Age cannot be greater than 150")
287
- }).strict(); // Use .strict() to forbid extra fields
288
-
289
- // Enums
290
- enum ResponseFormat {
291
- MARKDOWN = "markdown",
292
- JSON = "json"
293
- }
294
-
295
- const SearchSchema = z.object({
296
- response_format: z.nativeEnum(ResponseFormat)
297
- .default(ResponseFormat.MARKDOWN)
298
- .describe("Output format")
299
- });
300
-
301
- // Optional fields with defaults
302
- const PaginationSchema = z.object({
303
- limit: z.number()
304
- .int()
305
- .min(1)
306
- .max(100)
307
- .default(20)
308
- .describe("Maximum results to return"),
309
- offset: z.number()
310
- .int()
311
- .min(0)
312
- .default(0)
313
- .describe("Number of results to skip")
314
- });
315
- ```
316
-
317
- ## Response Format Options
318
-
319
- Support multiple output formats for flexibility:
320
-
321
- ```typescript
322
- enum ResponseFormat {
323
- MARKDOWN = "markdown",
324
- JSON = "json"
325
- }
326
-
327
- const inputSchema = z.object({
328
- query: z.string(),
329
- response_format: z.nativeEnum(ResponseFormat)
330
- .default(ResponseFormat.MARKDOWN)
331
- .describe("Output format: 'markdown' for human-readable or 'json' for machine-readable")
332
- });
333
- ```
334
-
335
- **Markdown format**:
336
- - Use headers, lists, and formatting for clarity
337
- - Convert timestamps to human-readable format
338
- - Show display names with IDs in parentheses
339
- - Omit verbose metadata
340
- - Group related information logically
341
-
342
- **JSON format**:
343
- - Return complete, structured data suitable for programmatic processing
344
- - Include all available fields and metadata
345
- - Use consistent field names and types
346
-
347
- ## Pagination Implementation
348
-
349
- For tools that list resources:
350
-
351
- ```typescript
352
- const ListSchema = z.object({
353
- limit: z.number().int().min(1).max(100).default(20),
354
- offset: z.number().int().min(0).default(0)
355
- });
356
-
357
- async function listItems(params: z.infer<typeof ListSchema>) {
358
- const data = await apiRequest(params.limit, params.offset);
359
-
360
- const response = {
361
- total: data.total,
362
- count: data.items.length,
363
- offset: params.offset,
364
- items: data.items,
365
- has_more: data.total > params.offset + data.items.length,
366
- next_offset: data.total > params.offset + data.items.length
367
- ? params.offset + data.items.length
368
- : undefined
369
- };
370
-
371
- return JSON.stringify(response, null, 2);
372
- }
373
- ```
374
-
375
- ## Character Limits and Truncation
376
-
377
- Add a CHARACTER_LIMIT constant to prevent overwhelming responses:
378
-
379
- ```typescript
380
- // At module level in constants.ts
381
- export const CHARACTER_LIMIT = 25000; // Maximum response size in characters
382
-
383
- async function searchTool(params: SearchInput) {
384
- let result = generateResponse(data);
385
-
386
- // Check character limit and truncate if needed
387
- if (result.length > CHARACTER_LIMIT) {
388
- const truncatedData = data.slice(0, Math.max(1, data.length / 2));
389
- response.data = truncatedData;
390
- response.truncated = true;
391
- response.truncation_message =
392
- `Response truncated from ${data.length} to ${truncatedData.length} items. ` +
393
- `Use 'offset' parameter or add filters to see more results.`;
394
- result = JSON.stringify(response, null, 2);
395
- }
396
-
397
- return result;
398
- }
399
- ```
400
-
401
- ## Error Handling
402
-
403
- Provide clear, actionable error messages:
404
-
405
- ```typescript
406
- import axios, { AxiosError } from "axios";
407
-
408
- function handleApiError(error: unknown): string {
409
- if (error instanceof AxiosError) {
410
- if (error.response) {
411
- switch (error.response.status) {
412
- case 404:
413
- return "Error: Resource not found. Please check the ID is correct.";
414
- case 403:
415
- return "Error: Permission denied. You don't have access to this resource.";
416
- case 429:
417
- return "Error: Rate limit exceeded. Please wait before making more requests.";
418
- default:
419
- return `Error: API request failed with status ${error.response.status}`;
420
- }
421
- } else if (error.code === "ECONNABORTED") {
422
- return "Error: Request timed out. Please try again.";
423
- }
424
- }
425
- return `Error: Unexpected error occurred: ${error instanceof Error ? error.message : String(error)}`;
426
- }
427
- ```
428
-
429
- ## Shared Utilities
430
-
431
- Extract common functionality into reusable functions:
432
-
433
- ```typescript
434
- // Shared API request function
435
- async function makeApiRequest<T>(
436
- endpoint: string,
437
- method: "GET" | "POST" | "PUT" | "DELETE" = "GET",
438
- data?: any,
439
- params?: any
440
- ): Promise<T> {
441
- try {
442
- const response = await axios({
443
- method,
444
- url: `${API_BASE_URL}/${endpoint}`,
445
- data,
446
- params,
447
- timeout: 30000,
448
- headers: {
449
- "Content-Type": "application/json",
450
- "Accept": "application/json"
451
- }
452
- });
453
- return response.data;
454
- } catch (error) {
455
- throw error;
456
- }
457
- }
458
- ```
459
-
460
- ## Async/Await Best Practices
461
-
462
- Always use async/await for network requests and I/O operations:
463
-
464
- ```typescript
465
- // Good: Async network request
466
- async function fetchData(resourceId: string): Promise<ResourceData> {
467
- const response = await axios.get(`${API_URL}/resource/${resourceId}`);
468
- return response.data;
469
- }
470
-
471
- // Bad: Promise chains
472
- function fetchData(resourceId: string): Promise<ResourceData> {
473
- return axios.get(`${API_URL}/resource/${resourceId}`)
474
- .then(response => response.data); // Harder to read and maintain
475
- }
476
- ```
477
-
478
- ## TypeScript Best Practices
479
-
480
- 1. **Use Strict TypeScript**: Enable strict mode in tsconfig.json
481
- 2. **Define Interfaces**: Create clear interface definitions for all data structures
482
- 3. **Avoid `any`**: Use proper types or `unknown` instead of `any`
483
- 4. **Zod for Runtime Validation**: Use Zod schemas to validate external data
484
- 5. **Type Guards**: Create type guard functions for complex type checking
485
- 6. **Error Handling**: Always use try-catch with proper error type checking
486
- 7. **Null Safety**: Use optional chaining (`?.`) and nullish coalescing (`??`)
487
-
488
- ```typescript
489
- // Good: Type-safe with Zod and interfaces
490
- interface UserResponse {
491
- id: string;
492
- name: string;
493
- email: string;
494
- team?: string;
495
- active: boolean;
496
- }
497
-
498
- const UserSchema = z.object({
499
- id: z.string(),
500
- name: z.string(),
501
- email: z.string().email(),
502
- team: z.string().optional(),
503
- active: z.boolean()
504
- });
505
-
506
- type User = z.infer<typeof UserSchema>;
507
-
508
- async function getUser(id: string): Promise<User> {
509
- const data = await apiCall(`/users/${id}`);
510
- return UserSchema.parse(data); // Runtime validation
511
- }
512
-
513
- // Bad: Using any
514
- async function getUser(id: string): Promise<any> {
515
- return await apiCall(`/users/${id}`); // No type safety
516
- }
517
- ```
518
-
519
- ## Package Configuration
520
-
521
- ### package.json
522
-
523
- ```json
524
- {
525
- "name": "{service}-mcp-server",
526
- "version": "1.0.0",
527
- "description": "MCP server for {Service} API integration",
528
- "type": "module",
529
- "main": "dist/index.js",
530
- "scripts": {
531
- "start": "node dist/index.js",
532
- "dev": "tsx watch src/index.ts",
533
- "build": "tsc",
534
- "clean": "rm -rf dist"
535
- },
536
- "engines": {
537
- "node": ">=18"
538
- },
539
- "dependencies": {
540
- "@modelcontextprotocol/sdk": "^1.6.1",
541
- "axios": "^1.7.9",
542
- "zod": "^3.23.8"
543
- },
544
- "devDependencies": {
545
- "@types/node": "^22.10.0",
546
- "tsx": "^4.19.2",
547
- "typescript": "^5.7.2"
548
- }
549
- }
550
- ```
551
-
552
- ### tsconfig.json
553
-
554
- ```json
555
- {
556
- "compilerOptions": {
557
- "target": "ES2022",
558
- "module": "Node16",
559
- "moduleResolution": "Node16",
560
- "lib": ["ES2022"],
561
- "outDir": "./dist",
562
- "rootDir": "./src",
563
- "strict": true,
564
- "esModuleInterop": true,
565
- "skipLibCheck": true,
566
- "forceConsistentCasingInFileNames": true,
567
- "declaration": true,
568
- "declarationMap": true,
569
- "sourceMap": true,
570
- "allowSyntheticDefaultImports": true
571
- },
572
- "include": ["src/**/*"],
573
- "exclude": ["node_modules", "dist"]
574
- }
575
- ```
576
-
577
- ## Complete Example
578
-
579
- ```typescript
580
- #!/usr/bin/env node
581
- /**
582
- * MCP Server for Example Service.
583
- *
584
- * This server provides tools to interact with Example API, including user search,
585
- * project management, and data export capabilities.
586
- */
587
-
588
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
589
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
590
- import { z } from "zod";
591
- import axios, { AxiosError } from "axios";
592
-
593
- // Constants
594
- const API_BASE_URL = "https://api.example.com/v1";
595
- const CHARACTER_LIMIT = 25000;
596
-
597
- // Enums
598
- enum ResponseFormat {
599
- MARKDOWN = "markdown",
600
- JSON = "json"
601
- }
602
-
603
- // Zod schemas
604
- const UserSearchInputSchema = z.object({
605
- query: z.string()
606
- .min(2, "Query must be at least 2 characters")
607
- .max(200, "Query must not exceed 200 characters")
608
- .describe("Search string to match against names/emails"),
609
- limit: z.number()
610
- .int()
611
- .min(1)
612
- .max(100)
613
- .default(20)
614
- .describe("Maximum results to return"),
615
- offset: z.number()
616
- .int()
617
- .min(0)
618
- .default(0)
619
- .describe("Number of results to skip for pagination"),
620
- response_format: z.nativeEnum(ResponseFormat)
621
- .default(ResponseFormat.MARKDOWN)
622
- .describe("Output format: 'markdown' for human-readable or 'json' for machine-readable")
623
- }).strict();
624
-
625
- type UserSearchInput = z.infer<typeof UserSearchInputSchema>;
626
-
627
- // Shared utility functions
628
- async function makeApiRequest<T>(
629
- endpoint: string,
630
- method: "GET" | "POST" | "PUT" | "DELETE" = "GET",
631
- data?: any,
632
- params?: any
633
- ): Promise<T> {
634
- try {
635
- const response = await axios({
636
- method,
637
- url: `${API_BASE_URL}/${endpoint}`,
638
- data,
639
- params,
640
- timeout: 30000,
641
- headers: {
642
- "Content-Type": "application/json",
643
- "Accept": "application/json"
644
- }
645
- });
646
- return response.data;
647
- } catch (error) {
648
- throw error;
649
- }
650
- }
651
-
652
- function handleApiError(error: unknown): string {
653
- if (error instanceof AxiosError) {
654
- if (error.response) {
655
- switch (error.response.status) {
656
- case 404:
657
- return "Error: Resource not found. Please check the ID is correct.";
658
- case 403:
659
- return "Error: Permission denied. You don't have access to this resource.";
660
- case 429:
661
- return "Error: Rate limit exceeded. Please wait before making more requests.";
662
- default:
663
- return `Error: API request failed with status ${error.response.status}`;
664
- }
665
- } else if (error.code === "ECONNABORTED") {
666
- return "Error: Request timed out. Please try again.";
667
- }
668
- }
669
- return `Error: Unexpected error occurred: ${error instanceof Error ? error.message : String(error)}`;
670
- }
671
-
672
- // Create MCP server instance
673
- const server = new McpServer({
674
- name: "example-mcp",
675
- version: "1.0.0"
676
- });
677
-
678
- // Register tools
679
- server.registerTool(
680
- "example_search_users",
681
- {
682
- title: "Search Example Users",
683
- description: `[Full description as shown above]`,
684
- inputSchema: UserSearchInputSchema,
685
- annotations: {
686
- readOnlyHint: true,
687
- destructiveHint: false,
688
- idempotentHint: true,
689
- openWorldHint: true
690
- }
691
- },
692
- async (params: UserSearchInput) => {
693
- // Implementation as shown above
694
- }
695
- );
696
-
697
- // Main function
698
- async function main() {
699
- // Verify environment variables if needed
700
- if (!process.env.EXAMPLE_API_KEY) {
701
- console.error("ERROR: EXAMPLE_API_KEY environment variable is required");
702
- process.exit(1);
703
- }
704
-
705
- // Create transport
706
- const transport = new StdioServerTransport();
707
-
708
- // Connect server to transport
709
- await server.connect(transport);
710
-
711
- console.error("Example MCP server running via stdio");
712
- }
713
-
714
- // Run the server
715
- main().catch((error) => {
716
- console.error("Server error:", error);
717
- process.exit(1);
718
- });
719
- ```
720
-
721
- ---
722
-
723
- ## Advanced MCP Features
724
-
725
- ### Resource Registration
726
-
727
- Expose data as resources for efficient, URI-based access:
728
-
729
- ```typescript
730
- import { ResourceTemplate } from "@modelcontextprotocol/sdk/types.js";
731
-
732
- // Register a resource with URI template
733
- server.registerResource(
734
- {
735
- uri: "file://documents/{name}",
736
- name: "Document Resource",
737
- description: "Access documents by name",
738
- mimeType: "text/plain"
739
- },
740
- async (uri: string) => {
741
- // Extract parameter from URI
742
- const match = uri.match(/^file:\/\/documents\/(.+)$/);
743
- if (!match) {
744
- throw new Error("Invalid URI format");
745
- }
746
-
747
- const documentName = match[1];
748
- const content = await loadDocument(documentName);
749
-
750
- return {
751
- contents: [{
752
- uri,
753
- mimeType: "text/plain",
754
- text: content
755
- }]
756
- };
757
- }
758
- );
759
-
760
- // List available resources dynamically
761
- server.registerResourceList(async () => {
762
- const documents = await getAvailableDocuments();
763
- return {
764
- resources: documents.map(doc => ({
765
- uri: `file://documents/${doc.name}`,
766
- name: doc.name,
767
- mimeType: "text/plain",
768
- description: doc.description
769
- }))
770
- };
771
- });
772
- ```
773
-
774
- **When to use Resources vs Tools:**
775
- - **Resources**: For data access with simple URI-based parameters
776
- - **Tools**: For complex operations requiring validation and business logic
777
- - **Resources**: When data is relatively static or template-based
778
- - **Tools**: When operations have side effects or complex workflows
779
-
780
- ### Multiple Transport Options
781
-
782
- The TypeScript SDK supports different transport mechanisms:
783
-
784
- ```typescript
785
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
786
- import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
787
-
788
- // Stdio transport (default - for CLI tools)
789
- const stdioTransport = new StdioServerTransport();
790
- await server.connect(stdioTransport);
791
-
792
- // SSE transport (for real-time web updates)
793
- const sseTransport = new SSEServerTransport("/message", response);
794
- await server.connect(sseTransport);
795
-
796
- // HTTP transport (for web services)
797
- // Configure based on your HTTP framework integration
798
- ```
799
-
800
- **Transport selection guide:**
801
- - **Stdio**: Command-line tools, subprocess integration, local development
802
- - **HTTP**: Web services, remote access, multiple simultaneous clients
803
- - **SSE**: Real-time updates, server-push notifications, web dashboards
804
-
805
- ### Notification Support
806
-
807
- Notify clients when server state changes:
808
-
809
- ```typescript
810
- // Notify when tools list changes
811
- server.notification({
812
- method: "notifications/tools/list_changed"
813
- });
814
-
815
- // Notify when resources change
816
- server.notification({
817
- method: "notifications/resources/list_changed"
818
- });
819
- ```
820
-
821
- Use notifications sparingly - only when server capabilities genuinely change.
822
-
823
- ---
824
-
825
- ## Code Best Practices
826
-
827
- ### Code Composability and Reusability
828
-
829
- Your implementation MUST prioritize composability and code reuse:
830
-
831
- 1. **Extract Common Functionality**:
832
- - Create reusable helper functions for operations used across multiple tools
833
- - Build shared API clients for HTTP requests instead of duplicating code
834
- - Centralize error handling logic in utility functions
835
- - Extract business logic into dedicated functions that can be composed
836
- - Extract shared markdown or JSON field selection & formatting functionality
837
-
838
- 2. **Avoid Duplication**:
839
- - NEVER copy-paste similar code between tools
840
- - If you find yourself writing similar logic twice, extract it into a function
841
- - Common operations like pagination, filtering, field selection, and formatting should be shared
842
- - Authentication/authorization logic should be centralized
843
-
844
- ## Building and Running
845
-
846
- Always build your TypeScript code before running:
847
-
848
- ```bash
849
- # Build the project
850
- npm run build
851
-
852
- # Run the server
853
- npm start
854
-
855
- # Development with auto-reload
856
- npm run dev
857
- ```
858
-
859
- Always ensure `npm run build` completes successfully before considering the implementation complete.
860
-
861
- ## Quality Checklist
862
-
863
- Before finalizing your Node/TypeScript MCP server implementation, ensure:
864
-
865
- ### Strategic Design
866
- - [ ] Tools enable complete workflows, not just API endpoint wrappers
867
- - [ ] Tool names reflect natural task subdivisions
868
- - [ ] Response formats optimize for agent context efficiency
869
- - [ ] Human-readable identifiers used where appropriate
870
- - [ ] Error messages guide agents toward correct usage
871
-
872
- ### Implementation Quality
873
- - [ ] FOCUSED IMPLEMENTATION: Most important and valuable tools implemented
874
- - [ ] All tools registered using `registerTool` with complete configuration
875
- - [ ] All tools include `title`, `description`, `inputSchema`, and `annotations`
876
- - [ ] Annotations correctly set (readOnlyHint, destructiveHint, idempotentHint, openWorldHint)
877
- - [ ] All tools use Zod schemas for runtime input validation with `.strict()` enforcement
878
- - [ ] All Zod schemas have proper constraints and descriptive error messages
879
- - [ ] All tools have comprehensive descriptions with explicit input/output types
880
- - [ ] Descriptions include return value examples and complete schema documentation
881
- - [ ] Error messages are clear, actionable, and educational
882
-
883
- ### TypeScript Quality
884
- - [ ] TypeScript interfaces are defined for all data structures
885
- - [ ] Strict TypeScript is enabled in tsconfig.json
886
- - [ ] No use of `any` type - use `unknown` or proper types instead
887
- - [ ] All async functions have explicit Promise<T> return types
888
- - [ ] Error handling uses proper type guards (e.g., `axios.isAxiosError`, `z.ZodError`)
889
-
890
- ### Advanced Features (where applicable)
891
- - [ ] Resources registered for appropriate data endpoints
892
- - [ ] Appropriate transport configured (stdio, HTTP, SSE)
893
- - [ ] Notifications implemented for dynamic server capabilities
894
- - [ ] Type-safe with SDK interfaces
895
-
896
- ### Project Configuration
897
- - [ ] Package.json includes all necessary dependencies
898
- - [ ] Build script produces working JavaScript in dist/ directory
899
- - [ ] Main entry point is properly configured as dist/index.js
900
- - [ ] Server name follows format: `{service}-mcp-server`
901
- - [ ] tsconfig.json properly configured with strict mode
902
-
903
- ### Code Quality
904
- - [ ] Pagination is properly implemented where applicable
905
- - [ ] Large responses check CHARACTER_LIMIT constant and truncate with clear messages
906
- - [ ] Filtering options are provided for potentially large result sets
907
- - [ ] All network operations handle timeouts and connection errors gracefully
908
- - [ ] Common functionality is extracted into reusable functions
909
- - [ ] Return types are consistent across similar operations
910
-
911
- ### Testing and Build
912
- - [ ] `npm run build` completes successfully without errors
913
- - [ ] dist/index.js created and executable
914
- - [ ] Server runs: `node dist/index.js --help`
915
- - [ ] All imports resolve correctly
1
+ # Node/TypeScript MCP Server Implementation Guide
2
+
3
+ ## Overview
4
+
5
+ This document provides Node/TypeScript-specific best practices and examples for implementing MCP servers using the MCP TypeScript SDK. It covers project structure, server setup, tool registration patterns, input validation with Zod, error handling, and complete working examples.
6
+
7
+ ---
8
+
9
+ ## Quick Reference
10
+
11
+ ### Key Imports
12
+ ```typescript
13
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
14
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
15
+ import { z } from "zod";
16
+ import axios, { AxiosError } from "axios";
17
+ ```
18
+
19
+ ### Server Initialization
20
+ ```typescript
21
+ const server = new McpServer({
22
+ name: "service-mcp-server",
23
+ version: "1.0.0"
24
+ });
25
+ ```
26
+
27
+ ### Tool Registration Pattern
28
+ ```typescript
29
+ server.registerTool("tool_name", {...config}, async (params) => {
30
+ // Implementation
31
+ });
32
+ ```
33
+
34
+ ---
35
+
36
+ ## MCP TypeScript SDK
37
+
38
+ The official MCP TypeScript SDK provides:
39
+ - `McpServer` class for server initialization
40
+ - `registerTool` method for tool registration
41
+ - Zod schema integration for runtime input validation
42
+ - Type-safe tool handler implementations
43
+
44
+ See the MCP SDK documentation in the references for complete details.
45
+
46
+ ## Server Naming Convention
47
+
48
+ Node/TypeScript MCP servers must follow this naming pattern:
49
+ - **Format**: `{service}-mcp-server` (lowercase with hyphens)
50
+ - **Examples**: `github-mcp-server`, `jira-mcp-server`, `stripe-mcp-server`
51
+
52
+ The name should be:
53
+ - General (not tied to specific features)
54
+ - Descriptive of the service/API being integrated
55
+ - Easy to infer from the task description
56
+ - Without version numbers or dates
57
+
58
+ ## Project Structure
59
+
60
+ Create the following structure for Node/TypeScript MCP servers:
61
+
62
+ ```
63
+ {service}-mcp-server/
64
+ ├── package.json
65
+ ├── tsconfig.json
66
+ ├── README.md
67
+ ├── src/
68
+ │ ├── index.ts # Main entry point with McpServer initialization
69
+ │ ├── types.ts # TypeScript type definitions and interfaces
70
+ │ ├── tools/ # Tool implementations (one file per domain)
71
+ │ ├── services/ # API clients and shared utilities
72
+ │ ├── schemas/ # Zod validation schemas
73
+ │ └── constants.ts # Shared constants (API_URL, CHARACTER_LIMIT, etc.)
74
+ └── dist/ # Built JavaScript files (entry point: dist/index.js)
75
+ ```
76
+
77
+ ## Tool Implementation
78
+
79
+ ### Tool Naming
80
+
81
+ Use snake_case for tool names (e.g., "search_users", "create_project", "get_channel_info") with clear, action-oriented names.
82
+
83
+ **Avoid Naming Conflicts**: Include the service context to prevent overlaps:
84
+ - Use "slack_send_message" instead of just "send_message"
85
+ - Use "github_create_issue" instead of just "create_issue"
86
+ - Use "asana_list_tasks" instead of just "list_tasks"
87
+
88
+ ### Tool Structure
89
+
90
+ Tools are registered using the `registerTool` method with the following requirements:
91
+ - Use Zod schemas for runtime input validation and type safety
92
+ - The `description` field must be explicitly provided - JSDoc comments are NOT automatically extracted
93
+ - Explicitly provide `title`, `description`, `inputSchema`, and `annotations`
94
+ - The `inputSchema` must be a Zod schema object (not a JSON schema)
95
+ - Type all parameters and return values explicitly
96
+
97
+ ```typescript
98
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
99
+ import { z } from "zod";
100
+
101
+ const server = new McpServer({
102
+ name: "example-mcp",
103
+ version: "1.0.0"
104
+ });
105
+
106
+ // Zod schema for input validation
107
+ const UserSearchInputSchema = z.object({
108
+ query: z.string()
109
+ .min(2, "Query must be at least 2 characters")
110
+ .max(200, "Query must not exceed 200 characters")
111
+ .describe("Search string to match against names/emails"),
112
+ limit: z.number()
113
+ .int()
114
+ .min(1)
115
+ .max(100)
116
+ .default(20)
117
+ .describe("Maximum results to return"),
118
+ offset: z.number()
119
+ .int()
120
+ .min(0)
121
+ .default(0)
122
+ .describe("Number of results to skip for pagination"),
123
+ response_format: z.nativeEnum(ResponseFormat)
124
+ .default(ResponseFormat.MARKDOWN)
125
+ .describe("Output format: 'markdown' for human-readable or 'json' for machine-readable")
126
+ }).strict();
127
+
128
+ // Type definition from Zod schema
129
+ type UserSearchInput = z.infer<typeof UserSearchInputSchema>;
130
+
131
+ server.registerTool(
132
+ "example_search_users",
133
+ {
134
+ title: "Search Example Users",
135
+ description: `Search for users in the Example system by name, email, or team.
136
+
137
+ This tool searches across all user profiles in the Example platform, supporting partial matches and various search filters. It does NOT create or modify users, only searches existing ones.
138
+
139
+ Args:
140
+ - query (string): Search string to match against names/emails
141
+ - limit (number): Maximum results to return, between 1-100 (default: 20)
142
+ - offset (number): Number of results to skip for pagination (default: 0)
143
+ - response_format ('markdown' | 'json'): Output format (default: 'markdown')
144
+
145
+ Returns:
146
+ For JSON format: Structured data with schema:
147
+ {
148
+ "total": number, // Total number of matches found
149
+ "count": number, // Number of results in this response
150
+ "offset": number, // Current pagination offset
151
+ "users": [
152
+ {
153
+ "id": string, // User ID (e.g., "U123456789")
154
+ "name": string, // Full name (e.g., "John Doe")
155
+ "email": string, // Email address
156
+ "team": string, // Team name (optional)
157
+ "active": boolean // Whether user is active
158
+ }
159
+ ],
160
+ "has_more": boolean, // Whether more results are available
161
+ "next_offset": number // Offset for next page (if has_more is true)
162
+ }
163
+
164
+ Examples:
165
+ - Use when: "Find all marketing team members" -> params with query="team:marketing"
166
+ - Use when: "Search for John's account" -> params with query="john"
167
+ - Don't use when: You need to create a user (use example_create_user instead)
168
+
169
+ Error Handling:
170
+ - Returns "Error: Rate limit exceeded" if too many requests (429 status)
171
+ - Returns "No users found matching '<query>'" if search returns empty`,
172
+ inputSchema: UserSearchInputSchema,
173
+ annotations: {
174
+ readOnlyHint: true,
175
+ destructiveHint: false,
176
+ idempotentHint: true,
177
+ openWorldHint: true
178
+ }
179
+ },
180
+ async (params: UserSearchInput) => {
181
+ try {
182
+ // Input validation is handled by Zod schema
183
+ // Make API request using validated parameters
184
+ const data = await makeApiRequest<any>(
185
+ "users/search",
186
+ "GET",
187
+ undefined,
188
+ {
189
+ q: params.query,
190
+ limit: params.limit,
191
+ offset: params.offset
192
+ }
193
+ );
194
+
195
+ const users = data.users || [];
196
+ const total = data.total || 0;
197
+
198
+ if (!users.length) {
199
+ return {
200
+ content: [{
201
+ type: "text",
202
+ text: `No users found matching '${params.query}'`
203
+ }]
204
+ };
205
+ }
206
+
207
+ // Format response based on requested format
208
+ let result: string;
209
+
210
+ if (params.response_format === ResponseFormat.MARKDOWN) {
211
+ // Human-readable markdown format
212
+ const lines: string[] = [`# User Search Results: '${params.query}'`, ""];
213
+ lines.push(`Found ${total} users (showing ${users.length})`);
214
+ lines.push("");
215
+
216
+ for (const user of users) {
217
+ lines.push(`## ${user.name} (${user.id})`);
218
+ lines.push(`- **Email**: ${user.email}`);
219
+ if (user.team) {
220
+ lines.push(`- **Team**: ${user.team}`);
221
+ }
222
+ lines.push("");
223
+ }
224
+
225
+ result = lines.join("\n");
226
+
227
+ } else {
228
+ // Machine-readable JSON format
229
+ const response: any = {
230
+ total,
231
+ count: users.length,
232
+ offset: params.offset,
233
+ users: users.map((user: any) => ({
234
+ id: user.id,
235
+ name: user.name,
236
+ email: user.email,
237
+ ...(user.team ? { team: user.team } : {}),
238
+ active: user.active ?? true
239
+ }))
240
+ };
241
+
242
+ // Add pagination info if there are more results
243
+ if (total > params.offset + users.length) {
244
+ response.has_more = true;
245
+ response.next_offset = params.offset + users.length;
246
+ }
247
+
248
+ result = JSON.stringify(response, null, 2);
249
+ }
250
+
251
+ return {
252
+ content: [{
253
+ type: "text",
254
+ text: result
255
+ }]
256
+ };
257
+ } catch (error) {
258
+ return {
259
+ content: [{
260
+ type: "text",
261
+ text: handleApiError(error)
262
+ }]
263
+ };
264
+ }
265
+ }
266
+ );
267
+ ```
268
+
269
+ ## Zod Schemas for Input Validation
270
+
271
+ Zod provides runtime type validation:
272
+
273
+ ```typescript
274
+ import { z } from "zod";
275
+
276
+ // Basic schema with validation
277
+ const CreateUserSchema = z.object({
278
+ name: z.string()
279
+ .min(1, "Name is required")
280
+ .max(100, "Name must not exceed 100 characters"),
281
+ email: z.string()
282
+ .email("Invalid email format"),
283
+ age: z.number()
284
+ .int("Age must be a whole number")
285
+ .min(0, "Age cannot be negative")
286
+ .max(150, "Age cannot be greater than 150")
287
+ }).strict(); // Use .strict() to forbid extra fields
288
+
289
+ // Enums
290
+ enum ResponseFormat {
291
+ MARKDOWN = "markdown",
292
+ JSON = "json"
293
+ }
294
+
295
+ const SearchSchema = z.object({
296
+ response_format: z.nativeEnum(ResponseFormat)
297
+ .default(ResponseFormat.MARKDOWN)
298
+ .describe("Output format")
299
+ });
300
+
301
+ // Optional fields with defaults
302
+ const PaginationSchema = z.object({
303
+ limit: z.number()
304
+ .int()
305
+ .min(1)
306
+ .max(100)
307
+ .default(20)
308
+ .describe("Maximum results to return"),
309
+ offset: z.number()
310
+ .int()
311
+ .min(0)
312
+ .default(0)
313
+ .describe("Number of results to skip")
314
+ });
315
+ ```
316
+
317
+ ## Response Format Options
318
+
319
+ Support multiple output formats for flexibility:
320
+
321
+ ```typescript
322
+ enum ResponseFormat {
323
+ MARKDOWN = "markdown",
324
+ JSON = "json"
325
+ }
326
+
327
+ const inputSchema = z.object({
328
+ query: z.string(),
329
+ response_format: z.nativeEnum(ResponseFormat)
330
+ .default(ResponseFormat.MARKDOWN)
331
+ .describe("Output format: 'markdown' for human-readable or 'json' for machine-readable")
332
+ });
333
+ ```
334
+
335
+ **Markdown format**:
336
+ - Use headers, lists, and formatting for clarity
337
+ - Convert timestamps to human-readable format
338
+ - Show display names with IDs in parentheses
339
+ - Omit verbose metadata
340
+ - Group related information logically
341
+
342
+ **JSON format**:
343
+ - Return complete, structured data suitable for programmatic processing
344
+ - Include all available fields and metadata
345
+ - Use consistent field names and types
346
+
347
+ ## Pagination Implementation
348
+
349
+ For tools that list resources:
350
+
351
+ ```typescript
352
+ const ListSchema = z.object({
353
+ limit: z.number().int().min(1).max(100).default(20),
354
+ offset: z.number().int().min(0).default(0)
355
+ });
356
+
357
+ async function listItems(params: z.infer<typeof ListSchema>) {
358
+ const data = await apiRequest(params.limit, params.offset);
359
+
360
+ const response = {
361
+ total: data.total,
362
+ count: data.items.length,
363
+ offset: params.offset,
364
+ items: data.items,
365
+ has_more: data.total > params.offset + data.items.length,
366
+ next_offset: data.total > params.offset + data.items.length
367
+ ? params.offset + data.items.length
368
+ : undefined
369
+ };
370
+
371
+ return JSON.stringify(response, null, 2);
372
+ }
373
+ ```
374
+
375
+ ## Character Limits and Truncation
376
+
377
+ Add a CHARACTER_LIMIT constant to prevent overwhelming responses:
378
+
379
+ ```typescript
380
+ // At module level in constants.ts
381
+ export const CHARACTER_LIMIT = 25000; // Maximum response size in characters
382
+
383
+ async function searchTool(params: SearchInput) {
384
+ let result = generateResponse(data);
385
+
386
+ // Check character limit and truncate if needed
387
+ if (result.length > CHARACTER_LIMIT) {
388
+ const truncatedData = data.slice(0, Math.max(1, data.length / 2));
389
+ response.data = truncatedData;
390
+ response.truncated = true;
391
+ response.truncation_message =
392
+ `Response truncated from ${data.length} to ${truncatedData.length} items. ` +
393
+ `Use 'offset' parameter or add filters to see more results.`;
394
+ result = JSON.stringify(response, null, 2);
395
+ }
396
+
397
+ return result;
398
+ }
399
+ ```
400
+
401
+ ## Error Handling
402
+
403
+ Provide clear, actionable error messages:
404
+
405
+ ```typescript
406
+ import axios, { AxiosError } from "axios";
407
+
408
+ function handleApiError(error: unknown): string {
409
+ if (error instanceof AxiosError) {
410
+ if (error.response) {
411
+ switch (error.response.status) {
412
+ case 404:
413
+ return "Error: Resource not found. Please check the ID is correct.";
414
+ case 403:
415
+ return "Error: Permission denied. You don't have access to this resource.";
416
+ case 429:
417
+ return "Error: Rate limit exceeded. Please wait before making more requests.";
418
+ default:
419
+ return `Error: API request failed with status ${error.response.status}`;
420
+ }
421
+ } else if (error.code === "ECONNABORTED") {
422
+ return "Error: Request timed out. Please try again.";
423
+ }
424
+ }
425
+ return `Error: Unexpected error occurred: ${error instanceof Error ? error.message : String(error)}`;
426
+ }
427
+ ```
428
+
429
+ ## Shared Utilities
430
+
431
+ Extract common functionality into reusable functions:
432
+
433
+ ```typescript
434
+ // Shared API request function
435
+ async function makeApiRequest<T>(
436
+ endpoint: string,
437
+ method: "GET" | "POST" | "PUT" | "DELETE" = "GET",
438
+ data?: any,
439
+ params?: any
440
+ ): Promise<T> {
441
+ try {
442
+ const response = await axios({
443
+ method,
444
+ url: `${API_BASE_URL}/${endpoint}`,
445
+ data,
446
+ params,
447
+ timeout: 30000,
448
+ headers: {
449
+ "Content-Type": "application/json",
450
+ "Accept": "application/json"
451
+ }
452
+ });
453
+ return response.data;
454
+ } catch (error) {
455
+ throw error;
456
+ }
457
+ }
458
+ ```
459
+
460
+ ## Async/Await Best Practices
461
+
462
+ Always use async/await for network requests and I/O operations:
463
+
464
+ ```typescript
465
+ // Good: Async network request
466
+ async function fetchData(resourceId: string): Promise<ResourceData> {
467
+ const response = await axios.get(`${API_URL}/resource/${resourceId}`);
468
+ return response.data;
469
+ }
470
+
471
+ // Bad: Promise chains
472
+ function fetchData(resourceId: string): Promise<ResourceData> {
473
+ return axios.get(`${API_URL}/resource/${resourceId}`)
474
+ .then(response => response.data); // Harder to read and maintain
475
+ }
476
+ ```
477
+
478
+ ## TypeScript Best Practices
479
+
480
+ 1. **Use Strict TypeScript**: Enable strict mode in tsconfig.json
481
+ 2. **Define Interfaces**: Create clear interface definitions for all data structures
482
+ 3. **Avoid `any`**: Use proper types or `unknown` instead of `any`
483
+ 4. **Zod for Runtime Validation**: Use Zod schemas to validate external data
484
+ 5. **Type Guards**: Create type guard functions for complex type checking
485
+ 6. **Error Handling**: Always use try-catch with proper error type checking
486
+ 7. **Null Safety**: Use optional chaining (`?.`) and nullish coalescing (`??`)
487
+
488
+ ```typescript
489
+ // Good: Type-safe with Zod and interfaces
490
+ interface UserResponse {
491
+ id: string;
492
+ name: string;
493
+ email: string;
494
+ team?: string;
495
+ active: boolean;
496
+ }
497
+
498
+ const UserSchema = z.object({
499
+ id: z.string(),
500
+ name: z.string(),
501
+ email: z.string().email(),
502
+ team: z.string().optional(),
503
+ active: z.boolean()
504
+ });
505
+
506
+ type User = z.infer<typeof UserSchema>;
507
+
508
+ async function getUser(id: string): Promise<User> {
509
+ const data = await apiCall(`/users/${id}`);
510
+ return UserSchema.parse(data); // Runtime validation
511
+ }
512
+
513
+ // Bad: Using any
514
+ async function getUser(id: string): Promise<any> {
515
+ return await apiCall(`/users/${id}`); // No type safety
516
+ }
517
+ ```
518
+
519
+ ## Package Configuration
520
+
521
+ ### package.json
522
+
523
+ ```json
524
+ {
525
+ "name": "{service}-mcp-server",
526
+ "version": "1.0.0",
527
+ "description": "MCP server for {Service} API integration",
528
+ "type": "module",
529
+ "main": "dist/index.js",
530
+ "scripts": {
531
+ "start": "node dist/index.js",
532
+ "dev": "tsx watch src/index.ts",
533
+ "build": "tsc",
534
+ "clean": "rm -rf dist"
535
+ },
536
+ "engines": {
537
+ "node": ">=18"
538
+ },
539
+ "dependencies": {
540
+ "@modelcontextprotocol/sdk": "^1.6.1",
541
+ "axios": "^1.7.9",
542
+ "zod": "^3.23.8"
543
+ },
544
+ "devDependencies": {
545
+ "@types/node": "^22.10.0",
546
+ "tsx": "^4.19.2",
547
+ "typescript": "^5.7.2"
548
+ }
549
+ }
550
+ ```
551
+
552
+ ### tsconfig.json
553
+
554
+ ```json
555
+ {
556
+ "compilerOptions": {
557
+ "target": "ES2022",
558
+ "module": "Node16",
559
+ "moduleResolution": "Node16",
560
+ "lib": ["ES2022"],
561
+ "outDir": "./dist",
562
+ "rootDir": "./src",
563
+ "strict": true,
564
+ "esModuleInterop": true,
565
+ "skipLibCheck": true,
566
+ "forceConsistentCasingInFileNames": true,
567
+ "declaration": true,
568
+ "declarationMap": true,
569
+ "sourceMap": true,
570
+ "allowSyntheticDefaultImports": true
571
+ },
572
+ "include": ["src/**/*"],
573
+ "exclude": ["node_modules", "dist"]
574
+ }
575
+ ```
576
+
577
+ ## Complete Example
578
+
579
+ ```typescript
580
+ #!/usr/bin/env node
581
+ /**
582
+ * MCP Server for Example Service.
583
+ *
584
+ * This server provides tools to interact with Example API, including user search,
585
+ * project management, and data export capabilities.
586
+ */
587
+
588
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
589
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
590
+ import { z } from "zod";
591
+ import axios, { AxiosError } from "axios";
592
+
593
+ // Constants
594
+ const API_BASE_URL = "https://api.example.com/v1";
595
+ const CHARACTER_LIMIT = 25000;
596
+
597
+ // Enums
598
+ enum ResponseFormat {
599
+ MARKDOWN = "markdown",
600
+ JSON = "json"
601
+ }
602
+
603
+ // Zod schemas
604
+ const UserSearchInputSchema = z.object({
605
+ query: z.string()
606
+ .min(2, "Query must be at least 2 characters")
607
+ .max(200, "Query must not exceed 200 characters")
608
+ .describe("Search string to match against names/emails"),
609
+ limit: z.number()
610
+ .int()
611
+ .min(1)
612
+ .max(100)
613
+ .default(20)
614
+ .describe("Maximum results to return"),
615
+ offset: z.number()
616
+ .int()
617
+ .min(0)
618
+ .default(0)
619
+ .describe("Number of results to skip for pagination"),
620
+ response_format: z.nativeEnum(ResponseFormat)
621
+ .default(ResponseFormat.MARKDOWN)
622
+ .describe("Output format: 'markdown' for human-readable or 'json' for machine-readable")
623
+ }).strict();
624
+
625
+ type UserSearchInput = z.infer<typeof UserSearchInputSchema>;
626
+
627
+ // Shared utility functions
628
+ async function makeApiRequest<T>(
629
+ endpoint: string,
630
+ method: "GET" | "POST" | "PUT" | "DELETE" = "GET",
631
+ data?: any,
632
+ params?: any
633
+ ): Promise<T> {
634
+ try {
635
+ const response = await axios({
636
+ method,
637
+ url: `${API_BASE_URL}/${endpoint}`,
638
+ data,
639
+ params,
640
+ timeout: 30000,
641
+ headers: {
642
+ "Content-Type": "application/json",
643
+ "Accept": "application/json"
644
+ }
645
+ });
646
+ return response.data;
647
+ } catch (error) {
648
+ throw error;
649
+ }
650
+ }
651
+
652
+ function handleApiError(error: unknown): string {
653
+ if (error instanceof AxiosError) {
654
+ if (error.response) {
655
+ switch (error.response.status) {
656
+ case 404:
657
+ return "Error: Resource not found. Please check the ID is correct.";
658
+ case 403:
659
+ return "Error: Permission denied. You don't have access to this resource.";
660
+ case 429:
661
+ return "Error: Rate limit exceeded. Please wait before making more requests.";
662
+ default:
663
+ return `Error: API request failed with status ${error.response.status}`;
664
+ }
665
+ } else if (error.code === "ECONNABORTED") {
666
+ return "Error: Request timed out. Please try again.";
667
+ }
668
+ }
669
+ return `Error: Unexpected error occurred: ${error instanceof Error ? error.message : String(error)}`;
670
+ }
671
+
672
+ // Create MCP server instance
673
+ const server = new McpServer({
674
+ name: "example-mcp",
675
+ version: "1.0.0"
676
+ });
677
+
678
+ // Register tools
679
+ server.registerTool(
680
+ "example_search_users",
681
+ {
682
+ title: "Search Example Users",
683
+ description: `[Full description as shown above]`,
684
+ inputSchema: UserSearchInputSchema,
685
+ annotations: {
686
+ readOnlyHint: true,
687
+ destructiveHint: false,
688
+ idempotentHint: true,
689
+ openWorldHint: true
690
+ }
691
+ },
692
+ async (params: UserSearchInput) => {
693
+ // Implementation as shown above
694
+ }
695
+ );
696
+
697
+ // Main function
698
+ async function main() {
699
+ // Verify environment variables if needed
700
+ if (!process.env.EXAMPLE_API_KEY) {
701
+ console.error("ERROR: EXAMPLE_API_KEY environment variable is required");
702
+ process.exit(1);
703
+ }
704
+
705
+ // Create transport
706
+ const transport = new StdioServerTransport();
707
+
708
+ // Connect server to transport
709
+ await server.connect(transport);
710
+
711
+ console.error("Example MCP server running via stdio");
712
+ }
713
+
714
+ // Run the server
715
+ main().catch((error) => {
716
+ console.error("Server error:", error);
717
+ process.exit(1);
718
+ });
719
+ ```
720
+
721
+ ---
722
+
723
+ ## Advanced MCP Features
724
+
725
+ ### Resource Registration
726
+
727
+ Expose data as resources for efficient, URI-based access:
728
+
729
+ ```typescript
730
+ import { ResourceTemplate } from "@modelcontextprotocol/sdk/types.js";
731
+
732
+ // Register a resource with URI template
733
+ server.registerResource(
734
+ {
735
+ uri: "file://documents/{name}",
736
+ name: "Document Resource",
737
+ description: "Access documents by name",
738
+ mimeType: "text/plain"
739
+ },
740
+ async (uri: string) => {
741
+ // Extract parameter from URI
742
+ const match = uri.match(/^file:\/\/documents\/(.+)$/);
743
+ if (!match) {
744
+ throw new Error("Invalid URI format");
745
+ }
746
+
747
+ const documentName = match[1];
748
+ const content = await loadDocument(documentName);
749
+
750
+ return {
751
+ contents: [{
752
+ uri,
753
+ mimeType: "text/plain",
754
+ text: content
755
+ }]
756
+ };
757
+ }
758
+ );
759
+
760
+ // List available resources dynamically
761
+ server.registerResourceList(async () => {
762
+ const documents = await getAvailableDocuments();
763
+ return {
764
+ resources: documents.map(doc => ({
765
+ uri: `file://documents/${doc.name}`,
766
+ name: doc.name,
767
+ mimeType: "text/plain",
768
+ description: doc.description
769
+ }))
770
+ };
771
+ });
772
+ ```
773
+
774
+ **When to use Resources vs Tools:**
775
+ - **Resources**: For data access with simple URI-based parameters
776
+ - **Tools**: For complex operations requiring validation and business logic
777
+ - **Resources**: When data is relatively static or template-based
778
+ - **Tools**: When operations have side effects or complex workflows
779
+
780
+ ### Multiple Transport Options
781
+
782
+ The TypeScript SDK supports different transport mechanisms:
783
+
784
+ ```typescript
785
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
786
+ import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
787
+
788
+ // Stdio transport (default - for CLI tools)
789
+ const stdioTransport = new StdioServerTransport();
790
+ await server.connect(stdioTransport);
791
+
792
+ // SSE transport (for real-time web updates)
793
+ const sseTransport = new SSEServerTransport("/message", response);
794
+ await server.connect(sseTransport);
795
+
796
+ // HTTP transport (for web services)
797
+ // Configure based on your HTTP framework integration
798
+ ```
799
+
800
+ **Transport selection guide:**
801
+ - **Stdio**: Command-line tools, subprocess integration, local development
802
+ - **HTTP**: Web services, remote access, multiple simultaneous clients
803
+ - **SSE**: Real-time updates, server-push notifications, web dashboards
804
+
805
+ ### Notification Support
806
+
807
+ Notify clients when server state changes:
808
+
809
+ ```typescript
810
+ // Notify when tools list changes
811
+ server.notification({
812
+ method: "notifications/tools/list_changed"
813
+ });
814
+
815
+ // Notify when resources change
816
+ server.notification({
817
+ method: "notifications/resources/list_changed"
818
+ });
819
+ ```
820
+
821
+ Use notifications sparingly - only when server capabilities genuinely change.
822
+
823
+ ---
824
+
825
+ ## Code Best Practices
826
+
827
+ ### Code Composability and Reusability
828
+
829
+ Your implementation MUST prioritize composability and code reuse:
830
+
831
+ 1. **Extract Common Functionality**:
832
+ - Create reusable helper functions for operations used across multiple tools
833
+ - Build shared API clients for HTTP requests instead of duplicating code
834
+ - Centralize error handling logic in utility functions
835
+ - Extract business logic into dedicated functions that can be composed
836
+ - Extract shared markdown or JSON field selection & formatting functionality
837
+
838
+ 2. **Avoid Duplication**:
839
+ - NEVER copy-paste similar code between tools
840
+ - If you find yourself writing similar logic twice, extract it into a function
841
+ - Common operations like pagination, filtering, field selection, and formatting should be shared
842
+ - Authentication/authorization logic should be centralized
843
+
844
+ ## Building and Running
845
+
846
+ Always build your TypeScript code before running:
847
+
848
+ ```bash
849
+ # Build the project
850
+ npm run build
851
+
852
+ # Run the server
853
+ npm start
854
+
855
+ # Development with auto-reload
856
+ npm run dev
857
+ ```
858
+
859
+ Always ensure `npm run build` completes successfully before considering the implementation complete.
860
+
861
+ ## Quality Checklist
862
+
863
+ Before finalizing your Node/TypeScript MCP server implementation, ensure:
864
+
865
+ ### Strategic Design
866
+ - [ ] Tools enable complete workflows, not just API endpoint wrappers
867
+ - [ ] Tool names reflect natural task subdivisions
868
+ - [ ] Response formats optimize for agent context efficiency
869
+ - [ ] Human-readable identifiers used where appropriate
870
+ - [ ] Error messages guide agents toward correct usage
871
+
872
+ ### Implementation Quality
873
+ - [ ] FOCUSED IMPLEMENTATION: Most important and valuable tools implemented
874
+ - [ ] All tools registered using `registerTool` with complete configuration
875
+ - [ ] All tools include `title`, `description`, `inputSchema`, and `annotations`
876
+ - [ ] Annotations correctly set (readOnlyHint, destructiveHint, idempotentHint, openWorldHint)
877
+ - [ ] All tools use Zod schemas for runtime input validation with `.strict()` enforcement
878
+ - [ ] All Zod schemas have proper constraints and descriptive error messages
879
+ - [ ] All tools have comprehensive descriptions with explicit input/output types
880
+ - [ ] Descriptions include return value examples and complete schema documentation
881
+ - [ ] Error messages are clear, actionable, and educational
882
+
883
+ ### TypeScript Quality
884
+ - [ ] TypeScript interfaces are defined for all data structures
885
+ - [ ] Strict TypeScript is enabled in tsconfig.json
886
+ - [ ] No use of `any` type - use `unknown` or proper types instead
887
+ - [ ] All async functions have explicit Promise<T> return types
888
+ - [ ] Error handling uses proper type guards (e.g., `axios.isAxiosError`, `z.ZodError`)
889
+
890
+ ### Advanced Features (where applicable)
891
+ - [ ] Resources registered for appropriate data endpoints
892
+ - [ ] Appropriate transport configured (stdio, HTTP, SSE)
893
+ - [ ] Notifications implemented for dynamic server capabilities
894
+ - [ ] Type-safe with SDK interfaces
895
+
896
+ ### Project Configuration
897
+ - [ ] Package.json includes all necessary dependencies
898
+ - [ ] Build script produces working JavaScript in dist/ directory
899
+ - [ ] Main entry point is properly configured as dist/index.js
900
+ - [ ] Server name follows format: `{service}-mcp-server`
901
+ - [ ] tsconfig.json properly configured with strict mode
902
+
903
+ ### Code Quality
904
+ - [ ] Pagination is properly implemented where applicable
905
+ - [ ] Large responses check CHARACTER_LIMIT constant and truncate with clear messages
906
+ - [ ] Filtering options are provided for potentially large result sets
907
+ - [ ] All network operations handle timeouts and connection errors gracefully
908
+ - [ ] Common functionality is extracted into reusable functions
909
+ - [ ] Return types are consistent across similar operations
910
+
911
+ ### Testing and Build
912
+ - [ ] `npm run build` completes successfully without errors
913
+ - [ ] dist/index.js created and executable
914
+ - [ ] Server runs: `node dist/index.js --help`
915
+ - [ ] All imports resolve correctly
916
916
  - [ ] Sample tool calls work as expected