@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
package/dist/server.js CHANGED
@@ -2,12 +2,85 @@
2
2
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
3
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
4
  import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
5
+ import { LibrarianError } from './library/errors.js';
5
6
  import { briefTool } from './tools/brief.js';
6
7
  import { recordTool } from './tools/record.js';
7
8
  import { adoptTool } from './tools/adopt.js';
8
9
  import { markHitTool } from './tools/mark-hit.js';
9
10
  import { importMemoriesTool } from './tools/import-memories.js';
10
11
  import { rebuildIndexTool } from './tools/rebuild-index.js';
12
+ import { authTool } from './tools/auth.js';
13
+ import { librarySearchTool } from './tools/library-search.js';
14
+ import { libraryBuyTool } from './tools/library-buy.js';
15
+ import { libraryDownloadTool } from './tools/library-download.js';
16
+ import { libraryPublishTool } from './tools/library-publish.js';
17
+ import { myBooksTool } from './tools/my-books.js';
18
+ import { syncTool } from './tools/sync.js';
19
+ import { sellerAnalyticsTool } from './tools/seller-analytics.js';
20
+ import { rateBookTool } from './tools/rate-book.js';
21
+ import { helpTool } from './tools/help.js';
22
+ import { feedbackTool } from './tools/feedback.js';
23
+ import { bountyCreateTool } from './tools/bounty-create.js';
24
+ import { bountyListTool } from './tools/bounty-list.js';
25
+ import { bountyClaimTool } from './tools/bounty-claim.js';
26
+ import { bountySubmitTool } from './tools/bounty-submit.js';
27
+ import { myBountiesTool } from './tools/my-bounties.js';
28
+ import { deleteTool } from './tools/delete.js';
29
+ import { unsubscribeTool } from './tools/unsubscribe.js';
30
+ const allTools = [
31
+ // Core tools — local knowledge management
32
+ { tool: briefTool, group: 'core' },
33
+ { tool: recordTool, group: 'core' },
34
+ { tool: adoptTool, group: 'core' },
35
+ { tool: markHitTool, group: 'core' },
36
+ { tool: importMemoriesTool, group: 'core' },
37
+ { tool: rebuildIndexTool, group: 'core' },
38
+ { tool: deleteTool, group: 'core' },
39
+ // Marketplace tools — cloud features
40
+ { tool: librarySearchTool, group: 'marketplace' },
41
+ { tool: libraryBuyTool, group: 'marketplace' },
42
+ { tool: libraryDownloadTool, group: 'marketplace' },
43
+ { tool: libraryPublishTool, group: 'marketplace' },
44
+ { tool: myBooksTool, group: 'marketplace' },
45
+ { tool: syncTool, group: 'marketplace' },
46
+ { tool: sellerAnalyticsTool, group: 'marketplace' },
47
+ { tool: rateBookTool, group: 'marketplace' },
48
+ { tool: bountyCreateTool, group: 'marketplace' },
49
+ { tool: bountyListTool, group: 'marketplace' },
50
+ { tool: bountyClaimTool, group: 'marketplace' },
51
+ { tool: bountySubmitTool, group: 'marketplace' },
52
+ { tool: myBountiesTool, group: 'marketplace' },
53
+ { tool: unsubscribeTool, group: 'marketplace' },
54
+ // Both — shared across core and marketplace
55
+ { tool: authTool, group: 'both' },
56
+ { tool: helpTool, group: 'both' },
57
+ { tool: feedbackTool, group: 'both' },
58
+ ];
59
+ function parseServerMode() {
60
+ const serverArg = process.argv.find(a => a.startsWith('--server='));
61
+ if (!serverArg)
62
+ return 'all';
63
+ const mode = serverArg.split('=')[1];
64
+ if (mode === 'core' || mode === 'marketplace')
65
+ return mode;
66
+ console.error(`Unknown --server mode: "${mode}". Valid: core, marketplace. Defaulting to all.`);
67
+ return 'all';
68
+ }
69
+ const serverMode = parseServerMode();
70
+ function isToolIncluded(entry) {
71
+ if (serverMode === 'all')
72
+ return true;
73
+ return entry.group === serverMode || entry.group === 'both';
74
+ }
75
+ const enabledTools = allTools.filter(isToolIncluded);
76
+ // Build lookup map for call handler
77
+ const toolMap = new Map();
78
+ for (const entry of enabledTools) {
79
+ toolMap.set(entry.tool.name, entry.tool);
80
+ }
81
+ // ---------------------------------------------------------------------------
82
+ // MCP Server
83
+ // ---------------------------------------------------------------------------
11
84
  const server = new Server({
12
85
  name: 'librarian',
13
86
  version: '1.0.0',
@@ -19,67 +92,29 @@ const server = new Server({
19
92
  // List available tools
20
93
  server.setRequestHandler(ListToolsRequestSchema, async () => {
21
94
  return {
22
- tools: [
23
- {
24
- name: briefTool.name,
25
- description: briefTool.description,
26
- inputSchema: briefTool.inputSchema,
27
- },
28
- {
29
- name: recordTool.name,
30
- description: recordTool.description,
31
- inputSchema: recordTool.inputSchema,
32
- },
33
- {
34
- name: adoptTool.name,
35
- description: adoptTool.description,
36
- inputSchema: adoptTool.inputSchema,
37
- },
38
- {
39
- name: markHitTool.name,
40
- description: markHitTool.description,
41
- inputSchema: markHitTool.inputSchema,
42
- },
43
- {
44
- name: importMemoriesTool.name,
45
- description: importMemoriesTool.description,
46
- inputSchema: importMemoriesTool.inputSchema,
47
- },
48
- {
49
- name: rebuildIndexTool.name,
50
- description: rebuildIndexTool.description,
51
- inputSchema: rebuildIndexTool.inputSchema,
52
- },
53
- ],
95
+ tools: enabledTools.map(({ tool }) => {
96
+ const entry = {
97
+ name: tool.name,
98
+ description: tool.description,
99
+ inputSchema: tool.inputSchema,
100
+ };
101
+ if (tool.title)
102
+ entry.title = tool.title;
103
+ if (tool.outputSchema)
104
+ entry.outputSchema = tool.outputSchema;
105
+ return entry;
106
+ }),
54
107
  };
55
108
  });
56
109
  // Handle tool calls
57
110
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
58
111
  const { name, arguments: args } = request.params;
59
112
  try {
60
- let result;
61
- switch (name) {
62
- case 'brief':
63
- result = await briefTool.handler(args);
64
- break;
65
- case 'record':
66
- result = await recordTool.handler(args);
67
- break;
68
- case 'adopt':
69
- result = await adoptTool.handler(args);
70
- break;
71
- case 'mark_hit':
72
- result = await markHitTool.handler(args);
73
- break;
74
- case 'import_memories':
75
- result = await importMemoriesTool.handler(args);
76
- break;
77
- case 'rebuild_index':
78
- result = await rebuildIndexTool.handler(args);
79
- break;
80
- default:
81
- throw new Error(`Unknown tool: ${name}`);
113
+ const tool = toolMap.get(name);
114
+ if (!tool) {
115
+ throw new Error(`Unknown tool: ${name}`);
82
116
  }
117
+ const result = await tool.handler(args);
83
118
  return {
84
119
  content: [
85
120
  {
@@ -90,6 +125,19 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
90
125
  };
91
126
  }
92
127
  catch (error) {
128
+ // Handle LibrarianError with error codes
129
+ if (error instanceof LibrarianError) {
130
+ return {
131
+ content: [
132
+ {
133
+ type: 'text',
134
+ text: JSON.stringify(error.toJSON()),
135
+ },
136
+ ],
137
+ isError: true,
138
+ };
139
+ }
140
+ // Handle generic errors
93
141
  const message = error instanceof Error ? error.message : String(error);
94
142
  return {
95
143
  content: [
@@ -5,6 +5,7 @@ export interface AdoptResult {
5
5
  }
6
6
  export declare const adoptTool: {
7
7
  name: string;
8
+ title: string;
8
9
  description: string;
9
10
  inputSchema: {
10
11
  type: "object";
@@ -1,20 +1,29 @@
1
1
  import * as fs from 'fs/promises';
2
2
  import * as path from 'path';
3
3
  import matter from 'gray-matter';
4
- import { getLibraryPath, getImportedPath, getLocalPath } from '../library/storage.js';
4
+ import { getLibraryPath, getImportedPath, getLocalPath, getPackagesPath } from '../library/storage.js';
5
5
  // ============================================================================
6
6
  // Tool Definition
7
7
  // ============================================================================
8
8
  export const adoptTool = {
9
9
  name: 'adopt',
10
- description: `Make imported knowledge ours.
10
+ title: 'Adopt Imported Entry',
11
+ description: `Move an imported/packages entry to local library for editing.
11
12
 
12
- When an entry from an imported package proves useful, adopt it into our
13
- local library. It graduates from "their knowledge" to "our knowledge" -
14
- now we can edit and evolve it.
13
+ USE THIS TOOL WHEN:
14
+ - An imported entry is useful but needs customization
15
+ - Want to evolve third-party knowledge with our learnings
16
+ - Entry from packages/ or imported/ should become our own
17
+
18
+ Copies to local/ where we can edit it. Original stays in place.
19
+
20
+ TRIGGER PATTERNS:
21
+ - Entry from brief() needs edits → adopt({ path: "..." })
22
+ - "Make that entry ours" → adopt({ path: "...", title: "Our version" })
23
+ - Want to customize purchased content → adopt({ path: "packages/..." })
15
24
 
16
25
  Examples:
17
- - adopt({ path: "imported/stripe-patterns/webhook-idempotency" })
26
+ - adopt({ path: "packages/stripe-patterns/webhook-idempotency" })
18
27
  - adopt({ path: "imported/auth-patterns/token-refresh", title: "Our token refresh" })`,
19
28
  inputSchema: {
20
29
  type: 'object',
@@ -37,22 +46,40 @@ Examples:
37
46
  }
38
47
  const libraryPath = getLibraryPath();
39
48
  const importedPath = getImportedPath(libraryPath);
49
+ const packagesPath = getPackagesPath(libraryPath);
40
50
  const localPath = getLocalPath(libraryPath);
41
- // Normalize path: strip "imported/" prefix if present, add .md if missing
51
+ // Normalize path: strip "imported/" or "packages/" prefix if present, add .md if missing
42
52
  let normalizedPath = entryPath;
43
53
  if (normalizedPath.startsWith('imported/')) {
44
54
  normalizedPath = normalizedPath.slice('imported/'.length);
45
55
  }
56
+ else if (normalizedPath.startsWith('packages/')) {
57
+ normalizedPath = normalizedPath.slice('packages/'.length);
58
+ }
46
59
  if (!normalizedPath.endsWith('.md')) {
47
60
  normalizedPath += '.md';
48
61
  }
49
- const sourcePath = path.join(importedPath, normalizedPath);
50
- // Check if source exists
62
+ // Try both imported/ and packages/ paths
63
+ let sourcePath = path.resolve(importedPath, normalizedPath);
64
+ // Prevent path traversal
65
+ if (!sourcePath.startsWith(path.resolve(importedPath)) && !sourcePath.startsWith(path.resolve(packagesPath))) {
66
+ throw new Error('Invalid path: must be within imported/ or packages/');
67
+ }
51
68
  try {
52
69
  await fs.access(sourcePath);
53
70
  }
54
71
  catch {
55
- throw new Error(`Entry not found: ${entryPath}`);
72
+ // Try packages path (for library downloads)
73
+ sourcePath = path.resolve(packagesPath, normalizedPath);
74
+ if (!sourcePath.startsWith(path.resolve(packagesPath))) {
75
+ throw new Error('Invalid path: must be within imported/ or packages/');
76
+ }
77
+ try {
78
+ await fs.access(sourcePath);
79
+ }
80
+ catch {
81
+ throw new Error(`Entry not found: ${entryPath}`);
82
+ }
56
83
  }
57
84
  // Read source file
58
85
  const content = await fs.readFile(sourcePath, 'utf-8');
@@ -0,0 +1,69 @@
1
+ export interface AuthData {
2
+ api_key: string;
3
+ user_email: string;
4
+ user_id: string;
5
+ created_at: string;
6
+ expires_at?: string;
7
+ }
8
+ export interface AuthResult {
9
+ authenticated: boolean;
10
+ user_email?: string;
11
+ user_id?: string;
12
+ message: string;
13
+ verification_url?: string;
14
+ user_code?: string;
15
+ expires_at?: string;
16
+ days_until_expiry?: number;
17
+ }
18
+ export declare const authTool: {
19
+ name: string;
20
+ title: string;
21
+ description: string;
22
+ inputSchema: {
23
+ type: "object";
24
+ properties: {
25
+ action: {
26
+ type: string;
27
+ enum: string[];
28
+ description: string;
29
+ };
30
+ };
31
+ required: string[];
32
+ };
33
+ outputSchema: {
34
+ type: "object";
35
+ properties: {
36
+ authenticated: {
37
+ type: string;
38
+ };
39
+ user_email: {
40
+ type: string;
41
+ };
42
+ user_id: {
43
+ type: string;
44
+ };
45
+ message: {
46
+ type: string;
47
+ };
48
+ verification_url: {
49
+ type: string;
50
+ };
51
+ user_code: {
52
+ type: string;
53
+ };
54
+ expires_at: {
55
+ type: string;
56
+ };
57
+ days_until_expiry: {
58
+ type: string;
59
+ };
60
+ };
61
+ required: string[];
62
+ };
63
+ handler(args: unknown): Promise<AuthResult>;
64
+ };
65
+ /**
66
+ * Load saved API key from auth file
67
+ * Used by other tools that need authenticated access
68
+ */
69
+ export declare function loadApiKey(): Promise<string | null>;