@telvok/librarian-mcp 1.5.3 → 2.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 (121) hide show
  1. package/dist/library/errors.d.ts +48 -0
  2. package/dist/library/errors.js +80 -0
  3. package/dist/library/parsers/jsonl.d.ts +9 -4
  4. package/dist/library/parsers/jsonl.js +52 -20
  5. package/dist/library/schemas.d.ts +6 -6
  6. package/dist/library/storage.d.ts +2 -2
  7. package/dist/library/storage.js +2 -2
  8. package/dist/library 2/embeddings.d.ts +21 -0
  9. package/dist/library 2/embeddings.js +86 -0
  10. package/dist/library 2/manager.d.ts +42 -0
  11. package/dist/library 2/manager.js +218 -0
  12. package/dist/library 2/parsers/cursor.d.ts +15 -0
  13. package/dist/library 2/parsers/cursor.js +168 -0
  14. package/dist/library 2/parsers/index.d.ts +6 -0
  15. package/dist/library 2/parsers/index.js +5 -0
  16. package/dist/library 2/parsers/json.d.ts +11 -0
  17. package/dist/library 2/parsers/json.js +95 -0
  18. package/dist/library 2/parsers/jsonl.d.ts +14 -0
  19. package/dist/library 2/parsers/jsonl.js +85 -0
  20. package/dist/library 2/parsers/markdown.d.ts +15 -0
  21. package/dist/library 2/parsers/markdown.js +77 -0
  22. package/dist/library 2/parsers/sqlite.d.ts +8 -0
  23. package/dist/library 2/parsers/sqlite.js +123 -0
  24. package/dist/library 2/parsers/types.d.ts +21 -0
  25. package/dist/library 2/parsers/types.js +4 -0
  26. package/dist/library 2/query.d.ts +26 -0
  27. package/dist/library 2/query.js +104 -0
  28. package/dist/library 2/schemas.d.ts +324 -0
  29. package/dist/library 2/schemas.js +79 -0
  30. package/dist/library 2/storage.d.ts +22 -0
  31. package/dist/library 2/storage.js +36 -0
  32. package/dist/library 2/vector-index.d.ts +55 -0
  33. package/dist/library 2/vector-index.js +160 -0
  34. package/dist/server 2.js +199 -0
  35. package/dist/server.d 2.ts +2 -0
  36. package/dist/server.js +102 -54
  37. package/dist/tools/adopt.d.ts +1 -0
  38. package/dist/tools/adopt.js +37 -10
  39. package/dist/tools/auth.d.ts +69 -0
  40. package/dist/tools/auth.js +379 -0
  41. package/dist/tools/bounty-claim.d.ts +28 -0
  42. package/dist/tools/bounty-claim.js +92 -0
  43. package/dist/tools/bounty-create.d.ts +47 -0
  44. package/dist/tools/bounty-create.js +118 -0
  45. package/dist/tools/bounty-list.d.ts +50 -0
  46. package/dist/tools/bounty-list.js +116 -0
  47. package/dist/tools/bounty-submit.d.ts +34 -0
  48. package/dist/tools/bounty-submit.js +94 -0
  49. package/dist/tools/brief.d.ts +94 -0
  50. package/dist/tools/brief.js +234 -15
  51. package/dist/tools/delete.d.ts +87 -0
  52. package/dist/tools/delete.js +266 -0
  53. package/dist/tools/feedback.d.ts +27 -0
  54. package/dist/tools/feedback.js +98 -0
  55. package/dist/tools/help.d.ts +22 -0
  56. package/dist/tools/help.js +482 -0
  57. package/dist/tools/import-memories.d.ts +1 -0
  58. package/dist/tools/import-memories.js +18 -13
  59. package/dist/tools/index.d.ts +11 -0
  60. package/dist/tools/index.js +12 -0
  61. package/dist/tools/library-buy.d.ts +31 -0
  62. package/dist/tools/library-buy.js +104 -0
  63. package/dist/tools/library-download.d.ts +27 -0
  64. package/dist/tools/library-download.js +177 -0
  65. package/dist/tools/library-publish.d.ts +112 -0
  66. package/dist/tools/library-publish.js +387 -0
  67. package/dist/tools/library-search.d.ts +110 -0
  68. package/dist/tools/library-search.js +132 -0
  69. package/dist/tools/mark-hit.d.ts +1 -0
  70. package/dist/tools/mark-hit.js +83 -5
  71. package/dist/tools/my-books.d.ts +51 -0
  72. package/dist/tools/my-books.js +115 -0
  73. package/dist/tools/my-bounties.d.ts +43 -0
  74. package/dist/tools/my-bounties.js +126 -0
  75. package/dist/tools/rate-book.d.ts +40 -0
  76. package/dist/tools/rate-book.js +147 -0
  77. package/dist/tools/rebuild-index.d.ts +1 -0
  78. package/dist/tools/rebuild-index.js +40 -8
  79. package/dist/tools/record.d.ts +18 -0
  80. package/dist/tools/record.js +30 -26
  81. package/dist/tools/seller-analytics.d.ts +53 -0
  82. package/dist/tools/seller-analytics.js +180 -0
  83. package/dist/tools/sync.d.ts +55 -0
  84. package/dist/tools/sync.js +304 -0
  85. package/dist/tools/unsubscribe.d.ts +48 -0
  86. package/dist/tools/unsubscribe.js +120 -0
  87. package/dist/tools 2/adopt.d.ts +24 -0
  88. package/dist/tools 2/adopt.js +154 -0
  89. package/dist/tools 2/auth.d.ts +35 -0
  90. package/dist/tools 2/auth.js +229 -0
  91. package/dist/tools 2/brief.d.ts +56 -0
  92. package/dist/tools 2/brief.js +414 -0
  93. package/dist/tools 2/help.d.ts +21 -0
  94. package/dist/tools 2/help.js +267 -0
  95. package/dist/tools 2/import-memories.d.ts +32 -0
  96. package/dist/tools 2/import-memories.js +231 -0
  97. package/dist/tools 2/index.d.ts +12 -0
  98. package/dist/tools 2/index.js +12 -0
  99. package/dist/tools 2/mark-hit.d.ts +20 -0
  100. package/dist/tools 2/mark-hit.js +71 -0
  101. package/dist/tools 2/marketplace-buy.d.ts +30 -0
  102. package/dist/tools 2/marketplace-buy.js +97 -0
  103. package/dist/tools 2/marketplace-download.d.ts +26 -0
  104. package/dist/tools 2/marketplace-download.js +160 -0
  105. package/dist/tools 2/marketplace-publish.d.ts +111 -0
  106. package/dist/tools 2/marketplace-publish.js +377 -0
  107. package/dist/tools 2/marketplace-search.d.ts +57 -0
  108. package/dist/tools 2/marketplace-search.js +96 -0
  109. package/dist/tools 2/my-books.d.ts +50 -0
  110. package/dist/tools 2/my-books.js +107 -0
  111. package/dist/tools 2/rate-book.d.ts +39 -0
  112. package/dist/tools 2/rate-book.js +139 -0
  113. package/dist/tools 2/rebuild-index.d.ts +23 -0
  114. package/dist/tools 2/rebuild-index.js +107 -0
  115. package/dist/tools 2/record.d.ts +40 -0
  116. package/dist/tools 2/record.js +205 -0
  117. package/dist/tools 2/seller-analytics.d.ts +35 -0
  118. package/dist/tools 2/seller-analytics.js +102 -0
  119. package/dist/tools 2/sync.d.ts +54 -0
  120. package/dist/tools 2/sync.js +298 -0
  121. package/package.json +1 -1
@@ -0,0 +1,98 @@
1
+ // ============================================================================
2
+ // Feedback Tool
3
+ // Send feedback to the Telvok team
4
+ // ============================================================================
5
+ import { loadApiKey } from './auth.js';
6
+ const TELVOK_API_URL = process.env.TELVOK_API_URL || 'https://telvok.com';
7
+ // ============================================================================
8
+ // Tool Definition
9
+ // ============================================================================
10
+ export const feedbackTool = {
11
+ name: 'feedback',
12
+ title: 'Send Feedback',
13
+ description: `Send feedback to the Telvok team.
14
+
15
+ USE THIS TOOL WHEN:
16
+ - User found a bug or issue
17
+ - User wants to request a feature
18
+ - User has questions about Librarian/Telvok
19
+ - User wants to share positive feedback
20
+
21
+ Types: bug, feature, question, general
22
+
23
+ TRIGGER PATTERNS:
24
+ - "This seems broken" → feedback({ message: "...", type: "bug" })
25
+ - "Can you add X feature?" → feedback({ message: "...", type: "feature" })
26
+ - "Great tool!" → feedback({ message: "..." })
27
+
28
+ Examples:
29
+ - feedback({ message: "The sync tool times out with large books", type: "bug" })
30
+ - feedback({ message: "Would love to filter by author", type: "feature" })
31
+ - feedback({ message: "Great tool, saved me hours!" })`,
32
+ inputSchema: {
33
+ type: 'object',
34
+ properties: {
35
+ message: {
36
+ type: 'string',
37
+ description: 'Your feedback message (5-5000 characters)',
38
+ },
39
+ type: {
40
+ type: 'string',
41
+ enum: ['bug', 'feature', 'general', 'question'],
42
+ description: 'Type of feedback (default: general)',
43
+ },
44
+ },
45
+ required: ['message'],
46
+ },
47
+ async handler(args) {
48
+ const { message, type = 'general' } = args;
49
+ if (!message || typeof message !== 'string') {
50
+ throw new Error('Message is required');
51
+ }
52
+ if (message.trim().length < 5) {
53
+ throw new Error('Message must be at least 5 characters');
54
+ }
55
+ if (message.length > 5000) {
56
+ throw new Error('Message must be 5000 characters or less');
57
+ }
58
+ // Get API key for attribution (optional)
59
+ const apiKey = await loadApiKey();
60
+ try {
61
+ const headers = {
62
+ 'Content-Type': 'application/json',
63
+ };
64
+ if (apiKey) {
65
+ headers['Authorization'] = `Bearer ${apiKey}`;
66
+ }
67
+ const response = await fetch(`${TELVOK_API_URL}/api/feedback`, {
68
+ method: 'POST',
69
+ headers,
70
+ body: JSON.stringify({
71
+ message: message.trim(),
72
+ type,
73
+ context: {
74
+ source: 'mcp',
75
+ timestamp: new Date().toISOString(),
76
+ },
77
+ }),
78
+ });
79
+ const data = await response.json();
80
+ if (!response.ok) {
81
+ return {
82
+ success: false,
83
+ message: data.error || 'Failed to send feedback',
84
+ };
85
+ }
86
+ return {
87
+ success: true,
88
+ message: data.message || 'Feedback sent! Thank you.',
89
+ feedback_id: data.feedback_id,
90
+ };
91
+ }
92
+ catch (error) {
93
+ const errorMessage = error instanceof Error ? error.message : String(error);
94
+ throw new Error(`Failed to send feedback: ${errorMessage}`);
95
+ }
96
+ },
97
+ };
98
+ export default feedbackTool;
@@ -0,0 +1,22 @@
1
+ interface HelpResult {
2
+ topic: string;
3
+ content: string;
4
+ }
5
+ export declare const helpTool: {
6
+ name: string;
7
+ title: string;
8
+ description: string;
9
+ inputSchema: {
10
+ type: "object";
11
+ properties: {
12
+ topic: {
13
+ type: string;
14
+ description: string;
15
+ enum: string[];
16
+ };
17
+ };
18
+ required: never[];
19
+ };
20
+ handler(args: unknown): Promise<HelpResult>;
21
+ };
22
+ export default helpTool;
@@ -0,0 +1,482 @@
1
+ // ============================================================================
2
+ // Help Tool
3
+ // Self-documenting system for the Librarian MCP
4
+ // ============================================================================
5
+ // ============================================================================
6
+ // Help Content
7
+ // ============================================================================
8
+ const HELP_TOPICS = {
9
+ overview: `LIBRARIAN - Memory layer for AI agents
10
+
11
+ Your library lives in .librarian/ with three folders:
12
+ - local/ Your knowledge (created via record())
13
+ - imported/ Downloaded books (via library_buy())
14
+ - packages/ Git-synced packages
15
+
16
+ QUICK START:
17
+ brief({ query: "auth" }) Check what we know before diving in
18
+ record({ insight: "..." }) Save what we learned
19
+ mark_hit({ path: "..." }) This entry helped
20
+
21
+ MARKETPLACE:
22
+ auth({ action: "login" }) Connect your Telvok account
23
+ library_search({ ... }) Find books
24
+ library_buy({ ... }) Purchase or claim a book
25
+ my_books() View your books
26
+ sync() Get updates for owned books
27
+ rate_book({ ... }) Rate a purchased book
28
+
29
+ SELLING:
30
+ library_publish({ ... }) Publish entries as a book
31
+ seller_analytics() View sales and reviews
32
+
33
+ BOUNTIES:
34
+ bounty_create({ ... }) Post a knowledge request
35
+ bounty_list() Browse available bounties
36
+ bounty_claim({ ... }) Claim a bounty to fulfill
37
+ bounty_submit({ ... }) Submit your solution
38
+ my_bounties() View your bounties
39
+
40
+ Run help({ topic: "name" }) for details on any tool.`,
41
+ brief: `brief({ query?, limit?, include_library? })
42
+
43
+ Check what we already know before diving in.
44
+
45
+ PARAMETERS:
46
+ query What are you working on? (optional)
47
+ limit Max entries to return (default: 5)
48
+ include_library Also search Telvok (default: false)
49
+
50
+ EXAMPLES:
51
+ brief({ query: "stripe webhooks" })
52
+ brief({ query: "auth", include_library: true })
53
+ brief({}) Returns recent entries
54
+
55
+ RANKING: 60% recency + 40% hits. Entries that helped bubble up.
56
+
57
+ When an entry helps, call mark_hit() so it ranks higher next time.`,
58
+ record: `record({ insight, intent?, reasoning?, context?, example?, title? })
59
+
60
+ Save knowledge worth keeping. Call this proactively!
61
+
62
+ PARAMETERS:
63
+ insight (required) What did we learn?
64
+ intent What were we trying to accomplish?
65
+ reasoning Why does this work?
66
+ context Topic, area, or when this applies
67
+ example Code snippet or illustration
68
+ title Entry title (auto-generated if not provided)
69
+
70
+ EXAMPLES:
71
+ record({ insight: "Stripe webhooks need idempotency checks" })
72
+
73
+ record({
74
+ intent: "Setting up auth flow",
75
+ insight: "Add 30s buffer to token validation for clock skew",
76
+ reasoning: "Server clocks drift between services",
77
+ context: "auth, tokens"
78
+ })
79
+
80
+ QUALITY BAR: "I wish we knew this yesterday"`,
81
+ auth: `auth({ action })
82
+
83
+ Connect to your Telvok account.
84
+
85
+ ACTIONS:
86
+ login Start device code flow
87
+ complete Finish login after browser authorization
88
+ status Check if authenticated
89
+ logout Remove stored credentials
90
+
91
+ FLOW:
92
+ 1. auth({ action: "login" }) Get code and URL
93
+ 2. Visit URL, authorize in browser
94
+ 3. auth({ action: "complete" }) Finish login
95
+
96
+ Credentials saved in .librarian/.auth`,
97
+ library_search: `library_search({ query, filters? })
98
+
99
+ Search Telvok library for books.
100
+
101
+ PARAMETERS:
102
+ query Search terms
103
+ filters Optional filters:
104
+ - pricing: "open" | "one_time" | "subscription"
105
+ - tags: ["tag1", "tag2"]
106
+ - min_rating: 1-5
107
+
108
+ EXAMPLES:
109
+ library_search({ query: "react patterns" })
110
+ library_search({ query: "auth", filters: { pricing: "open" } })`,
111
+ library_buy: `library_buy({ slug })
112
+
113
+ Purchase or claim a book from Telvok.
114
+
115
+ PARAMETERS:
116
+ slug Book slug from search results
117
+
118
+ BEHAVIOR:
119
+ Free (open) books: Instantly adds to library
120
+ Paid books: Returns checkout URL
121
+
122
+ EXAMPLE:
123
+ library_buy({ slug: "react-best-practices" })
124
+
125
+ After purchase, use sync() for updates.`,
126
+ rate_book: `rate_book({ slug, rating, title?, comment? })
127
+
128
+ Rate a book you've purchased.
129
+
130
+ PARAMETERS:
131
+ slug Book slug to rate
132
+ rating 1 to 5 stars
133
+ title Optional review title
134
+ comment Optional review comment
135
+
136
+ EXAMPLES:
137
+ rate_book({ slug: "auth-patterns", rating: 5 })
138
+ rate_book({
139
+ slug: "stripe-patterns",
140
+ rating: 4,
141
+ title: "Saved me hours",
142
+ comment: "Webhook section was exactly what I needed"
143
+ })
144
+
145
+ Ratings help surface quality content.`,
146
+ sync: `sync({ slug?, force?, include_content? })
147
+
148
+ Check for and receive updates to owned books.
149
+
150
+ PARAMETERS:
151
+ slug Specific book (omit for all)
152
+ force Include manual preference books
153
+ include_content Download open book content
154
+
155
+ SYNC PREFERENCES (per-book):
156
+ auto Synced automatically (default)
157
+ manual Requires force: true
158
+ pinned Never synced
159
+
160
+ EXAMPLES:
161
+ sync()
162
+ sync({ slug: "premium-patterns" })
163
+ sync({ force: true })`,
164
+ my_books: `my_books({ filter? })
165
+
166
+ View your published and purchased books.
167
+
168
+ PARAMETERS:
169
+ filter "all" (default), "published", or "purchased"
170
+
171
+ EXAMPLES:
172
+ my_books()
173
+ my_books({ filter: "published" })
174
+
175
+ Shows slugs for sync(), rate_book(), etc.`,
176
+ seller_analytics: `seller_analytics()
177
+
178
+ View analytics for books you've published.
179
+
180
+ SHOWS:
181
+ - Total revenue and purchases
182
+ - Per-book breakdown
183
+ - Recent reviews
184
+ - Hit counts (query frequency)
185
+
186
+ Requires authentication.`,
187
+ mark_hit: `mark_hit({ path })
188
+
189
+ Mark an entry as helpful. Call when brief() helped.
190
+
191
+ PARAMETERS:
192
+ path Path to entry (from brief() results)
193
+
194
+ EXAMPLE:
195
+ mark_hit({ path: "local/stripe-webhooks.md" })
196
+
197
+ Fire and forget. Entries with more hits rank higher.`,
198
+ adopt: `adopt({ path, title? })
199
+
200
+ Make imported knowledge yours.
201
+
202
+ When an imported entry proves useful, adopt it into local/.
203
+
204
+ PARAMETERS:
205
+ path Path to entry (e.g., "imported/package/entry")
206
+ title New title (optional)
207
+
208
+ EXAMPLE:
209
+ adopt({ path: "imported/stripe-patterns/webhooks" })`,
210
+ library_publish: `library_publish({ name, description?, pricing, entries?, attestation })
211
+
212
+ Publish local entries as a book on Telvok.
213
+
214
+ PARAMETERS:
215
+ name Book name
216
+ description Short description
217
+ pricing { type: "open" | "one_time" | "subscription", price_cents? }
218
+ entries Entry paths to include (default: all local/)
219
+ attestation { original_work: true, terms_accepted: true }
220
+
221
+ EXAMPLES:
222
+ library_publish({
223
+ name: "React Patterns",
224
+ pricing: { type: "open" },
225
+ attestation: { original_work: true, terms_accepted: true }
226
+ })
227
+
228
+ Paid books require Stripe Connect setup.`,
229
+ feedback: `feedback({ message, type? })
230
+
231
+ Send feedback to the Telvok team.
232
+
233
+ PARAMETERS:
234
+ message Your feedback (5-5000 characters)
235
+ type bug | feature | question | general
236
+
237
+ EXAMPLES:
238
+ feedback({ message: "Sync times out on large books", type: "bug" })
239
+ feedback({ message: "Would love author filtering", type: "feature" })
240
+
241
+ We read every message!`,
242
+ bounty_create: `bounty_create({ title, amount_cents, description?, tags?, expires_days? })
243
+
244
+ Create a knowledge bounty for others to fulfill.
245
+
246
+ PARAMETERS:
247
+ title What you need (3+ chars)
248
+ amount_cents Bounty reward (min 500 = $5)
249
+ description Detailed requirements (optional)
250
+ tags Topic tags (optional)
251
+ expires_days Days until expiry (default: 30)
252
+
253
+ EXAMPLES:
254
+ bounty_create({
255
+ title: "Stripe webhook patterns",
256
+ amount_cents: 1000,
257
+ description: "Need idempotency and retry handling examples"
258
+ })
259
+
260
+ FLOW:
261
+ 1. Create bounty → Get Stripe checkout URL
262
+ 2. Pay to fund bounty
263
+ 3. Bounty becomes visible for claims
264
+
265
+ Platform fee: 20%`,
266
+ bounty_list: `bounty_list({ query?, tags?, status?, limit? })
267
+
268
+ Browse available bounties to fulfill.
269
+
270
+ PARAMETERS:
271
+ query Search terms (optional)
272
+ tags Filter by tags (optional, case-sensitive!)
273
+ status "open" (default) or "all"
274
+ limit Max results (default: 20)
275
+
276
+ EXAMPLES:
277
+ bounty_list()
278
+ bounty_list({ query: "stripe" })
279
+ bounty_list({ tags: ["auth", "security"] })
280
+ bounty_list({ status: "all", limit: 50 })
281
+
282
+ NOTE: Tags are case-sensitive ("stripe" ≠ "STRIPE")
283
+
284
+ Use bounty_claim() to claim a bounty you can fulfill.`,
285
+ bounty_claim: `bounty_claim({ bounty_id })
286
+
287
+ Claim a bounty you want to fulfill.
288
+
289
+ PARAMETERS:
290
+ bounty_id UUID from bounty_list()
291
+
292
+ REQUIREMENTS:
293
+ - Must be authenticated
294
+ - Cannot claim your own bounty
295
+ - Bounty must be open (funded, not claimed)
296
+
297
+ EXAMPLE:
298
+ bounty_claim({ bounty_id: "abc123..." })
299
+
300
+ AFTER CLAIMING:
301
+ 1. Publish relevant book via library_publish()
302
+ 2. Submit with bounty_submit()
303
+ 3. Creator reviews and approves/rejects`,
304
+ bounty_submit: `bounty_submit({ bounty_id, book_slug })
305
+
306
+ Submit a published book to fulfill a claimed bounty.
307
+
308
+ PARAMETERS:
309
+ bounty_id The bounty you claimed
310
+ book_slug Slug of your published book
311
+
312
+ REQUIREMENTS:
313
+ - Must have claimed this bounty
314
+ - Book must be published
315
+
316
+ EXAMPLE:
317
+ bounty_submit({
318
+ bounty_id: "abc123...",
319
+ book_slug: "stripe-webhook-patterns"
320
+ })
321
+
322
+ AFTER SUBMISSION:
323
+ Creator has 7 days to review. If approved, you receive payment.
324
+ If no response, auto-approved after deadline.`,
325
+ my_bounties: `my_bounties({ role? })
326
+
327
+ View bounties you've created or claimed.
328
+
329
+ PARAMETERS:
330
+ role "all" (default), "creator", or "claimer" (case-insensitive)
331
+
332
+ EXAMPLES:
333
+ my_bounties()
334
+ my_bounties({ role: "creator" })
335
+ my_bounties({ role: "claimer" })
336
+
337
+ Shows status, amounts, and deadlines for your bounties.`,
338
+ delete: `delete({ path?, query?, confirm? })
339
+
340
+ Delete entries from your local library.
341
+
342
+ PARAMETERS:
343
+ path Exact path to entry (e.g., "local/entry-name.md")
344
+ query Search query to find entries
345
+ confirm Required to actually delete (default: false)
346
+
347
+ THREE-STEP WORKFLOW:
348
+ 1. delete({ query: "..." }) Find matching entries
349
+ 2. delete({ path: "..." }) Preview what will be deleted
350
+ 3. delete({ path: "...", confirm: true }) Actually delete
351
+
352
+ EXAMPLES:
353
+ delete({ query: "old auth" })
354
+ delete({ path: "local/outdated-entry.md" })
355
+ delete({ path: "local/outdated-entry.md", confirm: true })
356
+
357
+ SCOPE: Only deletes from local/ (your entries).
358
+ Cannot delete imported/ or packages/ content.`,
359
+ library_download: `library_download({ slug })
360
+
361
+ Download a free (open) book to your local library.
362
+
363
+ PARAMETERS:
364
+ slug Book slug from search results
365
+
366
+ BEHAVIOR:
367
+ Only works for open (free) books.
368
+ Downloads content to .librarian/imported/<slug>/
369
+ Paid books use cloud API — no local download.
370
+
371
+ EXAMPLE:
372
+ library_download({ slug: "react-patterns" })`,
373
+ import_memories: `import_memories({ format, path, source_name? })
374
+
375
+ Import knowledge from other AI tools.
376
+
377
+ PARAMETERS:
378
+ format jsonl | markdown | cursor | json | sqlite
379
+ path Path to the file or directory
380
+ source_name Label for the source (optional)
381
+
382
+ SUPPORTED SOURCES:
383
+ jsonl - Anthropic MCP Memory, mcp-knowledge-graph
384
+ markdown - Obsidian, Basic Memory MCP
385
+ cursor - Cursor Memory Bank (.cursor-memory/)
386
+ json - Simple memory servers
387
+ sqlite - mcp-memory-service, SQLite-vec
388
+
389
+ EXAMPLES:
390
+ import_memories({ format: "jsonl", path: "~/.aim/memory.jsonl" })
391
+ import_memories({ format: "sqlite", path: "~/memory.db", source_name: "old-project" })
392
+
393
+ Run rebuild_index() after importing for semantic search.`,
394
+ rebuild_index: `rebuild_index({ force? })
395
+
396
+ Rebuild the semantic search index for all entries.
397
+
398
+ PARAMETERS:
399
+ force Rebuild even if index exists (default: false)
400
+
401
+ BEHAVIOR:
402
+ Scans local/ and imported/ for all .md files
403
+ Generates 384-dim embeddings using all-MiniLM-L6-v2
404
+ Chunks long content at sentence boundaries (~500 chars)
405
+ First run downloads ~30MB model (cached in .librarian/models/)
406
+
407
+ WHEN TO USE:
408
+ After import_memories() — new entries need indexing
409
+ After sync() — subscription updates need indexing
410
+ After delete() — remove stale embeddings
411
+ If search results seem wrong or stale
412
+
413
+ EXAMPLE:
414
+ rebuild_index()
415
+ rebuild_index({ force: true })`,
416
+ unsubscribe: `unsubscribe({ slug })
417
+
418
+ Cancel a subscription to a book.
419
+
420
+ PARAMETERS:
421
+ slug Book slug (from my_books())
422
+
423
+ EXAMPLE:
424
+ unsubscribe({ slug: "premium-patterns" })
425
+
426
+ Only works for subscription purchases.
427
+ One-time purchases grant permanent access.`,
428
+ };
429
+ // ============================================================================
430
+ // Tool Definition
431
+ // ============================================================================
432
+ export const helpTool = {
433
+ name: 'help',
434
+ title: 'Get Help',
435
+ description: `Get help on Librarian tools and workflows.
436
+
437
+ USE THIS TOOL WHEN:
438
+ - User asks "how do I use X" about Librarian features
439
+ - Need to explain a tool's parameters or behavior
440
+ - User is confused about Librarian workflows
441
+
442
+ TRIGGER PATTERNS:
443
+ - "How does brief work?" → help({ topic: "brief" })
444
+ - "Help with publishing" → help({ topic: "library_publish" })
445
+ - "What can Librarian do?" → help()
446
+
447
+ Examples:
448
+ - help() - Overview of all tools
449
+ - help({ topic: "brief" }) - Details on brief()
450
+ - help({ topic: "auth" }) - Details on authentication`,
451
+ inputSchema: {
452
+ type: 'object',
453
+ properties: {
454
+ topic: {
455
+ type: 'string',
456
+ description: 'Specific topic to get help on',
457
+ enum: Object.keys(HELP_TOPICS),
458
+ },
459
+ },
460
+ required: [],
461
+ },
462
+ async handler(args) {
463
+ const { topic } = (args || {});
464
+ const helpTopic = topic?.toLowerCase() || 'overview';
465
+ const content = HELP_TOPICS[helpTopic];
466
+ if (!content) {
467
+ const availableTopics = Object.keys(HELP_TOPICS).filter(t => t !== 'overview').join(', ');
468
+ return {
469
+ topic: 'error',
470
+ content: `Unknown topic: "${topic}"\n\nAvailable topics: ${availableTopics}`,
471
+ };
472
+ }
473
+ return {
474
+ topic: helpTopic,
475
+ content: content.trim(),
476
+ };
477
+ },
478
+ };
479
+ // ============================================================================
480
+ // Export
481
+ // ============================================================================
482
+ export default helpTool;
@@ -8,6 +8,7 @@ export interface ImportResult {
8
8
  }
9
9
  export declare const importMemoriesTool: {
10
10
  name: string;
11
+ title: string;
11
12
  description: string;
12
13
  inputSchema: {
13
14
  type: "object";
@@ -8,25 +8,26 @@ import { parseJSONL, parseMarkdown, parseCursorMemory, parseJSON, parseSQLite }
8
8
  // ============================================================================
9
9
  export const importMemoriesTool = {
10
10
  name: 'import_memories',
11
+ title: 'Import External Memories',
11
12
  description: `Import memories from other AI tools into Librarian.
12
13
 
13
- Use this when you see memory files from other AI tools (Cursor .cursor-memory/, Anthropic ~/.aim/, mcp-memory-service .db files, Obsidian vaults) or when user mentions having knowledge in other tools. Import them so past knowledge becomes searchable.
14
+ USE THIS TOOL WHEN:
15
+ - You see .cursor-memory/, ~/.aim/, or other AI memory files
16
+ - User mentions having knowledge in Cursor, Obsidian, or other tools
17
+ - User wants to consolidate memories from multiple sources
14
18
 
15
- Supported formats:
16
- - jsonl: Anthropic MCP Memory, mcp-knowledge-graph (.jsonl files)
17
- - markdown: Basic Memory, Obsidian, any .md files
18
- - cursor: Cursor Memory Bank (.cursor-memory/)
19
- - json: Simple memory servers, knowledge stores (.json files)
20
- - sqlite: mcp-memory-service, SQLite-vec (.db, .sqlite files)
19
+ Supported: jsonl, markdown, cursor, json, sqlite formats.
20
+ Imports go to .librarian/local/[source]/ and are auto-indexed.
21
21
 
22
- Imports go to .librarian/local/[source-name]/ and are automatically indexed for semantic search.
22
+ TRIGGER PATTERNS:
23
+ - See .cursor-memory/ folder → import_memories({ format: "cursor", path: ".cursor-memory/" })
24
+ - "Import my Obsidian notes" → import_memories({ format: "markdown", path: "~/notes/" })
25
+ - User mentions other AI memory → offer to import it
23
26
 
24
27
  Examples:
25
- - import_memories({ format: "jsonl", path: "~/.aim/memory.jsonl", source_name: "anthropic-memory" })
26
- - import_memories({ format: "markdown", path: "~/basic-memory/", source_name: "basic-memory" })
27
28
  - import_memories({ format: "cursor", path: ".cursor-memory/", source_name: "cursor-memory" })
28
- - import_memories({ format: "json", path: "~/memories.json", source_name: "json-memory" })
29
- - import_memories({ format: "sqlite", path: "~/memory.db", source_name: "sqlite-memory" })`,
29
+ - import_memories({ format: "markdown", path: "~/basic-memory/", source_name: "basic-memory" })
30
+ - import_memories({ format: "jsonl", path: "~/.aim/memory.jsonl", source_name: "anthropic-memory" })`,
30
31
  inputSchema: {
31
32
  type: 'object',
32
33
  properties: {
@@ -58,7 +59,11 @@ Examples:
58
59
  // Setup output directory
59
60
  const libraryPath = getLibraryPath();
60
61
  const localPath = getLocalPath(libraryPath);
61
- const outputPath = path.join(localPath, sourceName);
62
+ const outputPath = path.resolve(localPath, sourceName);
63
+ // Prevent path traversal in output directory
64
+ if (!outputPath.startsWith(path.resolve(localPath))) {
65
+ throw new Error('Invalid source_name: output path must be within local/');
66
+ }
62
67
  // Check if output directory already exists
63
68
  try {
64
69
  await fs.access(outputPath);
@@ -4,3 +4,14 @@ export { adoptTool } from './adopt.js';
4
4
  export { markHitTool } from './mark-hit.js';
5
5
  export { importMemoriesTool } from './import-memories.js';
6
6
  export { rebuildIndexTool } from './rebuild-index.js';
7
+ export { authTool, loadApiKey } from './auth.js';
8
+ export { myBooksTool } from './my-books.js';
9
+ export { syncTool } from './sync.js';
10
+ export { sellerAnalyticsTool } from './seller-analytics.js';
11
+ export { rateBookTool } from './rate-book.js';
12
+ export { helpTool } from './help.js';
13
+ export { bountyCreateTool } from './bounty-create.js';
14
+ export { bountyListTool } from './bounty-list.js';
15
+ export { bountyClaimTool } from './bounty-claim.js';
16
+ export { bountySubmitTool } from './bounty-submit.js';
17
+ export { myBountiesTool } from './my-bounties.js';
@@ -4,3 +4,15 @@ export { adoptTool } from './adopt.js';
4
4
  export { markHitTool } from './mark-hit.js';
5
5
  export { importMemoriesTool } from './import-memories.js';
6
6
  export { rebuildIndexTool } from './rebuild-index.js';
7
+ export { authTool, loadApiKey } from './auth.js';
8
+ export { myBooksTool } from './my-books.js';
9
+ export { syncTool } from './sync.js';
10
+ export { sellerAnalyticsTool } from './seller-analytics.js';
11
+ export { rateBookTool } from './rate-book.js';
12
+ export { helpTool } from './help.js';
13
+ // Bounty tools
14
+ export { bountyCreateTool } from './bounty-create.js';
15
+ export { bountyListTool } from './bounty-list.js';
16
+ export { bountyClaimTool } from './bounty-claim.js';
17
+ export { bountySubmitTool } from './bounty-submit.js';
18
+ export { myBountiesTool } from './my-bounties.js';