@mseep/core 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (312) hide show
  1. package/CHANGELOG.md +285 -0
  2. package/LICENSE +21 -0
  3. package/README.ja.md +14 -0
  4. package/README.ko.md +14 -0
  5. package/README.md +227 -0
  6. package/README.pt-BR.md +14 -0
  7. package/README.skills.md +50 -0
  8. package/README.uk.md +14 -0
  9. package/README.zh-CN.md +14 -0
  10. package/bin/booklib-mcp.js +458 -0
  11. package/bin/booklib.js +2394 -0
  12. package/bin/skills.cjs +1292 -0
  13. package/community/registry.json +1616 -0
  14. package/hooks/hooks.json +52 -0
  15. package/hooks/posttooluse-capture.mjs +67 -0
  16. package/hooks/posttooluse-contradict.mjs +76 -0
  17. package/hooks/posttooluse-imports.mjs +67 -0
  18. package/hooks/pretooluse-inject.mjs +82 -0
  19. package/hooks/suggest.js +153 -0
  20. package/lib/agent-detector.js +96 -0
  21. package/lib/config-loader.js +39 -0
  22. package/lib/conflict-resolver.js +148 -0
  23. package/lib/connectors/context7.js +167 -0
  24. package/lib/connectors/github.js +223 -0
  25. package/lib/connectors/local.js +120 -0
  26. package/lib/connectors/notion.js +436 -0
  27. package/lib/connectors/web.js +134 -0
  28. package/lib/context-builder.js +574 -0
  29. package/lib/discovery-engine.js +298 -0
  30. package/lib/doctor/hook-installer.js +83 -0
  31. package/lib/doctor/usage-tracker.js +87 -0
  32. package/lib/engine/auditor.js +103 -0
  33. package/lib/engine/auto-linker.js +177 -0
  34. package/lib/engine/bm25-index.js +178 -0
  35. package/lib/engine/capture.js +120 -0
  36. package/lib/engine/context-map.js +641 -0
  37. package/lib/engine/corrections.js +194 -0
  38. package/lib/engine/decision-checker.js +203 -0
  39. package/lib/engine/doctor.js +207 -0
  40. package/lib/engine/embedding-provider.js +72 -0
  41. package/lib/engine/gap-detector.js +138 -0
  42. package/lib/engine/gap-resolver.js +135 -0
  43. package/lib/engine/graph-injector.js +137 -0
  44. package/lib/engine/graph-search.js +183 -0
  45. package/lib/engine/graph.js +170 -0
  46. package/lib/engine/handoff.js +411 -0
  47. package/lib/engine/import-checker.js +249 -0
  48. package/lib/engine/import-parser.js +145 -0
  49. package/lib/engine/indexer.js +334 -0
  50. package/lib/engine/lookup-priority.js +15 -0
  51. package/lib/engine/parser.js +257 -0
  52. package/lib/engine/principle-extractor.js +116 -0
  53. package/lib/engine/project-analyzer.js +353 -0
  54. package/lib/engine/query-expander.js +42 -0
  55. package/lib/engine/reasoning-modes.js +353 -0
  56. package/lib/engine/registries.js +524 -0
  57. package/lib/engine/reranker.js +45 -0
  58. package/lib/engine/rrf.js +59 -0
  59. package/lib/engine/scanner.js +151 -0
  60. package/lib/engine/searcher.js +223 -0
  61. package/lib/engine/session-coordinator.js +291 -0
  62. package/lib/engine/session-manager.js +375 -0
  63. package/lib/engine/source-detector.js +240 -0
  64. package/lib/engine/source-manager.js +142 -0
  65. package/lib/engine/structured-response.js +47 -0
  66. package/lib/engine/synthesis-templates.js +364 -0
  67. package/lib/installer.js +70 -0
  68. package/lib/instinct-block.js +21 -0
  69. package/lib/mcp-config-writer.js +107 -0
  70. package/lib/paths.js +62 -0
  71. package/lib/project-initializer.js +856 -0
  72. package/lib/registry/skills.js +102 -0
  73. package/lib/registry-searcher.js +107 -0
  74. package/lib/rules/rules-manager.js +169 -0
  75. package/lib/skill-fetcher.js +333 -0
  76. package/lib/well-known-builder.js +74 -0
  77. package/lib/wizard/index.js +1389 -0
  78. package/lib/wizard/integration-detector.js +41 -0
  79. package/lib/wizard/project-detector.js +146 -0
  80. package/lib/wizard/prompt.js +221 -0
  81. package/lib/wizard/registry-embeddings.js +107 -0
  82. package/lib/wizard/skill-recommender.js +69 -0
  83. package/package.json +70 -0
  84. package/skills/animation-at-work/SKILL.md +270 -0
  85. package/skills/animation-at-work/assets/example_asset.txt +1 -0
  86. package/skills/animation-at-work/evals/evals.json +44 -0
  87. package/skills/animation-at-work/evals/results.json +13 -0
  88. package/skills/animation-at-work/examples/after.md +64 -0
  89. package/skills/animation-at-work/examples/before.md +35 -0
  90. package/skills/animation-at-work/references/api_reference.md +369 -0
  91. package/skills/animation-at-work/references/review-checklist.md +79 -0
  92. package/skills/animation-at-work/scripts/audit_animations.py +295 -0
  93. package/skills/animation-at-work/scripts/example.py +1 -0
  94. package/skills/booklib-mcp-guide/SKILL.md +129 -0
  95. package/skills/booklib-mcp-guide/evals/evals.json +37 -0
  96. package/skills/booklib-mcp-guide/examples/after.md +34 -0
  97. package/skills/booklib-mcp-guide/examples/before.md +27 -0
  98. package/skills/booklib-mcp-guide/references/tool-catalog.md +9 -0
  99. package/skills/clean-code-reviewer/SKILL.md +444 -0
  100. package/skills/clean-code-reviewer/audit.json +35 -0
  101. package/skills/clean-code-reviewer/evals/evals.json +185 -0
  102. package/skills/clean-code-reviewer/evals/results.json +13 -0
  103. package/skills/clean-code-reviewer/examples/after.md +48 -0
  104. package/skills/clean-code-reviewer/examples/before.md +33 -0
  105. package/skills/clean-code-reviewer/references/api_reference.md +158 -0
  106. package/skills/clean-code-reviewer/references/practices-catalog.md +282 -0
  107. package/skills/clean-code-reviewer/references/review-checklist.md +254 -0
  108. package/skills/clean-code-reviewer/scripts/pre-review.py +206 -0
  109. package/skills/data-intensive-patterns/SKILL.md +267 -0
  110. package/skills/data-intensive-patterns/assets/example_asset.txt +1 -0
  111. package/skills/data-intensive-patterns/evals/evals.json +54 -0
  112. package/skills/data-intensive-patterns/evals/results.json +13 -0
  113. package/skills/data-intensive-patterns/examples/after.md +61 -0
  114. package/skills/data-intensive-patterns/examples/before.md +38 -0
  115. package/skills/data-intensive-patterns/references/api_reference.md +34 -0
  116. package/skills/data-intensive-patterns/references/patterns-catalog.md +551 -0
  117. package/skills/data-intensive-patterns/references/review-checklist.md +193 -0
  118. package/skills/data-intensive-patterns/scripts/adr.py +213 -0
  119. package/skills/data-intensive-patterns/scripts/example.py +1 -0
  120. package/skills/data-pipelines/SKILL.md +259 -0
  121. package/skills/data-pipelines/assets/example_asset.txt +1 -0
  122. package/skills/data-pipelines/evals/evals.json +45 -0
  123. package/skills/data-pipelines/evals/results.json +13 -0
  124. package/skills/data-pipelines/examples/after.md +97 -0
  125. package/skills/data-pipelines/examples/before.md +37 -0
  126. package/skills/data-pipelines/references/api_reference.md +301 -0
  127. package/skills/data-pipelines/references/review-checklist.md +181 -0
  128. package/skills/data-pipelines/scripts/example.py +1 -0
  129. package/skills/data-pipelines/scripts/new_pipeline.py +444 -0
  130. package/skills/design-patterns/SKILL.md +271 -0
  131. package/skills/design-patterns/assets/example_asset.txt +1 -0
  132. package/skills/design-patterns/evals/evals.json +46 -0
  133. package/skills/design-patterns/evals/results.json +13 -0
  134. package/skills/design-patterns/examples/after.md +52 -0
  135. package/skills/design-patterns/examples/before.md +29 -0
  136. package/skills/design-patterns/references/api_reference.md +1 -0
  137. package/skills/design-patterns/references/patterns-catalog.md +726 -0
  138. package/skills/design-patterns/references/review-checklist.md +173 -0
  139. package/skills/design-patterns/scripts/example.py +1 -0
  140. package/skills/design-patterns/scripts/scaffold.py +807 -0
  141. package/skills/domain-driven-design/SKILL.md +142 -0
  142. package/skills/domain-driven-design/assets/example_asset.txt +1 -0
  143. package/skills/domain-driven-design/evals/evals.json +48 -0
  144. package/skills/domain-driven-design/evals/results.json +13 -0
  145. package/skills/domain-driven-design/examples/after.md +80 -0
  146. package/skills/domain-driven-design/examples/before.md +43 -0
  147. package/skills/domain-driven-design/references/api_reference.md +1 -0
  148. package/skills/domain-driven-design/references/patterns-catalog.md +545 -0
  149. package/skills/domain-driven-design/references/review-checklist.md +158 -0
  150. package/skills/domain-driven-design/scripts/example.py +1 -0
  151. package/skills/domain-driven-design/scripts/scaffold.py +421 -0
  152. package/skills/effective-java/SKILL.md +227 -0
  153. package/skills/effective-java/assets/example_asset.txt +1 -0
  154. package/skills/effective-java/evals/evals.json +46 -0
  155. package/skills/effective-java/evals/results.json +13 -0
  156. package/skills/effective-java/examples/after.md +83 -0
  157. package/skills/effective-java/examples/before.md +37 -0
  158. package/skills/effective-java/references/api_reference.md +1 -0
  159. package/skills/effective-java/references/items-catalog.md +955 -0
  160. package/skills/effective-java/references/review-checklist.md +216 -0
  161. package/skills/effective-java/scripts/checkstyle_setup.py +211 -0
  162. package/skills/effective-java/scripts/example.py +1 -0
  163. package/skills/effective-kotlin/SKILL.md +271 -0
  164. package/skills/effective-kotlin/assets/example_asset.txt +1 -0
  165. package/skills/effective-kotlin/audit.json +29 -0
  166. package/skills/effective-kotlin/evals/evals.json +45 -0
  167. package/skills/effective-kotlin/evals/results.json +13 -0
  168. package/skills/effective-kotlin/examples/after.md +36 -0
  169. package/skills/effective-kotlin/examples/before.md +38 -0
  170. package/skills/effective-kotlin/references/api_reference.md +1 -0
  171. package/skills/effective-kotlin/references/practices-catalog.md +1228 -0
  172. package/skills/effective-kotlin/references/review-checklist.md +126 -0
  173. package/skills/effective-kotlin/scripts/example.py +1 -0
  174. package/skills/effective-python/SKILL.md +441 -0
  175. package/skills/effective-python/evals/evals.json +44 -0
  176. package/skills/effective-python/evals/results.json +13 -0
  177. package/skills/effective-python/examples/after.md +56 -0
  178. package/skills/effective-python/examples/before.md +40 -0
  179. package/skills/effective-python/ref-01-pythonic-thinking.md +202 -0
  180. package/skills/effective-python/ref-02-lists-and-dicts.md +146 -0
  181. package/skills/effective-python/ref-03-functions.md +186 -0
  182. package/skills/effective-python/ref-04-comprehensions-generators.md +211 -0
  183. package/skills/effective-python/ref-05-classes-interfaces.md +188 -0
  184. package/skills/effective-python/ref-06-metaclasses-attributes.md +209 -0
  185. package/skills/effective-python/ref-07-concurrency.md +213 -0
  186. package/skills/effective-python/ref-08-robustness-performance.md +248 -0
  187. package/skills/effective-python/ref-09-testing-debugging.md +253 -0
  188. package/skills/effective-python/ref-10-collaboration.md +175 -0
  189. package/skills/effective-python/references/api_reference.md +218 -0
  190. package/skills/effective-python/references/practices-catalog.md +483 -0
  191. package/skills/effective-python/references/review-checklist.md +190 -0
  192. package/skills/effective-python/scripts/lint.py +173 -0
  193. package/skills/effective-typescript/SKILL.md +262 -0
  194. package/skills/effective-typescript/audit.json +29 -0
  195. package/skills/effective-typescript/evals/evals.json +37 -0
  196. package/skills/effective-typescript/evals/results.json +13 -0
  197. package/skills/effective-typescript/examples/after.md +70 -0
  198. package/skills/effective-typescript/examples/before.md +47 -0
  199. package/skills/effective-typescript/references/api_reference.md +118 -0
  200. package/skills/effective-typescript/references/practices-catalog.md +371 -0
  201. package/skills/effective-typescript/scripts/review.py +169 -0
  202. package/skills/kotlin-in-action/SKILL.md +261 -0
  203. package/skills/kotlin-in-action/assets/example_asset.txt +1 -0
  204. package/skills/kotlin-in-action/evals/evals.json +43 -0
  205. package/skills/kotlin-in-action/evals/results.json +13 -0
  206. package/skills/kotlin-in-action/examples/after.md +53 -0
  207. package/skills/kotlin-in-action/examples/before.md +39 -0
  208. package/skills/kotlin-in-action/references/api_reference.md +1 -0
  209. package/skills/kotlin-in-action/references/practices-catalog.md +436 -0
  210. package/skills/kotlin-in-action/references/review-checklist.md +204 -0
  211. package/skills/kotlin-in-action/scripts/example.py +1 -0
  212. package/skills/kotlin-in-action/scripts/setup_detekt.py +224 -0
  213. package/skills/lean-startup/SKILL.md +160 -0
  214. package/skills/lean-startup/assets/example_asset.txt +1 -0
  215. package/skills/lean-startup/evals/evals.json +43 -0
  216. package/skills/lean-startup/evals/results.json +13 -0
  217. package/skills/lean-startup/examples/after.md +80 -0
  218. package/skills/lean-startup/examples/before.md +34 -0
  219. package/skills/lean-startup/references/api_reference.md +319 -0
  220. package/skills/lean-startup/references/review-checklist.md +137 -0
  221. package/skills/lean-startup/scripts/example.py +1 -0
  222. package/skills/lean-startup/scripts/new_experiment.py +286 -0
  223. package/skills/microservices-patterns/SKILL.md +384 -0
  224. package/skills/microservices-patterns/evals/evals.json +45 -0
  225. package/skills/microservices-patterns/evals/results.json +13 -0
  226. package/skills/microservices-patterns/examples/after.md +69 -0
  227. package/skills/microservices-patterns/examples/before.md +40 -0
  228. package/skills/microservices-patterns/references/patterns-catalog.md +391 -0
  229. package/skills/microservices-patterns/references/review-checklist.md +169 -0
  230. package/skills/microservices-patterns/scripts/new_service.py +583 -0
  231. package/skills/programming-with-rust/SKILL.md +209 -0
  232. package/skills/programming-with-rust/evals/evals.json +37 -0
  233. package/skills/programming-with-rust/evals/results.json +13 -0
  234. package/skills/programming-with-rust/examples/after.md +107 -0
  235. package/skills/programming-with-rust/examples/before.md +59 -0
  236. package/skills/programming-with-rust/references/api_reference.md +152 -0
  237. package/skills/programming-with-rust/references/practices-catalog.md +335 -0
  238. package/skills/programming-with-rust/scripts/review.py +142 -0
  239. package/skills/refactoring-ui/SKILL.md +362 -0
  240. package/skills/refactoring-ui/assets/example_asset.txt +1 -0
  241. package/skills/refactoring-ui/evals/evals.json +45 -0
  242. package/skills/refactoring-ui/evals/results.json +13 -0
  243. package/skills/refactoring-ui/examples/after.md +85 -0
  244. package/skills/refactoring-ui/examples/before.md +58 -0
  245. package/skills/refactoring-ui/references/api_reference.md +355 -0
  246. package/skills/refactoring-ui/references/review-checklist.md +114 -0
  247. package/skills/refactoring-ui/scripts/audit_css.py +250 -0
  248. package/skills/refactoring-ui/scripts/example.py +1 -0
  249. package/skills/rust-in-action/SKILL.md +350 -0
  250. package/skills/rust-in-action/evals/evals.json +38 -0
  251. package/skills/rust-in-action/evals/results.json +13 -0
  252. package/skills/rust-in-action/examples/after.md +156 -0
  253. package/skills/rust-in-action/examples/before.md +56 -0
  254. package/skills/rust-in-action/references/practices-catalog.md +346 -0
  255. package/skills/rust-in-action/scripts/review.py +147 -0
  256. package/skills/skill-router/SKILL.md +186 -0
  257. package/skills/skill-router/evals/evals.json +38 -0
  258. package/skills/skill-router/evals/results.json +13 -0
  259. package/skills/skill-router/examples/after.md +63 -0
  260. package/skills/skill-router/examples/before.md +39 -0
  261. package/skills/skill-router/references/api_reference.md +24 -0
  262. package/skills/skill-router/references/routing-heuristics.md +89 -0
  263. package/skills/skill-router/references/skill-catalog.md +174 -0
  264. package/skills/skill-router/scripts/route.py +266 -0
  265. package/skills/spring-boot-in-action/SKILL.md +340 -0
  266. package/skills/spring-boot-in-action/evals/evals.json +39 -0
  267. package/skills/spring-boot-in-action/evals/results.json +13 -0
  268. package/skills/spring-boot-in-action/examples/after.md +185 -0
  269. package/skills/spring-boot-in-action/examples/before.md +84 -0
  270. package/skills/spring-boot-in-action/references/practices-catalog.md +403 -0
  271. package/skills/spring-boot-in-action/scripts/review.py +184 -0
  272. package/skills/storytelling-with-data/SKILL.md +241 -0
  273. package/skills/storytelling-with-data/assets/example_asset.txt +1 -0
  274. package/skills/storytelling-with-data/evals/evals.json +47 -0
  275. package/skills/storytelling-with-data/evals/results.json +13 -0
  276. package/skills/storytelling-with-data/examples/after.md +50 -0
  277. package/skills/storytelling-with-data/examples/before.md +33 -0
  278. package/skills/storytelling-with-data/references/api_reference.md +379 -0
  279. package/skills/storytelling-with-data/references/review-checklist.md +111 -0
  280. package/skills/storytelling-with-data/scripts/chart_review.py +301 -0
  281. package/skills/storytelling-with-data/scripts/example.py +1 -0
  282. package/skills/system-design-interview/SKILL.md +233 -0
  283. package/skills/system-design-interview/assets/example_asset.txt +1 -0
  284. package/skills/system-design-interview/evals/evals.json +46 -0
  285. package/skills/system-design-interview/evals/results.json +13 -0
  286. package/skills/system-design-interview/examples/after.md +94 -0
  287. package/skills/system-design-interview/examples/before.md +27 -0
  288. package/skills/system-design-interview/references/api_reference.md +582 -0
  289. package/skills/system-design-interview/references/review-checklist.md +201 -0
  290. package/skills/system-design-interview/scripts/example.py +1 -0
  291. package/skills/system-design-interview/scripts/new_design.py +421 -0
  292. package/skills/using-asyncio-python/SKILL.md +290 -0
  293. package/skills/using-asyncio-python/assets/example_asset.txt +1 -0
  294. package/skills/using-asyncio-python/evals/evals.json +43 -0
  295. package/skills/using-asyncio-python/evals/results.json +13 -0
  296. package/skills/using-asyncio-python/examples/after.md +68 -0
  297. package/skills/using-asyncio-python/examples/before.md +39 -0
  298. package/skills/using-asyncio-python/references/api_reference.md +267 -0
  299. package/skills/using-asyncio-python/references/review-checklist.md +149 -0
  300. package/skills/using-asyncio-python/scripts/check_blocking.py +270 -0
  301. package/skills/using-asyncio-python/scripts/example.py +1 -0
  302. package/skills/web-scraping-python/SKILL.md +280 -0
  303. package/skills/web-scraping-python/assets/example_asset.txt +1 -0
  304. package/skills/web-scraping-python/evals/evals.json +46 -0
  305. package/skills/web-scraping-python/evals/results.json +13 -0
  306. package/skills/web-scraping-python/examples/after.md +109 -0
  307. package/skills/web-scraping-python/examples/before.md +40 -0
  308. package/skills/web-scraping-python/references/api_reference.md +393 -0
  309. package/skills/web-scraping-python/references/review-checklist.md +163 -0
  310. package/skills/web-scraping-python/scripts/example.py +1 -0
  311. package/skills/web-scraping-python/scripts/new_scraper.py +231 -0
  312. package/skills/writing-plans/audit.json +34 -0
@@ -0,0 +1,458 @@
1
+ #!/usr/bin/env node
2
+
3
+ import path from 'path';
4
+ import fs from 'fs';
5
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
6
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
+ import {
8
+ CallToolRequestSchema,
9
+ ListToolsRequestSchema,
10
+ } from "@modelcontextprotocol/sdk/types.js";
11
+ import { BookLibSearcher } from "../lib/engine/searcher.js";
12
+ import { BookLibAuditor } from "../lib/engine/auditor.js";
13
+ import { BookLibHandoff } from "../lib/engine/handoff.js";
14
+ import { resolveBookLibPaths } from "../lib/paths.js";
15
+ import { ContextBuilder } from "../lib/context-builder.js";
16
+ import {
17
+ serializeNode, saveNode, generateNodeId,
18
+ listNodes, loadNode, parseNodeFrontmatter,
19
+ resolveNodeRef, appendEdge, EDGE_TYPES,
20
+ resolveKnowledgePaths, parseCaptureLinkArgs,
21
+ } from "../lib/engine/graph.js";
22
+ import { BookLibIndexer } from "../lib/engine/indexer.js";
23
+ import { processResults } from "../lib/engine/reasoning-modes.js";
24
+ import { detectResultSourceType } from '../lib/engine/synthesis-templates.js';
25
+ import { autoLink } from '../lib/engine/auto-linker.js';
26
+ import { buildGraphContext } from '../lib/engine/graph-injector.js';
27
+ import { graphActivatedSearch } from '../lib/engine/graph-search.js';
28
+ import { extractFromResults } from '../lib/engine/principle-extractor.js';
29
+ import { prioritizeLookupResults } from '../lib/engine/lookup-priority.js';
30
+ import { ContextMapBuilder } from '../lib/engine/context-map.js';
31
+
32
+ const __pkgDir = path.resolve(path.dirname(new URL(import.meta.url).pathname), '..');
33
+ const __pkg = JSON.parse(fs.readFileSync(path.join(__pkgDir, 'package.json'), 'utf8'));
34
+
35
+ const { skillsPath } = resolveBookLibPaths();
36
+ const searcher = new BookLibSearcher();
37
+ const auditor = new BookLibAuditor();
38
+ const handoff = new BookLibHandoff();
39
+
40
+ const server = new Server(
41
+ {
42
+ name: "booklib-engine",
43
+ version: __pkg.version,
44
+ },
45
+ {
46
+ capabilities: {
47
+ tools: {},
48
+ },
49
+ }
50
+ );
51
+
52
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
53
+ return {
54
+ tools: [
55
+ {
56
+ name: "lookup",
57
+ description: "Search BookLib for post-training API docs, team decisions, or expert knowledge. Prioritizes gap corrections, then team knowledge, then skills. Skip for standard patterns you already know.",
58
+ inputSchema: {
59
+ type: "object",
60
+ properties: {
61
+ query: {
62
+ type: "string",
63
+ description: "What you need to know (e.g., 'supabase auth session handling')",
64
+ },
65
+ file: {
66
+ type: "string",
67
+ description: "Path to the file being worked on — adds language and component context",
68
+ },
69
+ limit: {
70
+ type: "number",
71
+ description: "Maximum results (default: 3)",
72
+ },
73
+ source: {
74
+ type: "string",
75
+ enum: ["all", "skills", "knowledge"],
76
+ description: "Filter: 'all' (default), 'skills' (expert only), 'knowledge' (team/personal only)",
77
+ },
78
+ },
79
+ required: ["query"],
80
+ },
81
+ },
82
+ {
83
+ name: "review",
84
+ description: "Deep code review of a file against a named skill's principles. Returns structured findings with source citations.",
85
+ inputSchema: {
86
+ type: "object",
87
+ properties: {
88
+ skill_name: {
89
+ type: "string",
90
+ description: "Skill to review against (e.g., 'effective-kotlin', 'clean-code-reviewer')",
91
+ },
92
+ file_path: {
93
+ type: "string",
94
+ description: "Path to the file to review",
95
+ },
96
+ },
97
+ required: ["skill_name", "file_path"],
98
+ },
99
+ },
100
+ {
101
+ name: "remember",
102
+ description: "Capture a team decision, pattern, or insight as a searchable knowledge node. Use when the user says 'remember this', makes a decision, or discovers something worth preserving.",
103
+ inputSchema: {
104
+ type: "object",
105
+ properties: {
106
+ title: {
107
+ type: "string",
108
+ description: "Short descriptive title (e.g., 'use PaymentIntents not Charges')",
109
+ },
110
+ content: {
111
+ type: "string",
112
+ description: "Detailed description in markdown. Leave empty for a stub.",
113
+ },
114
+ type: {
115
+ type: "string",
116
+ enum: ["insight", "decision", "pattern", "note", "research"],
117
+ description: "Node type (default: 'insight')",
118
+ },
119
+ tags: {
120
+ type: "string",
121
+ description: "Comma-separated tags",
122
+ },
123
+ links: {
124
+ type: "string",
125
+ description: "Link targets as 'target:edge-type' pairs (e.g., 'auth:applies-to')",
126
+ },
127
+ },
128
+ required: ["title"],
129
+ },
130
+ },
131
+ {
132
+ name: "verify",
133
+ description: "Check if a file's imports are covered by BookLib's index. Flags unknown post-training APIs that may need current docs.",
134
+ inputSchema: {
135
+ type: "object",
136
+ properties: {
137
+ file_path: { type: "string", description: "Path to the source file to check" },
138
+ auto_index: { type: "boolean", description: "Auto-index docs for unknown imports if configured" },
139
+ },
140
+ required: ["file_path"],
141
+ },
142
+ },
143
+ {
144
+ name: "guard",
145
+ description: "Check if code contradicts captured team decisions. Use after writing code that touches architecture, API choices, or team conventions.",
146
+ inputSchema: {
147
+ type: "object",
148
+ properties: {
149
+ file_path: { type: "string", description: "Path to the source file to check" },
150
+ },
151
+ required: ["file_path"],
152
+ },
153
+ },
154
+ ],
155
+ };
156
+ });
157
+
158
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
159
+ const { name, arguments: args } = request.params;
160
+
161
+ try {
162
+ switch (name) {
163
+ case "lookup":
164
+ case "search_skills":
165
+ case "search_knowledge": {
166
+ const raw = await searcher.search(args.query, args.limit ?? 3, 0);
167
+ const sourceFilter = args.source ?? 'all';
168
+ const filtered = raw
169
+ .filter(r => {
170
+ if (sourceFilter === 'skills') return r.metadata?.nodeKind !== 'knowledge';
171
+ if (sourceFilter === 'knowledge') return r.metadata?.nodeKind === 'knowledge';
172
+ return true;
173
+ });
174
+
175
+ // Check context-map for post-training gap matches before generic search
176
+ let contextMapHits = [];
177
+ try {
178
+ const mapPath = path.join(process.cwd(), '.booklib', 'context-map.json');
179
+ const map = ContextMapBuilder.load(mapPath);
180
+ if (map?.items?.length) {
181
+ const queryLower = args.query.toLowerCase();
182
+ contextMapHits = map.items.filter(item =>
183
+ item.type === 'post-training' &&
184
+ item.importTriggers.some(t => queryLower.includes(t.toLowerCase()))
185
+ ).map(item => ({
186
+ text: item.injection?.correction ?? item.id,
187
+ score: 1.0,
188
+ metadata: { nodeKind: 'context-map', source: item.source, type: item.type },
189
+ }));
190
+ }
191
+ } catch { /* context map not available */ }
192
+
193
+ // Prioritize: gap results first, then team knowledge, then skill results
194
+ const gapResults = contextMapHits;
195
+ const teamResults = filtered.filter(r => r.metadata?.nodeKind === 'knowledge');
196
+ const nicheResults = filtered.filter(r => r.metadata?.nodeKind !== 'knowledge');
197
+ const prioritized = prioritizeLookupResults({ gapResults, teamResults, nicheResults });
198
+
199
+ // Read config for reasoning mode + ollama model
200
+ let reasoningMode = 'fast';
201
+ let ollamaModel = 'phi3';
202
+ try {
203
+ const configPath = path.join(process.cwd(), 'booklib.config.json');
204
+ if (fs.existsSync(configPath)) {
205
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
206
+ reasoningMode = config.reasoning ?? 'fast';
207
+ ollamaModel = config.ollamaModel ?? 'phi3';
208
+ }
209
+ } catch { /* use default */ }
210
+
211
+ // Try graph-activated search for multi-concept queries
212
+ const graphResult = graphActivatedSearch(args.query, prioritized);
213
+
214
+ if (graphResult.activated && graphResult.graphResults.length > 0) {
215
+ const limit = args.limit ?? 3;
216
+ const textPrinciples = extractFromResults(prioritized, limit);
217
+ // Skills first, graph context appended — never replace skill results
218
+ const allPrinciples = [
219
+ ...textPrinciples.slice(0, limit),
220
+ ...graphResult.graphResults.slice(0, 2),
221
+ ];
222
+
223
+ return { content: [{ type: "text", text: JSON.stringify({
224
+ query: args.query,
225
+ file: args.file ?? null,
226
+ concepts: graphResult.concepts,
227
+ graphActivated: true,
228
+ results: allPrinciples,
229
+ note: `${textPrinciples.length} expert result(s), ${graphResult.graphResults.length} project context(s).`,
230
+ }, null, 2) }] };
231
+ }
232
+
233
+ const sourceType = detectResultSourceType(prioritized);
234
+
235
+ const structured = await processResults(args.query, prioritized, reasoningMode, {
236
+ maxPrinciples: args.limit ?? 3,
237
+ file: args.file,
238
+ sourceType,
239
+ apiKey: process.env.ANTHROPIC_API_KEY ?? process.env.OPENAI_API_KEY,
240
+ apiProvider: process.env.ANTHROPIC_API_KEY ? 'anthropic' : 'openai',
241
+ ollamaModel,
242
+ });
243
+ return { content: [{ type: "text", text: JSON.stringify(structured, null, 2) }] };
244
+ }
245
+
246
+ case "review":
247
+ case "review_file":
248
+ case "audit_content": {
249
+ const skillPath = path.join(skillsPath, args.skill_name);
250
+ const auditReport = await auditor.audit(skillPath, args.file_path);
251
+ return { content: [{ type: "text", text: auditReport }] };
252
+ }
253
+
254
+ // brief: demoted from MCP tool list but still works as alias → lookup with file context
255
+ case "brief":
256
+ case "get_context": {
257
+ const builder = new ContextBuilder();
258
+
259
+ // Graph-first: if file provided, find component and linked knowledge
260
+ let projectKnowledge = [];
261
+ if (args.file) {
262
+ try {
263
+ const graphNodes = await buildGraphContext({
264
+ filePath: args.file,
265
+ taskContext: args.task,
266
+ searcher,
267
+ });
268
+ projectKnowledge = graphNodes.map(node => ({
269
+ insight: node.title,
270
+ type: node.type,
271
+ source: `project ${node.type}: ${node.id}`,
272
+ body: node.body,
273
+ score: node.score,
274
+ }));
275
+ } catch { /* graph traversal is best-effort */ }
276
+ }
277
+
278
+ // Expert knowledge from skill search
279
+ const expertContext = await builder.build(args.task, { promptOnly: true });
280
+
281
+ const structured = {
282
+ task: args.task,
283
+ file: args.file ?? null,
284
+ project_knowledge: projectKnowledge,
285
+ expert_knowledge: expertContext,
286
+ note: projectKnowledge.length > 0
287
+ ? `Graph context: ${projectKnowledge.length} linked node(s) for ${args.file}.`
288
+ : 'No graph context — no file provided or no matching components.',
289
+ };
290
+
291
+ return { content: [{ type: "text", text: JSON.stringify(structured, null, 2) }] };
292
+ }
293
+
294
+ case "remember":
295
+ case "create_note": {
296
+ const { nodesDir } = resolveKnowledgePaths();
297
+ const { indexPath } = resolveBookLibPaths();
298
+ const id = generateNodeId('node');
299
+ const nodeType = args.type ?? 'insight';
300
+ const nodeContent = serializeNode({
301
+ id,
302
+ type: nodeType,
303
+ title: args.title,
304
+ content: args.content ?? '',
305
+ tags: args.tags ? args.tags.split(',').map(t => t.trim()).filter(Boolean) : [],
306
+ links: args.links,
307
+ });
308
+ const filePath = saveNode(nodeContent, id, { nodesDir });
309
+ try {
310
+ const indexer = new BookLibIndexer(indexPath);
311
+ await indexer.indexNodeFile(filePath, nodesDir);
312
+ } catch {
313
+ // Index may not exist yet — node is saved, will appear after booklib index
314
+ }
315
+ // Process explicit links
316
+ if (args.links) {
317
+ const links = parseCaptureLinkArgs(args.links);
318
+ const today = new Date().toISOString().split('T')[0];
319
+ for (const link of links) {
320
+ if (EDGE_TYPES.includes(link.type)) {
321
+ appendEdge({ from: id, to: link.to, type: link.type, weight: 1.0, created: today });
322
+ }
323
+ }
324
+ }
325
+ // Auto-link to components and related knowledge
326
+ let autoLinked = [];
327
+ try {
328
+ autoLinked = await autoLink({
329
+ nodeId: id,
330
+ title: args.title,
331
+ content: args.content ?? '',
332
+ tags: args.tags ? args.tags.split(',').map(t => t.trim()).filter(Boolean) : [],
333
+ });
334
+ } catch { /* best-effort */ }
335
+ return { content: [{ type: "text", text: JSON.stringify({
336
+ id,
337
+ title: args.title,
338
+ type: nodeType,
339
+ saved_to: filePath,
340
+ indexed: true,
341
+ auto_linked: autoLinked.map(l => `${l.to} (${l.type}) — ${l.reason}`),
342
+ note: `Saved and indexed.${autoLinked.length > 0 ? ` Auto-linked to ${autoLinked.length} node(s).` : ''}`
343
+ }, null, 2) }] };
344
+ }
345
+
346
+ // recalled: demoted from MCP tool list but still works as alias
347
+ case "recalled":
348
+ case "list_nodes": {
349
+ const { nodesDir } = resolveKnowledgePaths();
350
+ const allIds = listNodes({ nodesDir });
351
+ const nodes = allIds
352
+ .map(id => {
353
+ const raw = loadNode(id, { nodesDir });
354
+ if (!raw) return null;
355
+ const parsed = parseNodeFrontmatter(raw);
356
+ return { id, title: parsed.title ?? '', type: parsed.type ?? '' };
357
+ })
358
+ .filter(n => {
359
+ if (!n) return false;
360
+ if (args.type_filter) return n.type === args.type_filter;
361
+ return true;
362
+ });
363
+ return { content: [{ type: "text", text: JSON.stringify(nodes, null, 2) }] };
364
+ }
365
+
366
+ // connect: demoted from MCP tool list but still works as alias
367
+ case "connect":
368
+ case "link_nodes": {
369
+ const fromId = resolveNodeRef(args.from);
370
+ const toId = resolveNodeRef(args.to);
371
+ if (!EDGE_TYPES.includes(args.type)) {
372
+ throw new Error(`Invalid edge type "${args.type}". Valid: ${EDGE_TYPES.join(', ')}`);
373
+ }
374
+ const edge = {
375
+ from: fromId,
376
+ to: toId,
377
+ type: args.type,
378
+ weight: 1.0,
379
+ created: new Date().toISOString().split('T')[0],
380
+ };
381
+ appendEdge(edge);
382
+ return { content: [{ type: "text", text: `Edge created: ${fromId} --[${args.type}]--> ${toId}` }] };
383
+ }
384
+
385
+ case "save":
386
+ case "save_progress":
387
+ case "save_session_state": {
388
+ handoff.saveState(args);
389
+ return { content: [{ type: "text", text: `Session state saved successfully for ${args.name || 'current branch'}.` }] };
390
+ }
391
+
392
+ case "verify":
393
+ case "check_imports": {
394
+ const { ImportChecker } = await import('../lib/engine/import-checker.js');
395
+
396
+ let indexMode = 'manual';
397
+ try {
398
+ const cfgPath = path.join(process.cwd(), 'booklib.config.json');
399
+ if (fs.existsSync(cfgPath)) {
400
+ const cfg = JSON.parse(fs.readFileSync(cfgPath, 'utf8'));
401
+ indexMode = cfg.importChecking ?? 'manual';
402
+ }
403
+ } catch { /* use default */ }
404
+
405
+ const checker = new ImportChecker({ searcher, indexMode });
406
+ const resolved = path.resolve(args.file_path);
407
+ const result = await checker.checkFile(resolved, process.cwd());
408
+
409
+ const summary = {
410
+ file: args.file_path,
411
+ unknown: await Promise.all(result.unknown.map(async imp => {
412
+ const docs = await checker.resolveDocsUrl(imp);
413
+ return { module: imp.module, language: imp.language, docsUrl: docs.url };
414
+ })),
415
+ known: result.known.map(i => i.module),
416
+ skipped: result.skipped.map(i => i.module),
417
+ counts: {
418
+ known: result.known.length,
419
+ unknown: result.unknown.length,
420
+ skipped: result.skipped.length,
421
+ },
422
+ };
423
+
424
+ return { content: [{ type: "text", text: JSON.stringify(summary, null, 2) }] };
425
+ }
426
+
427
+ case "guard":
428
+ case "check_decisions": {
429
+ const { DecisionChecker } = await import('../lib/engine/decision-checker.js');
430
+ const checker = new DecisionChecker({ searcher });
431
+ const filePath = path.resolve(args.file_path);
432
+ const result = await checker.checkFile(filePath);
433
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
434
+ }
435
+
436
+ default:
437
+ throw new Error(`Tool not found: ${name}`);
438
+ }
439
+ } catch (error) {
440
+ return { content: [{ type: "text", text: `Error: ${error.message}` }], isError: true };
441
+ }
442
+ });
443
+
444
+ async function main() {
445
+ const transport = new StdioServerTransport();
446
+ await server.connect(transport);
447
+
448
+ // Warm up embedding model at startup so CoreML native warnings fire NOW
449
+ // (to stderr, before any tool call) instead of polluting the first lookup response.
450
+ try {
451
+ const { createEmbeddingPipeline } = await import('../lib/engine/embedding-provider.js');
452
+ await createEmbeddingPipeline({ quiet: true });
453
+ } catch { /* non-fatal — model loads on first search if warmup fails */ }
454
+
455
+ console.error("BookLib MCP Server running");
456
+ }
457
+
458
+ main().catch(console.error);