tiddlywiki-mcp-server 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +242 -0
  3. package/dist/embeddings/database.d.ts +53 -0
  4. package/dist/embeddings/database.d.ts.map +1 -0
  5. package/dist/embeddings/database.js +212 -0
  6. package/dist/embeddings/database.js.map +1 -0
  7. package/dist/embeddings/ollama-client.d.ts +39 -0
  8. package/dist/embeddings/ollama-client.d.ts.map +1 -0
  9. package/dist/embeddings/ollama-client.js +190 -0
  10. package/dist/embeddings/ollama-client.js.map +1 -0
  11. package/dist/embeddings/sync-worker.d.ts +49 -0
  12. package/dist/embeddings/sync-worker.d.ts.map +1 -0
  13. package/dist/embeddings/sync-worker.js +244 -0
  14. package/dist/embeddings/sync-worker.js.map +1 -0
  15. package/dist/filter-reference.d.ts +8 -0
  16. package/dist/filter-reference.d.ts.map +1 -0
  17. package/dist/filter-reference.js +159 -0
  18. package/dist/filter-reference.js.map +1 -0
  19. package/dist/index.d.ts +3 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +450 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/logger.d.ts +17 -0
  24. package/dist/logger.d.ts.map +1 -0
  25. package/dist/logger.js +33 -0
  26. package/dist/logger.js.map +1 -0
  27. package/dist/service-discovery.d.ts +24 -0
  28. package/dist/service-discovery.d.ts.map +1 -0
  29. package/dist/service-discovery.js +82 -0
  30. package/dist/service-discovery.js.map +1 -0
  31. package/dist/tiddlywiki-http.d.ts +55 -0
  32. package/dist/tiddlywiki-http.d.ts.map +1 -0
  33. package/dist/tiddlywiki-http.js +253 -0
  34. package/dist/tiddlywiki-http.js.map +1 -0
  35. package/dist/tools/create-tiddler.d.ts +15 -0
  36. package/dist/tools/create-tiddler.d.ts.map +1 -0
  37. package/dist/tools/create-tiddler.js +61 -0
  38. package/dist/tools/create-tiddler.js.map +1 -0
  39. package/dist/tools/delete-tiddler.d.ts +9 -0
  40. package/dist/tools/delete-tiddler.d.ts.map +1 -0
  41. package/dist/tools/delete-tiddler.js +40 -0
  42. package/dist/tools/delete-tiddler.js.map +1 -0
  43. package/dist/tools/index.d.ts +6 -0
  44. package/dist/tools/index.d.ts.map +1 -0
  45. package/dist/tools/index.js +7 -0
  46. package/dist/tools/index.js.map +1 -0
  47. package/dist/tools/search-tiddlers.d.ts +12 -0
  48. package/dist/tools/search-tiddlers.d.ts.map +1 -0
  49. package/dist/tools/search-tiddlers.js +189 -0
  50. package/dist/tools/search-tiddlers.js.map +1 -0
  51. package/dist/tools/types.d.ts +101 -0
  52. package/dist/tools/types.d.ts.map +1 -0
  53. package/dist/tools/types.js +55 -0
  54. package/dist/tools/types.js.map +1 -0
  55. package/dist/tools/update-tiddler.d.ts +9 -0
  56. package/dist/tools/update-tiddler.d.ts.map +1 -0
  57. package/dist/tools/update-tiddler.js +90 -0
  58. package/dist/tools/update-tiddler.js.map +1 -0
  59. package/package.json +67 -0
@@ -0,0 +1,7 @@
1
+ // ABOUTME: Barrel export for MCP tool handlers
2
+ // ABOUTME: Re-exports all tool handlers and their input schemas
3
+ export { handleSearchTiddlers, SearchTiddlersInput } from './search-tiddlers.js';
4
+ export { handleUpdateTiddler, UpdateTiddlerInput } from './update-tiddler.js';
5
+ export { handleCreateTiddler, CreateTiddlerInput, formatTiddlerPreview } from './create-tiddler.js';
6
+ export { handleDeleteTiddler, DeleteTiddlerInput } from './delete-tiddler.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,gEAAgE;AAEhE,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACpG,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { ToolResult, ToolDependencies } from './types.js';
2
+ import { SearchTiddlersInput } from './types.js';
3
+ /**
4
+ * Handle search_tiddlers tool requests.
5
+ * Supports three modes:
6
+ * - Filter-only: Pure TiddlyWiki filter expressions
7
+ * - Semantic-only: Similarity search on indexed tiddlers
8
+ * - Hybrid: Filter results, then re-rank by semantic similarity
9
+ */
10
+ export declare function handleSearchTiddlers(args: unknown, deps: ToolDependencies): Promise<ToolResult>;
11
+ export { SearchTiddlersInput };
12
+ //# sourceMappingURL=search-tiddlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-tiddlers.d.ts","sourceRoot":"","sources":["../../src/tools/search-tiddlers.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAmDjD;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,OAAO,EACb,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,UAAU,CAAC,CAwKrB;AAGD,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,189 @@
1
+ // ABOUTME: Handler for the search_tiddlers MCP tool
2
+ // ABOUTME: Supports filter-based, semantic, and hybrid search modes with pagination
3
+ import { encode } from 'gpt-tokenizer';
4
+ import { queryTiddlers, getTiddler } from '../tiddlywiki-http.js';
5
+ import { SearchTiddlersInput } from './types.js';
6
+ // Token counting and response size validation
7
+ const MAX_RESPONSE_TOKENS = 23000; // Safe threshold below ~25k limit
8
+ /**
9
+ * Count tokens in a string using gpt-tokenizer
10
+ */
11
+ function countTokens(text) {
12
+ return encode(text).length;
13
+ }
14
+ /**
15
+ * Validate response size and suggest pagination if needed.
16
+ * Returns null if response is OK, or an error message if too large.
17
+ */
18
+ function validateResponseSize(results, filter, includeText) {
19
+ const responseJson = JSON.stringify(results, null, 2);
20
+ const tokenCount = countTokens(responseJson);
21
+ if (tokenCount <= MAX_RESPONSE_TOKENS) {
22
+ return null; // Response is fine
23
+ }
24
+ // Calculate how many items would fit
25
+ const avgTokensPerItem = tokenCount / results.length;
26
+ const suggestedLimit = Math.floor(MAX_RESPONSE_TOKENS / avgTokensPerItem);
27
+ const errorMessage = `Query matched ${results.length} tiddlers but response would be ${tokenCount.toLocaleString()} tokens (exceeds ${MAX_RESPONSE_TOKENS.toLocaleString()} token limit).
28
+
29
+ To retrieve results, use the limit parameter with offset for pagination.
30
+
31
+ **Suggested query:**
32
+ \`\`\`
33
+ query_tiddlers({
34
+ filter: "${filter}",
35
+ includeText: ${includeText},
36
+ limit: ${suggestedLimit},
37
+ offset: 0
38
+ })
39
+ \`\`\`
40
+
41
+ Then increment offset by ${suggestedLimit} for subsequent batches (offset: ${suggestedLimit}, offset: ${suggestedLimit * 2}, etc.) until you've retrieved all ${results.length} tiddlers.`;
42
+ return errorMessage;
43
+ }
44
+ /**
45
+ * Handle search_tiddlers tool requests.
46
+ * Supports three modes:
47
+ * - Filter-only: Pure TiddlyWiki filter expressions
48
+ * - Semantic-only: Similarity search on indexed tiddlers
49
+ * - Hybrid: Filter results, then re-rank by semantic similarity
50
+ */
51
+ export async function handleSearchTiddlers(args, deps) {
52
+ const input = SearchTiddlersInput.parse(args);
53
+ const includeText = input.includeText ?? false;
54
+ const hasSemantic = input.semantic !== undefined;
55
+ const hasFilter = input.filter !== undefined;
56
+ // Filter-only mode
57
+ if (hasFilter && !hasSemantic) {
58
+ const offset = input.offset ?? 0;
59
+ const limit = input.limit;
60
+ const filter = input.filter;
61
+ const results = await queryTiddlers(filter, includeText, offset, limit);
62
+ // Validate response size
63
+ const sizeError = validateResponseSize(results, filter, includeText);
64
+ if (sizeError) {
65
+ return {
66
+ content: [{ type: 'text', text: sizeError }],
67
+ isError: true,
68
+ };
69
+ }
70
+ return {
71
+ content: [{ type: 'text', text: JSON.stringify(results, null, 2) }],
72
+ };
73
+ }
74
+ // Semantic mode (with optional filter)
75
+ if (hasSemantic) {
76
+ const { embeddingsDB, ollamaClient, syncWorker } = deps;
77
+ // Check if embeddings infrastructure is available
78
+ if (!embeddingsDB || !ollamaClient) {
79
+ return {
80
+ content: [
81
+ {
82
+ type: 'text',
83
+ text: JSON.stringify({
84
+ error: 'Semantic search is not available',
85
+ reason: 'Embeddings database or Ollama client not initialized',
86
+ suggestion: 'Check server logs for initialization errors',
87
+ }, null, 2),
88
+ },
89
+ ],
90
+ isError: true,
91
+ };
92
+ }
93
+ // Check if any tiddlers have been indexed
94
+ const indexedCount = embeddingsDB.getIndexedTiddlersCount();
95
+ if (indexedCount === 0) {
96
+ return {
97
+ content: [
98
+ {
99
+ type: 'text',
100
+ text: JSON.stringify({
101
+ error: 'No tiddlers have been indexed yet',
102
+ suggestion: 'The sync worker is still indexing entries. Please wait a few minutes and try again.',
103
+ status: syncWorker?.getStatus() || 'unknown',
104
+ }, null, 2),
105
+ },
106
+ ],
107
+ isError: true,
108
+ };
109
+ }
110
+ // Generate embedding for the query with search_query prefix
111
+ const semantic = input.semantic;
112
+ const queryEmbedding = await ollamaClient.generateQueryEmbedding(semantic);
113
+ // Search for similar entries
114
+ const limit = input.limit || 10;
115
+ const results = embeddingsDB.searchSimilar(queryEmbedding, limit);
116
+ // Apply optional TiddlyWiki filter for hybrid search
117
+ let filteredResults = results;
118
+ if (hasFilter) {
119
+ const filter = input.filter;
120
+ const filterMatches = await queryTiddlers(filter, false);
121
+ const filterTitles = new Set(filterMatches.map((t) => t.title));
122
+ filteredResults = results.filter((r) => filterTitles.has(r.tiddler_title));
123
+ }
124
+ // Fetch full tiddlers if includeText is true
125
+ const formattedResults = await Promise.all(filteredResults.map(async (r) => {
126
+ const result = {
127
+ tiddler_title: r.tiddler_title,
128
+ chunk_id: r.chunk_id,
129
+ similarity_score: (1 - r.distance).toFixed(4), // Convert distance to similarity
130
+ created: r.created,
131
+ modified: r.modified,
132
+ tags: r.tags,
133
+ };
134
+ // Fetch full tiddler text if requested
135
+ if (includeText) {
136
+ const fullTiddler = await getTiddler(r.tiddler_title);
137
+ if (fullTiddler) {
138
+ result.text = fullTiddler.text;
139
+ result.type = fullTiddler.type;
140
+ }
141
+ }
142
+ return result;
143
+ }));
144
+ // Validate response size
145
+ const responseJson = JSON.stringify(formattedResults, null, 2);
146
+ const tokenCount = countTokens(responseJson);
147
+ if (tokenCount > MAX_RESPONSE_TOKENS) {
148
+ const avgTokensPerItem = tokenCount / formattedResults.length;
149
+ const suggestedLimit = Math.floor(MAX_RESPONSE_TOKENS / avgTokensPerItem);
150
+ const filterParam = hasFilter ? `,\n filter: "${input.filter}"` : '';
151
+ const errorMessage = `Semantic search matched ${formattedResults.length} results but response would be ${tokenCount.toLocaleString()} tokens (exceeds ${MAX_RESPONSE_TOKENS.toLocaleString()} token limit).
152
+
153
+ To retrieve results, use the limit parameter.
154
+
155
+ **Suggested query:**
156
+ \`\`\`
157
+ search_tiddlers({
158
+ semantic: "${semantic}",
159
+ includeText: ${includeText},
160
+ limit: ${suggestedLimit}${filterParam}
161
+ })
162
+ \`\`\`
163
+
164
+ Note: Semantic search returns results ordered by similarity, so using a lower limit will return the most relevant matches.`;
165
+ return {
166
+ content: [{ type: 'text', text: errorMessage }],
167
+ isError: true,
168
+ };
169
+ }
170
+ return {
171
+ content: [
172
+ {
173
+ type: 'text',
174
+ text: JSON.stringify({
175
+ query: semantic,
176
+ total_results: formattedResults.length,
177
+ indexed_tiddlers: indexedCount,
178
+ results: formattedResults,
179
+ }, null, 2),
180
+ },
181
+ ],
182
+ };
183
+ }
184
+ // Should never reach here due to Zod validation
185
+ throw new Error('Either semantic or filter must be provided');
186
+ }
187
+ // Re-export the input schema for use in tool registration
188
+ export { SearchTiddlersInput };
189
+ //# sourceMappingURL=search-tiddlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-tiddlers.js","sourceRoot":"","sources":["../../src/tools/search-tiddlers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ import { z } from 'zod';
2
+ import type { EmbeddingsDB } from '../embeddings/database.js';
3
+ import type { OllamaClient } from '../embeddings/ollama-client.js';
4
+ import type { SyncWorker } from '../embeddings/sync-worker.js';
5
+ /**
6
+ * Standard result type returned by all tool handlers.
7
+ * Matches the MCP SDK's expected response format.
8
+ * Uses index signature to allow additional properties the SDK may expect.
9
+ */
10
+ export interface ToolResult {
11
+ [key: string]: unknown;
12
+ content: Array<{
13
+ type: 'text';
14
+ text: string;
15
+ }>;
16
+ isError?: boolean;
17
+ }
18
+ /**
19
+ * Dependencies injected into tool handlers that need embeddings functionality.
20
+ * All fields are nullable since embeddings may be disabled.
21
+ */
22
+ export interface ToolDependencies {
23
+ embeddingsDB: EmbeddingsDB | null;
24
+ ollamaClient: OllamaClient | null;
25
+ syncWorker: SyncWorker | null;
26
+ }
27
+ export declare const SearchTiddlersInput: z.ZodEffects<z.ZodObject<{
28
+ semantic: z.ZodOptional<z.ZodString>;
29
+ filter: z.ZodOptional<z.ZodString>;
30
+ includeText: z.ZodOptional<z.ZodBoolean>;
31
+ offset: z.ZodOptional<z.ZodNumber>;
32
+ limit: z.ZodOptional<z.ZodNumber>;
33
+ }, "strip", z.ZodTypeAny, {
34
+ filter?: string | undefined;
35
+ semantic?: string | undefined;
36
+ includeText?: boolean | undefined;
37
+ offset?: number | undefined;
38
+ limit?: number | undefined;
39
+ }, {
40
+ filter?: string | undefined;
41
+ semantic?: string | undefined;
42
+ includeText?: boolean | undefined;
43
+ offset?: number | undefined;
44
+ limit?: number | undefined;
45
+ }>, {
46
+ filter?: string | undefined;
47
+ semantic?: string | undefined;
48
+ includeText?: boolean | undefined;
49
+ offset?: number | undefined;
50
+ limit?: number | undefined;
51
+ }, {
52
+ filter?: string | undefined;
53
+ semantic?: string | undefined;
54
+ includeText?: boolean | undefined;
55
+ offset?: number | undefined;
56
+ limit?: number | undefined;
57
+ }>;
58
+ export type SearchTiddlersInputType = z.infer<typeof SearchTiddlersInput>;
59
+ export declare const UpdateTiddlerInput: z.ZodObject<{
60
+ title: z.ZodString;
61
+ text: z.ZodOptional<z.ZodString>;
62
+ tags: z.ZodOptional<z.ZodString>;
63
+ type: z.ZodOptional<z.ZodString>;
64
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
65
+ title: z.ZodString;
66
+ text: z.ZodOptional<z.ZodString>;
67
+ tags: z.ZodOptional<z.ZodString>;
68
+ type: z.ZodOptional<z.ZodString>;
69
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
70
+ title: z.ZodString;
71
+ text: z.ZodOptional<z.ZodString>;
72
+ tags: z.ZodOptional<z.ZodString>;
73
+ type: z.ZodOptional<z.ZodString>;
74
+ }, z.ZodTypeAny, "passthrough">>;
75
+ export type UpdateTiddlerInputType = z.infer<typeof UpdateTiddlerInput>;
76
+ export declare const CreateTiddlerInput: z.ZodObject<{
77
+ title: z.ZodString;
78
+ text: z.ZodString;
79
+ tags: z.ZodOptional<z.ZodString>;
80
+ type: z.ZodOptional<z.ZodString>;
81
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
82
+ title: z.ZodString;
83
+ text: z.ZodString;
84
+ tags: z.ZodOptional<z.ZodString>;
85
+ type: z.ZodOptional<z.ZodString>;
86
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
87
+ title: z.ZodString;
88
+ text: z.ZodString;
89
+ tags: z.ZodOptional<z.ZodString>;
90
+ type: z.ZodOptional<z.ZodString>;
91
+ }, z.ZodTypeAny, "passthrough">>;
92
+ export type CreateTiddlerInputType = z.infer<typeof CreateTiddlerInput>;
93
+ export declare const DeleteTiddlerInput: z.ZodObject<{
94
+ title: z.ZodString;
95
+ }, "strip", z.ZodTypeAny, {
96
+ title: string;
97
+ }, {
98
+ title: string;
99
+ }>;
100
+ export type DeleteTiddlerInputType = z.infer<typeof DeleteTiddlerInput>;
101
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE/D;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;CAC/B;AAID,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoC5B,CAAC;AAEL,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAE1E,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;gCAOf,CAAC;AAEjB,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAExE,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;gCAOf,CAAC;AAEjB,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAExE,eAAO,MAAM,kBAAkB;;;;;;EAE7B,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
@@ -0,0 +1,55 @@
1
+ // ABOUTME: Shared types for MCP tool handlers
2
+ // ABOUTME: Defines ToolResult, ToolDependencies, and Zod schemas for tool inputs
3
+ import { z } from 'zod';
4
+ // Zod schemas for tool inputs
5
+ export const SearchTiddlersInput = z
6
+ .object({
7
+ semantic: z
8
+ .string()
9
+ .optional()
10
+ .describe('Natural language semantic search query (e.g., "times I felt anxious about parenting")'),
11
+ filter: z
12
+ .string()
13
+ .optional()
14
+ .describe('TiddlyWiki filter expression (e.g., "[tag[Journal]prefix[2025-11]]"). Can be used alone for filter-based search, or combined with semantic for hybrid search.'),
15
+ includeText: z
16
+ .boolean()
17
+ .optional()
18
+ .describe('Include text content in results (default: false)'),
19
+ offset: z
20
+ .number()
21
+ .int()
22
+ .min(0)
23
+ .optional()
24
+ .describe('Number of results to skip (default: 0). Only applies to filter-based search.'),
25
+ limit: z
26
+ .number()
27
+ .int()
28
+ .min(1)
29
+ .max(100)
30
+ .optional()
31
+ .describe('Maximum number of results to return (default: 10 for semantic, unlimited for filter, max: 100)'),
32
+ })
33
+ .refine((data) => data.semantic !== undefined || data.filter !== undefined, {
34
+ message: 'At least one of semantic or filter must be provided',
35
+ });
36
+ export const UpdateTiddlerInput = z
37
+ .object({
38
+ title: z.string().describe('Title of the tiddler to update'),
39
+ text: z.string().optional().describe('New text content'),
40
+ tags: z.string().optional().describe('New tags (space-separated)'),
41
+ type: z.string().optional().describe('Content type (e.g., text/markdown)'),
42
+ })
43
+ .passthrough(); // Allow additional custom fields
44
+ export const CreateTiddlerInput = z
45
+ .object({
46
+ title: z.string().describe('Title of the new tiddler'),
47
+ text: z.string().describe('Text content'),
48
+ tags: z.string().optional().describe('Tags (space-separated)'),
49
+ type: z.string().optional().describe('Content type (default: text/markdown)'),
50
+ })
51
+ .passthrough(); // Allow additional custom fields
52
+ export const DeleteTiddlerInput = z.object({
53
+ title: z.string().describe('Title of the tiddler to delete'),
54
+ });
55
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,iFAAiF;AAEjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA0BxB,8BAA8B;AAE9B,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC;KACjC,MAAM,CAAC;IACN,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,uFAAuF,CACxF;IACH,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,+JAA+J,CAChK;IACH,WAAW,EAAE,CAAC;SACX,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CAAC,kDAAkD,CAAC;IAC/D,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,EAAE;SACV,QAAQ,CAAC,8EAA8E,CAAC;IAC3F,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,gGAAgG,CACjG;CACJ,CAAC;KACD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE;IAC1E,OAAO,EAAE,qDAAqD;CAC/D,CAAC,CAAC;AAIL,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAChC,MAAM,CAAC;IACN,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;IAC5D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IACxD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;IAClE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;CAC3E,CAAC;KACD,WAAW,EAAE,CAAC,CAAC,iCAAiC;AAInD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAChC,MAAM,CAAC;IACN,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;IACtD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;IACzC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;IAC9D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;CAC9E,CAAC;KACD,WAAW,EAAE,CAAC,CAAC,iCAAiC;AAInD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;CAC7D,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { ToolResult } from './types.js';
2
+ import { UpdateTiddlerInput } from './types.js';
3
+ /**
4
+ * Handle update_tiddler tool requests.
5
+ * Gets the current tiddler, applies updates, generates a diff, and saves.
6
+ */
7
+ export declare function handleUpdateTiddler(args: unknown): Promise<ToolResult>;
8
+ export { UpdateTiddlerInput };
9
+ //# sourceMappingURL=update-tiddler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-tiddler.d.ts","sourceRoot":"","sources":["../../src/tools/update-tiddler.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA4DhD;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAwC5E;AAGD,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -0,0 +1,90 @@
1
+ // ABOUTME: Handler for the update_tiddler MCP tool
2
+ // ABOUTME: Updates existing tiddlers with diff preview and custom field support
3
+ import { createTwoFilesPatch } from 'diff';
4
+ import { getTiddler, putTiddler, updateTiddlerObject, getAuthUser, } from '../tiddlywiki-http.js';
5
+ import { UpdateTiddlerInput } from './types.js';
6
+ /**
7
+ * Generate a readable diff between two tiddlers
8
+ */
9
+ function generateTiddlerDiff(oldTiddler, newTiddler) {
10
+ const lines = [];
11
+ // Text diff
12
+ const oldText = oldTiddler.text || '';
13
+ const newText = newTiddler.text || '';
14
+ if (oldText !== newText) {
15
+ const patch = createTwoFilesPatch(oldTiddler.title, newTiddler.title, oldText, newText, 'Before', 'After', { context: 1 } // Reduce context to 1 line for more compact diffs
16
+ );
17
+ // Add a concise summary
18
+ const oldLines = oldText.split('\n').length;
19
+ const newLines = newText.split('\n').length;
20
+ const delta = newLines - oldLines;
21
+ const summary = delta > 0
22
+ ? `+${delta} line${delta === 1 ? '' : 's'}`
23
+ : delta < 0
24
+ ? `${delta} line${delta === -1 ? '' : 's'}`
25
+ : 'modified';
26
+ lines.push(`**Content:** ${summary}`);
27
+ lines.push('```diff');
28
+ lines.push(patch);
29
+ lines.push('```');
30
+ }
31
+ // Metadata changes
32
+ const metadataChanges = [];
33
+ if (oldTiddler.tags !== newTiddler.tags) {
34
+ metadataChanges.push(` tags: "${oldTiddler.tags || ''}" → "${newTiddler.tags || ''}"`);
35
+ }
36
+ if (oldTiddler.type !== newTiddler.type) {
37
+ metadataChanges.push(` type: "${oldTiddler.type}" → "${newTiddler.type}"`);
38
+ }
39
+ if (metadataChanges.length > 0) {
40
+ lines.push('');
41
+ lines.push('**Metadata:**');
42
+ lines.push(...metadataChanges);
43
+ }
44
+ return lines.join('\n');
45
+ }
46
+ /**
47
+ * Handle update_tiddler tool requests.
48
+ * Gets the current tiddler, applies updates, generates a diff, and saves.
49
+ */
50
+ export async function handleUpdateTiddler(args) {
51
+ const input = UpdateTiddlerInput.parse(args);
52
+ // Get current tiddler
53
+ const current = await getTiddler(input.title);
54
+ if (!current) {
55
+ return {
56
+ content: [
57
+ {
58
+ type: 'text',
59
+ text: JSON.stringify({ error: `Tiddler not found: ${input.title}` }, null, 2),
60
+ },
61
+ ],
62
+ isError: true,
63
+ };
64
+ }
65
+ // Build updated tiddler - include all custom fields from input
66
+ const { title: _title, text, tags, type, ...customFields } = input;
67
+ const updates = { ...customFields };
68
+ if (text !== undefined)
69
+ updates.text = text;
70
+ if (tags !== undefined)
71
+ updates.tags = tags;
72
+ if (type !== undefined)
73
+ updates.type = type;
74
+ const updated = updateTiddlerObject(current, updates, getAuthUser());
75
+ // Generate diff
76
+ const diff = generateTiddlerDiff(current, updated);
77
+ // Apply the change
78
+ await putTiddler(updated);
79
+ return {
80
+ content: [
81
+ {
82
+ type: 'text',
83
+ text: `## Updated: "${input.title}"\n\n${diff}`,
84
+ },
85
+ ],
86
+ };
87
+ }
88
+ // Re-export the input schema for use in tool registration
89
+ export { UpdateTiddlerInput };
90
+ //# sourceMappingURL=update-tiddler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-tiddler.js","sourceRoot":"","sources":["../../src/tools/update-tiddler.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "tiddlywiki-mcp-server",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for TiddlyWiki with stdio and HTTP transport support",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "tiddlywiki-mcp-server": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/ppetru/tiddlywiki-mcp.git"
16
+ },
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "watch": "tsc --watch",
20
+ "start": "node dist/index.js",
21
+ "test": "vitest run",
22
+ "test:watch": "vitest",
23
+ "test:coverage": "vitest run --coverage",
24
+ "lint": "eslint src/**/*.ts",
25
+ "lint:fix": "eslint src/**/*.ts --fix",
26
+ "format": "prettier --write 'src/**/*.ts'",
27
+ "format:check": "prettier --check 'src/**/*.ts'",
28
+ "typecheck": "tsc --noEmit",
29
+ "prepare": "lefthook install"
30
+ },
31
+ "keywords": [
32
+ "mcp",
33
+ "tiddlywiki",
34
+ "model-context-protocol"
35
+ ],
36
+ "author": "Petru Paler <petru@paler.net> (https://petru.paler.net)",
37
+ "license": "MIT",
38
+ "engines": {
39
+ "node": ">=22"
40
+ },
41
+ "dependencies": {
42
+ "@modelcontextprotocol/sdk": "^1.25.1",
43
+ "better-sqlite3": "^12.4.1",
44
+ "diff": "^5.2.0",
45
+ "express": "^4.21.2",
46
+ "gpt-tokenizer": "^3.4.0",
47
+ "sqlite-vec": "^0.1.7-alpha.2",
48
+ "zod": "^3.23.8"
49
+ },
50
+ "devDependencies": {
51
+ "@eslint/js": "^9.39.2",
52
+ "@types/better-sqlite3": "^7.6.13",
53
+ "@types/diff": "^5.2.0",
54
+ "@types/express": "^5.0.0",
55
+ "@types/node": "^22.0.0",
56
+ "@typescript-eslint/eslint-plugin": "^8.18.2",
57
+ "@typescript-eslint/parser": "^8.18.2",
58
+ "@vitest/coverage-v8": "^2.1.8",
59
+ "eslint": "^9.17.0",
60
+ "eslint-config-prettier": "^10.1.8",
61
+ "lefthook": "^2.0.13",
62
+ "prettier": "^3.4.2",
63
+ "typescript": "^5.6.0",
64
+ "typescript-eslint": "^8.50.1",
65
+ "vitest": "^2.1.8"
66
+ }
67
+ }