@pragmatic-growth/memory-mcp 1.0.0 → 2.1.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.
- package/dist/index.js +114 -32
- package/package.json +1 -1
- package/src/index.ts +119 -37
package/dist/index.js
CHANGED
|
@@ -71,11 +71,11 @@ async function callRemoteServer(method, params) {
|
|
|
71
71
|
*/
|
|
72
72
|
async function initializeRemoteSession() {
|
|
73
73
|
await callRemoteServer('initialize', {
|
|
74
|
-
protocolVersion: '
|
|
74
|
+
protocolVersion: '2025-11-25',
|
|
75
75
|
capabilities: {},
|
|
76
76
|
clientInfo: {
|
|
77
77
|
name: 'pg-memory-stdio',
|
|
78
|
-
version: '1.0
|
|
78
|
+
version: '2.1.0',
|
|
79
79
|
},
|
|
80
80
|
});
|
|
81
81
|
}
|
|
@@ -95,81 +95,163 @@ async function main() {
|
|
|
95
95
|
// Create local MCP server
|
|
96
96
|
const server = new McpServer({
|
|
97
97
|
name: 'pg-memory',
|
|
98
|
-
version: '1.0
|
|
98
|
+
version: '2.1.0',
|
|
99
99
|
description: `PG-Memory knowledge base (${modeLabel} mode)`,
|
|
100
100
|
});
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
|
|
104
|
-
|
|
101
|
+
// ============================================================
|
|
102
|
+
// READ-ONLY TOOLS (available in all modes)
|
|
103
|
+
// ============================================================
|
|
104
|
+
// Tool 1: Search Knowledge (matches HTTP server's search_knowledge)
|
|
105
|
+
server.tool('search_knowledge', `Search the nonresident.tax knowledge base using semantic similarity.
|
|
106
|
+
|
|
107
|
+
This knowledge base contains comprehensive information about:
|
|
108
|
+
- Services: LLC formation, tax filing, registered agent, accounting
|
|
109
|
+
- Pricing: Package costs, annual fees, consultation fees
|
|
110
|
+
- Tax compliance: Form 5472, Form 1120, ECI rules, penalties, deadlines
|
|
111
|
+
- Company formation: Wyoming LLC, Delaware LLC, single-member LLC
|
|
112
|
+
- Banking: Mercury, Wise, US bank account requirements
|
|
113
|
+
- Process: Onboarding steps, document requirements, timelines
|
|
114
|
+
- Dissolution: LLC closure, final filings, IRS compliance
|
|
115
|
+
|
|
116
|
+
Returns relevant articles with relevance scores. Use get_article to retrieve full content.`, {
|
|
117
|
+
query: z.string().describe('The question or topic to search for'),
|
|
105
118
|
limit: z.number().optional().describe('Maximum number of results to return (default: 5)'),
|
|
106
119
|
threshold: z.number().optional().describe('Minimum similarity threshold 0-1 (default: 0.55)'),
|
|
107
120
|
}, async (args) => {
|
|
108
121
|
const result = await callRemoteServer('tools/call', {
|
|
109
|
-
name: '
|
|
122
|
+
name: 'search_knowledge',
|
|
110
123
|
arguments: args,
|
|
111
124
|
});
|
|
112
125
|
return result;
|
|
113
126
|
});
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
127
|
+
// Tool 2: Get Article
|
|
128
|
+
server.tool('get_article', `Retrieve the complete content of a knowledge base article by ID.
|
|
129
|
+
|
|
130
|
+
Use this tool when:
|
|
131
|
+
- You have an article ID from search_knowledge or list_articles
|
|
132
|
+
- You need the full article content (not just summary)
|
|
133
|
+
- You want to verify specific details from search results
|
|
134
|
+
|
|
135
|
+
Returns: Full article with title, content, summary, category, tags, version, and last update date.`, {
|
|
136
|
+
article_id: z.string().describe('The article ID (e.g., art_abc123)'),
|
|
117
137
|
}, async (args) => {
|
|
118
138
|
const result = await callRemoteServer('tools/call', {
|
|
119
|
-
name: '
|
|
139
|
+
name: 'get_article',
|
|
120
140
|
arguments: args,
|
|
121
141
|
});
|
|
122
142
|
return result;
|
|
123
143
|
});
|
|
124
|
-
|
|
125
|
-
|
|
144
|
+
// Tool 3: Answer Question (Full RAG)
|
|
145
|
+
server.tool('answer_question', `Answer a customer question using the knowledge base with full RAG.
|
|
146
|
+
|
|
147
|
+
This tool:
|
|
148
|
+
1. Searches for relevant articles in the knowledge base
|
|
149
|
+
2. If found: Generates an answer synthesizing the retrieved content
|
|
150
|
+
3. If not found: Optionally generates a new article to fill the gap
|
|
151
|
+
|
|
152
|
+
Use for questions about:
|
|
153
|
+
- Services and pricing
|
|
154
|
+
- Tax filing requirements and deadlines
|
|
155
|
+
- LLC formation process
|
|
156
|
+
- Bank account options
|
|
157
|
+
- Document requirements
|
|
158
|
+
- How onboarding works
|
|
159
|
+
- Any nonresident.tax topic
|
|
160
|
+
|
|
161
|
+
The answer includes source references for transparency.`, {
|
|
162
|
+
question: z.string().describe('The customer question to answer'),
|
|
163
|
+
context: z.string().optional().describe('Additional context about the question'),
|
|
164
|
+
generate_if_not_found: z.boolean().optional().describe('Generate new article if no relevant content found (default: true)'),
|
|
126
165
|
}, async (args) => {
|
|
127
166
|
const result = await callRemoteServer('tools/call', {
|
|
128
|
-
name: '
|
|
167
|
+
name: 'answer_question',
|
|
129
168
|
arguments: args,
|
|
130
169
|
});
|
|
131
170
|
return result;
|
|
132
171
|
});
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
172
|
+
// Tool 4: Log Unanswered
|
|
173
|
+
server.tool('log_unanswered', `Flag a customer question as unanswered for knowledge gap analysis.
|
|
174
|
+
|
|
175
|
+
WHEN TO USE:
|
|
176
|
+
- After search_knowledge returns no relevant results
|
|
177
|
+
- When existing articles don't fully answer the question
|
|
178
|
+
- When a customer asks something completely new
|
|
179
|
+
- To track recurring questions that need dedicated articles
|
|
180
|
+
|
|
181
|
+
WHY IT MATTERS:
|
|
182
|
+
- Flagged questions appear in the admin "Knowledge Gaps" section
|
|
183
|
+
- Helps prioritize which new articles to create
|
|
184
|
+
- Builds a list of topics customers actually need
|
|
185
|
+
- Improves the knowledge base over time`, {
|
|
186
|
+
query: z.string().describe('The question that could not be answered'),
|
|
187
|
+
reason: z.string().optional().describe('Reason why the question could not be answered'),
|
|
136
188
|
}, async (args) => {
|
|
137
189
|
const result = await callRemoteServer('tools/call', {
|
|
138
|
-
name: '
|
|
190
|
+
name: 'log_unanswered',
|
|
139
191
|
arguments: args,
|
|
140
192
|
});
|
|
141
193
|
return result;
|
|
142
194
|
});
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
195
|
+
// Tool 5: List Articles
|
|
196
|
+
server.tool('list_articles', `Browse articles in the knowledge base with optional filtering.
|
|
197
|
+
|
|
198
|
+
Parameters:
|
|
199
|
+
- limit: Number of articles (default 10, max 50)
|
|
200
|
+
- category: Filter by category slug (use list_categories first)
|
|
201
|
+
|
|
202
|
+
Returns article ID, title, and summary for each match.
|
|
203
|
+
Use get_article with the ID to retrieve full content.
|
|
204
|
+
|
|
205
|
+
WORKFLOW:
|
|
206
|
+
1. Call list_categories to discover available categories
|
|
207
|
+
2. Call list_articles with specific category for focused results
|
|
208
|
+
3. Call get_article for articles that look relevant`, {
|
|
209
|
+
limit: z.number().optional().describe('Number of articles to return (max 50)'),
|
|
210
|
+
category: z.string().optional().describe('Filter by category slug'),
|
|
146
211
|
}, async (args) => {
|
|
147
212
|
const result = await callRemoteServer('tools/call', {
|
|
148
|
-
name: '
|
|
213
|
+
name: 'list_articles',
|
|
149
214
|
arguments: args,
|
|
150
215
|
});
|
|
151
216
|
return result;
|
|
152
217
|
});
|
|
153
|
-
|
|
218
|
+
// Tool 6: Health Check
|
|
219
|
+
server.tool('health_check', 'Check the health status of the memory system.', {}, async () => {
|
|
154
220
|
const result = await callRemoteServer('tools/call', {
|
|
155
221
|
name: 'health_check',
|
|
156
222
|
arguments: {},
|
|
157
223
|
});
|
|
158
224
|
return result;
|
|
159
225
|
});
|
|
160
|
-
// Tool 7: List Categories
|
|
161
|
-
server.tool('list_categories',
|
|
226
|
+
// Tool 7: List Categories
|
|
227
|
+
server.tool('list_categories', `List all categories in the knowledge base with article counts.
|
|
228
|
+
|
|
229
|
+
CRITICAL FOR EFFICIENT SEARCH:
|
|
230
|
+
Categories help you quickly narrow down to relevant content.
|
|
231
|
+
|
|
232
|
+
Returns for each category:
|
|
233
|
+
- slug: Category identifier for filtering
|
|
234
|
+
- name: Human-readable name
|
|
235
|
+
- count: Number of articles
|
|
236
|
+
- description: What the category covers
|
|
237
|
+
|
|
238
|
+
RECOMMENDED WORKFLOW:
|
|
239
|
+
1. Call list_categories to see what's available
|
|
240
|
+
2. Call list_articles with category slug
|
|
241
|
+
3. Call get_article for full content
|
|
242
|
+
4. Or use search_knowledge for semantic search across all`, {}, async () => {
|
|
162
243
|
const result = await callRemoteServer('tools/call', {
|
|
163
244
|
name: 'list_categories',
|
|
164
245
|
arguments: {},
|
|
165
246
|
});
|
|
166
247
|
return result;
|
|
167
248
|
});
|
|
168
|
-
//
|
|
169
|
-
//
|
|
249
|
+
// ============================================================
|
|
250
|
+
// FULL MODE TOOLS (only available with --full flag or MCP_MODE=full)
|
|
251
|
+
// ============================================================
|
|
170
252
|
if (isFullMode) {
|
|
171
253
|
// Tool 8: Add Article
|
|
172
|
-
server.tool('add_article', 'Create a new article in the knowledge base
|
|
254
|
+
server.tool('add_article', 'Create a new article in the knowledge base. Automatically generates embedding for semantic search.', {
|
|
173
255
|
title: z.string().describe('Article title'),
|
|
174
256
|
content: z.string().describe('Article content in markdown format'),
|
|
175
257
|
summary: z.string().optional().describe('Brief summary (auto-generated if not provided)'),
|
|
@@ -184,7 +266,7 @@ async function main() {
|
|
|
184
266
|
return result;
|
|
185
267
|
});
|
|
186
268
|
// Tool 9: Edit Article
|
|
187
|
-
server.tool('edit_article', 'Update an existing article
|
|
269
|
+
server.tool('edit_article', 'Update an existing article. Re-generates embedding if content changes.', {
|
|
188
270
|
article_id: z.string().describe('Article ID to update'),
|
|
189
271
|
title: z.string().optional().describe('New title'),
|
|
190
272
|
content: z.string().optional().describe('New content'),
|
|
@@ -199,7 +281,7 @@ async function main() {
|
|
|
199
281
|
return result;
|
|
200
282
|
});
|
|
201
283
|
// Tool 10: Remove Article
|
|
202
|
-
server.tool('remove_article', 'Soft-delete an article from the knowledge base
|
|
284
|
+
server.tool('remove_article', 'Soft-delete an article from the knowledge base. Article is marked as deleted but not permanently removed.', {
|
|
203
285
|
article_id: z.string().describe('Article ID to remove'),
|
|
204
286
|
reason: z.string().optional().describe('Reason for deletion (for audit log)'),
|
|
205
287
|
}, async (args) => {
|
|
@@ -210,7 +292,7 @@ async function main() {
|
|
|
210
292
|
return result;
|
|
211
293
|
});
|
|
212
294
|
// Tool 11: Rate Answer
|
|
213
|
-
server.tool('rate_answer', 'Rate a previous answer as helpful, unhelpful, or neutral
|
|
295
|
+
server.tool('rate_answer', 'Rate a previous answer as helpful, unhelpful, or neutral. Helps improve the knowledge base.', {
|
|
214
296
|
query_id: z.string().describe('Query log ID from a previous answer_question response'),
|
|
215
297
|
rating: z.number().describe('Rating: -1 (unhelpful), 0 (neutral), 1 (helpful)'),
|
|
216
298
|
feedback: z.string().optional().describe('Optional text feedback'),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pragmatic-growth/memory-mcp",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "MCP stdio client for PG-Memory knowledge base - connect AI agents to your PostgreSQL knowledge base via Model Context Protocol",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
package/src/index.ts
CHANGED
|
@@ -93,11 +93,11 @@ async function callRemoteServer(method: string, params?: Record<string, unknown>
|
|
|
93
93
|
*/
|
|
94
94
|
async function initializeRemoteSession(): Promise<void> {
|
|
95
95
|
await callRemoteServer('initialize', {
|
|
96
|
-
protocolVersion: '
|
|
96
|
+
protocolVersion: '2025-11-25',
|
|
97
97
|
capabilities: {},
|
|
98
98
|
clientInfo: {
|
|
99
99
|
name: 'pg-memory-stdio',
|
|
100
|
-
version: '1.0
|
|
100
|
+
version: '2.1.0',
|
|
101
101
|
},
|
|
102
102
|
});
|
|
103
103
|
}
|
|
@@ -119,96 +119,162 @@ async function main(): Promise<void> {
|
|
|
119
119
|
// Create local MCP server
|
|
120
120
|
const server = new McpServer({
|
|
121
121
|
name: 'pg-memory',
|
|
122
|
-
version: '1.0
|
|
122
|
+
version: '2.1.0',
|
|
123
123
|
description: `PG-Memory knowledge base (${modeLabel} mode)`,
|
|
124
124
|
});
|
|
125
125
|
|
|
126
|
-
//
|
|
127
|
-
//
|
|
126
|
+
// ============================================================
|
|
127
|
+
// READ-ONLY TOOLS (available in all modes)
|
|
128
|
+
// ============================================================
|
|
128
129
|
|
|
130
|
+
// Tool 1: Search Knowledge (matches HTTP server's search_knowledge)
|
|
129
131
|
server.tool(
|
|
130
|
-
'
|
|
131
|
-
|
|
132
|
+
'search_knowledge',
|
|
133
|
+
`Search the nonresident.tax knowledge base using semantic similarity.
|
|
134
|
+
|
|
135
|
+
This knowledge base contains comprehensive information about:
|
|
136
|
+
- Services: LLC formation, tax filing, registered agent, accounting
|
|
137
|
+
- Pricing: Package costs, annual fees, consultation fees
|
|
138
|
+
- Tax compliance: Form 5472, Form 1120, ECI rules, penalties, deadlines
|
|
139
|
+
- Company formation: Wyoming LLC, Delaware LLC, single-member LLC
|
|
140
|
+
- Banking: Mercury, Wise, US bank account requirements
|
|
141
|
+
- Process: Onboarding steps, document requirements, timelines
|
|
142
|
+
- Dissolution: LLC closure, final filings, IRS compliance
|
|
143
|
+
|
|
144
|
+
Returns relevant articles with relevance scores. Use get_article to retrieve full content.`,
|
|
132
145
|
{
|
|
133
|
-
query: z.string().describe('The
|
|
146
|
+
query: z.string().describe('The question or topic to search for'),
|
|
134
147
|
limit: z.number().optional().describe('Maximum number of results to return (default: 5)'),
|
|
135
148
|
threshold: z.number().optional().describe('Minimum similarity threshold 0-1 (default: 0.55)'),
|
|
136
149
|
},
|
|
137
150
|
async (args) => {
|
|
138
151
|
const result = await callRemoteServer('tools/call', {
|
|
139
|
-
name: '
|
|
152
|
+
name: 'search_knowledge',
|
|
140
153
|
arguments: args,
|
|
141
154
|
}) as { content: Array<{ type: 'text'; text: string }> };
|
|
142
155
|
return result;
|
|
143
156
|
}
|
|
144
157
|
);
|
|
145
158
|
|
|
159
|
+
// Tool 2: Get Article
|
|
146
160
|
server.tool(
|
|
147
|
-
'
|
|
148
|
-
|
|
161
|
+
'get_article',
|
|
162
|
+
`Retrieve the complete content of a knowledge base article by ID.
|
|
163
|
+
|
|
164
|
+
Use this tool when:
|
|
165
|
+
- You have an article ID from search_knowledge or list_articles
|
|
166
|
+
- You need the full article content (not just summary)
|
|
167
|
+
- You want to verify specific details from search results
|
|
168
|
+
|
|
169
|
+
Returns: Full article with title, content, summary, category, tags, version, and last update date.`,
|
|
149
170
|
{
|
|
150
|
-
|
|
151
|
-
context: z.string().optional().describe('Additional context'),
|
|
171
|
+
article_id: z.string().describe('The article ID (e.g., art_abc123)'),
|
|
152
172
|
},
|
|
153
173
|
async (args) => {
|
|
154
174
|
const result = await callRemoteServer('tools/call', {
|
|
155
|
-
name: '
|
|
175
|
+
name: 'get_article',
|
|
156
176
|
arguments: args,
|
|
157
177
|
}) as { content: Array<{ type: 'text'; text: string }> };
|
|
158
178
|
return result;
|
|
159
179
|
}
|
|
160
180
|
);
|
|
161
181
|
|
|
182
|
+
// Tool 3: Answer Question (Full RAG)
|
|
162
183
|
server.tool(
|
|
163
|
-
'
|
|
164
|
-
|
|
184
|
+
'answer_question',
|
|
185
|
+
`Answer a customer question using the knowledge base with full RAG.
|
|
186
|
+
|
|
187
|
+
This tool:
|
|
188
|
+
1. Searches for relevant articles in the knowledge base
|
|
189
|
+
2. If found: Generates an answer synthesizing the retrieved content
|
|
190
|
+
3. If not found: Optionally generates a new article to fill the gap
|
|
191
|
+
|
|
192
|
+
Use for questions about:
|
|
193
|
+
- Services and pricing
|
|
194
|
+
- Tax filing requirements and deadlines
|
|
195
|
+
- LLC formation process
|
|
196
|
+
- Bank account options
|
|
197
|
+
- Document requirements
|
|
198
|
+
- How onboarding works
|
|
199
|
+
- Any nonresident.tax topic
|
|
200
|
+
|
|
201
|
+
The answer includes source references for transparency.`,
|
|
165
202
|
{
|
|
166
|
-
|
|
203
|
+
question: z.string().describe('The customer question to answer'),
|
|
204
|
+
context: z.string().optional().describe('Additional context about the question'),
|
|
205
|
+
generate_if_not_found: z.boolean().optional().describe('Generate new article if no relevant content found (default: true)'),
|
|
167
206
|
},
|
|
168
207
|
async (args) => {
|
|
169
208
|
const result = await callRemoteServer('tools/call', {
|
|
170
|
-
name: '
|
|
209
|
+
name: 'answer_question',
|
|
171
210
|
arguments: args,
|
|
172
211
|
}) as { content: Array<{ type: 'text'; text: string }> };
|
|
173
212
|
return result;
|
|
174
213
|
}
|
|
175
214
|
);
|
|
176
215
|
|
|
216
|
+
// Tool 4: Log Unanswered
|
|
177
217
|
server.tool(
|
|
178
|
-
'
|
|
179
|
-
|
|
218
|
+
'log_unanswered',
|
|
219
|
+
`Flag a customer question as unanswered for knowledge gap analysis.
|
|
220
|
+
|
|
221
|
+
WHEN TO USE:
|
|
222
|
+
- After search_knowledge returns no relevant results
|
|
223
|
+
- When existing articles don't fully answer the question
|
|
224
|
+
- When a customer asks something completely new
|
|
225
|
+
- To track recurring questions that need dedicated articles
|
|
226
|
+
|
|
227
|
+
WHY IT MATTERS:
|
|
228
|
+
- Flagged questions appear in the admin "Knowledge Gaps" section
|
|
229
|
+
- Helps prioritize which new articles to create
|
|
230
|
+
- Builds a list of topics customers actually need
|
|
231
|
+
- Improves the knowledge base over time`,
|
|
180
232
|
{
|
|
181
|
-
|
|
182
|
-
|
|
233
|
+
query: z.string().describe('The question that could not be answered'),
|
|
234
|
+
reason: z.string().optional().describe('Reason why the question could not be answered'),
|
|
183
235
|
},
|
|
184
236
|
async (args) => {
|
|
185
237
|
const result = await callRemoteServer('tools/call', {
|
|
186
|
-
name: '
|
|
238
|
+
name: 'log_unanswered',
|
|
187
239
|
arguments: args,
|
|
188
240
|
}) as { content: Array<{ type: 'text'; text: string }> };
|
|
189
241
|
return result;
|
|
190
242
|
}
|
|
191
243
|
);
|
|
192
244
|
|
|
245
|
+
// Tool 5: List Articles
|
|
193
246
|
server.tool(
|
|
194
|
-
'
|
|
195
|
-
|
|
247
|
+
'list_articles',
|
|
248
|
+
`Browse articles in the knowledge base with optional filtering.
|
|
249
|
+
|
|
250
|
+
Parameters:
|
|
251
|
+
- limit: Number of articles (default 10, max 50)
|
|
252
|
+
- category: Filter by category slug (use list_categories first)
|
|
253
|
+
|
|
254
|
+
Returns article ID, title, and summary for each match.
|
|
255
|
+
Use get_article with the ID to retrieve full content.
|
|
256
|
+
|
|
257
|
+
WORKFLOW:
|
|
258
|
+
1. Call list_categories to discover available categories
|
|
259
|
+
2. Call list_articles with specific category for focused results
|
|
260
|
+
3. Call get_article for articles that look relevant`,
|
|
196
261
|
{
|
|
197
|
-
|
|
198
|
-
|
|
262
|
+
limit: z.number().optional().describe('Number of articles to return (max 50)'),
|
|
263
|
+
category: z.string().optional().describe('Filter by category slug'),
|
|
199
264
|
},
|
|
200
265
|
async (args) => {
|
|
201
266
|
const result = await callRemoteServer('tools/call', {
|
|
202
|
-
name: '
|
|
267
|
+
name: 'list_articles',
|
|
203
268
|
arguments: args,
|
|
204
269
|
}) as { content: Array<{ type: 'text'; text: string }> };
|
|
205
270
|
return result;
|
|
206
271
|
}
|
|
207
272
|
);
|
|
208
273
|
|
|
274
|
+
// Tool 6: Health Check
|
|
209
275
|
server.tool(
|
|
210
276
|
'health_check',
|
|
211
|
-
'Check the health status of the
|
|
277
|
+
'Check the health status of the memory system.',
|
|
212
278
|
{},
|
|
213
279
|
async () => {
|
|
214
280
|
const result = await callRemoteServer('tools/call', {
|
|
@@ -219,10 +285,25 @@ async function main(): Promise<void> {
|
|
|
219
285
|
}
|
|
220
286
|
);
|
|
221
287
|
|
|
222
|
-
// Tool 7: List Categories
|
|
288
|
+
// Tool 7: List Categories
|
|
223
289
|
server.tool(
|
|
224
290
|
'list_categories',
|
|
225
|
-
|
|
291
|
+
`List all categories in the knowledge base with article counts.
|
|
292
|
+
|
|
293
|
+
CRITICAL FOR EFFICIENT SEARCH:
|
|
294
|
+
Categories help you quickly narrow down to relevant content.
|
|
295
|
+
|
|
296
|
+
Returns for each category:
|
|
297
|
+
- slug: Category identifier for filtering
|
|
298
|
+
- name: Human-readable name
|
|
299
|
+
- count: Number of articles
|
|
300
|
+
- description: What the category covers
|
|
301
|
+
|
|
302
|
+
RECOMMENDED WORKFLOW:
|
|
303
|
+
1. Call list_categories to see what's available
|
|
304
|
+
2. Call list_articles with category slug
|
|
305
|
+
3. Call get_article for full content
|
|
306
|
+
4. Or use search_knowledge for semantic search across all`,
|
|
226
307
|
{},
|
|
227
308
|
async () => {
|
|
228
309
|
const result = await callRemoteServer('tools/call', {
|
|
@@ -233,14 +314,15 @@ async function main(): Promise<void> {
|
|
|
233
314
|
}
|
|
234
315
|
);
|
|
235
316
|
|
|
236
|
-
//
|
|
237
|
-
//
|
|
317
|
+
// ============================================================
|
|
318
|
+
// FULL MODE TOOLS (only available with --full flag or MCP_MODE=full)
|
|
319
|
+
// ============================================================
|
|
238
320
|
|
|
239
321
|
if (isFullMode) {
|
|
240
322
|
// Tool 8: Add Article
|
|
241
323
|
server.tool(
|
|
242
324
|
'add_article',
|
|
243
|
-
'Create a new article in the knowledge base
|
|
325
|
+
'Create a new article in the knowledge base. Automatically generates embedding for semantic search.',
|
|
244
326
|
{
|
|
245
327
|
title: z.string().describe('Article title'),
|
|
246
328
|
content: z.string().describe('Article content in markdown format'),
|
|
@@ -261,7 +343,7 @@ async function main(): Promise<void> {
|
|
|
261
343
|
// Tool 9: Edit Article
|
|
262
344
|
server.tool(
|
|
263
345
|
'edit_article',
|
|
264
|
-
'Update an existing article
|
|
346
|
+
'Update an existing article. Re-generates embedding if content changes.',
|
|
265
347
|
{
|
|
266
348
|
article_id: z.string().describe('Article ID to update'),
|
|
267
349
|
title: z.string().optional().describe('New title'),
|
|
@@ -282,7 +364,7 @@ async function main(): Promise<void> {
|
|
|
282
364
|
// Tool 10: Remove Article
|
|
283
365
|
server.tool(
|
|
284
366
|
'remove_article',
|
|
285
|
-
'Soft-delete an article from the knowledge base
|
|
367
|
+
'Soft-delete an article from the knowledge base. Article is marked as deleted but not permanently removed.',
|
|
286
368
|
{
|
|
287
369
|
article_id: z.string().describe('Article ID to remove'),
|
|
288
370
|
reason: z.string().optional().describe('Reason for deletion (for audit log)'),
|
|
@@ -299,7 +381,7 @@ async function main(): Promise<void> {
|
|
|
299
381
|
// Tool 11: Rate Answer
|
|
300
382
|
server.tool(
|
|
301
383
|
'rate_answer',
|
|
302
|
-
'Rate a previous answer as helpful, unhelpful, or neutral
|
|
384
|
+
'Rate a previous answer as helpful, unhelpful, or neutral. Helps improve the knowledge base.',
|
|
303
385
|
{
|
|
304
386
|
query_id: z.string().describe('Query log ID from a previous answer_question response'),
|
|
305
387
|
rating: z.number().describe('Rating: -1 (unhelpful), 0 (neutral), 1 (helpful)'),
|