@get-technology-inc/jamf-docs-mcp-server 0.0.1 → 1.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.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -29
  3. package/dist/constants.d.ts +263 -0
  4. package/dist/constants.d.ts.map +1 -0
  5. package/dist/constants.js +308 -0
  6. package/dist/constants.js.map +1 -0
  7. package/dist/index.d.ts +9 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +40 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/resources/index.d.ts +13 -0
  12. package/dist/resources/index.d.ts.map +1 -0
  13. package/dist/resources/index.js +45 -0
  14. package/dist/resources/index.js.map +1 -0
  15. package/dist/schemas/index.d.ts +61 -0
  16. package/dist/schemas/index.d.ts.map +1 -0
  17. package/dist/schemas/index.js +127 -0
  18. package/dist/schemas/index.js.map +1 -0
  19. package/dist/services/cache.d.ts +47 -0
  20. package/dist/services/cache.d.ts.map +1 -0
  21. package/dist/services/cache.js +165 -0
  22. package/dist/services/cache.js.map +1 -0
  23. package/dist/services/metadata.d.ts +78 -0
  24. package/dist/services/metadata.d.ts.map +1 -0
  25. package/dist/services/metadata.js +349 -0
  26. package/dist/services/metadata.js.map +1 -0
  27. package/dist/services/scraper.d.ts +62 -0
  28. package/dist/services/scraper.d.ts.map +1 -0
  29. package/dist/services/scraper.js +544 -0
  30. package/dist/services/scraper.js.map +1 -0
  31. package/dist/services/search-suggestions.d.ts +27 -0
  32. package/dist/services/search-suggestions.d.ts.map +1 -0
  33. package/dist/services/search-suggestions.js +193 -0
  34. package/dist/services/search-suggestions.js.map +1 -0
  35. package/dist/services/tokenizer.d.ts +93 -0
  36. package/dist/services/tokenizer.d.ts.map +1 -0
  37. package/dist/services/tokenizer.js +330 -0
  38. package/dist/services/tokenizer.js.map +1 -0
  39. package/dist/tools/get-article.d.ts +7 -0
  40. package/dist/tools/get-article.d.ts.map +1 -0
  41. package/dist/tools/get-article.js +244 -0
  42. package/dist/tools/get-article.js.map +1 -0
  43. package/dist/tools/get-toc.d.ts +7 -0
  44. package/dist/tools/get-toc.d.ts.map +1 -0
  45. package/dist/tools/get-toc.js +202 -0
  46. package/dist/tools/get-toc.js.map +1 -0
  47. package/dist/tools/list-products.d.ts +7 -0
  48. package/dist/tools/list-products.d.ts.map +1 -0
  49. package/dist/tools/list-products.js +150 -0
  50. package/dist/tools/list-products.js.map +1 -0
  51. package/dist/tools/search.d.ts +7 -0
  52. package/dist/tools/search.d.ts.map +1 -0
  53. package/dist/tools/search.js +252 -0
  54. package/dist/tools/search.js.map +1 -0
  55. package/dist/types.d.ts +188 -0
  56. package/dist/types.d.ts.map +1 -0
  57. package/dist/types.js +28 -0
  58. package/dist/types.js.map +1 -0
  59. package/package.json +68 -6
@@ -0,0 +1,202 @@
1
+ /**
2
+ * jamf_docs_get_toc tool
3
+ * Get the table of contents for a Jamf product's documentation.
4
+ */
5
+ import { GetTocInputSchema } from '../schemas/index.js';
6
+ import { ResponseFormat, OutputMode, JAMF_PRODUCTS, TOKEN_CONFIG } from '../constants.js';
7
+ import { fetchTableOfContents } from '../services/scraper.js';
8
+ import { getAvailableVersions } from '../services/metadata.js';
9
+ /**
10
+ * Render a single TOC entry as markdown
11
+ */
12
+ function renderTocEntry(entry, depth = 0, compact = false) {
13
+ const indent = ' '.repeat(depth);
14
+ let result = `${indent}- [${entry.title}](${entry.url})\n`;
15
+ if (!compact && entry.children !== undefined && entry.children.length > 0) {
16
+ for (const child of entry.children) {
17
+ result += renderTocEntry(child, depth + 1, compact);
18
+ }
19
+ }
20
+ return result;
21
+ }
22
+ /**
23
+ * Format TOC as compact markdown
24
+ */
25
+ function formatTocCompact(productName, toc, pagination) {
26
+ let markdown = `## ${productName} TOC (${pagination.totalItems} entries)\n\n`;
27
+ for (const entry of toc) {
28
+ markdown += renderTocEntry(entry, 0, true);
29
+ }
30
+ markdown += `\n---\n*Page ${pagination.page}/${pagination.totalPages}`;
31
+ if (pagination.hasNext) {
32
+ markdown += ` | page=${pagination.page + 1} for more`;
33
+ }
34
+ markdown += '*\n';
35
+ return markdown;
36
+ }
37
+ /**
38
+ * Format TOC as full markdown
39
+ */
40
+ function formatTocFull(productName, version, toc, pagination, tokenInfo) {
41
+ let markdown = `# ${productName} Documentation\n\n`;
42
+ markdown += `**Version**: ${version} | **Page ${pagination.page} of ${pagination.totalPages}** | ${tokenInfo.tokenCount.toLocaleString()} tokens\n\n`;
43
+ markdown += '---\n\n';
44
+ markdown += '## Table of Contents\n\n';
45
+ for (const entry of toc) {
46
+ markdown += renderTocEntry(entry);
47
+ }
48
+ markdown += '\n---\n\n';
49
+ markdown += `**Page ${pagination.page} of ${pagination.totalPages}** (${tokenInfo.tokenCount.toLocaleString()} tokens, ${pagination.totalItems} total entries)`;
50
+ if (pagination.hasNext) {
51
+ markdown += ` | Use \`page=${pagination.page + 1}\` for more`;
52
+ }
53
+ if (tokenInfo.truncated) {
54
+ markdown += '\n*TOC truncated due to token limit. Use `page` parameter or increase `maxTokens`.*';
55
+ }
56
+ markdown += '\n\n*Use `jamf_docs_get_article` with any URL above to read the full content.*\n';
57
+ return markdown;
58
+ }
59
+ const TOOL_NAME = 'jamf_docs_get_toc';
60
+ const TOOL_DESCRIPTION = `Get the table of contents for a Jamf product's documentation.
61
+
62
+ This tool retrieves the navigation structure for a specific Jamf product,
63
+ allowing you to browse available documentation topics.
64
+
65
+ Args:
66
+ - product (string, required): Product ID - one of: jamf-pro, jamf-school, jamf-connect, jamf-protect
67
+ - version (string, optional): Specific version (defaults to latest)
68
+ - page (number, optional): Page number for pagination 1-100 (default: 1)
69
+ - maxTokens (number, optional): Maximum tokens in response 100-20000 (default: 5000)
70
+ - outputMode ('full' | 'compact'): Output detail level (default: 'full'). Use 'compact' for flat list without nested children
71
+ - responseFormat ('markdown' | 'json'): Output format (default: 'markdown')
72
+
73
+ Returns:
74
+ For JSON format:
75
+ {
76
+ "product": string,
77
+ "version": string,
78
+ "toc": [...],
79
+ "tokenInfo": {
80
+ "tokenCount": number,
81
+ "truncated": boolean,
82
+ "maxTokens": number
83
+ },
84
+ "pagination": {
85
+ "page": number,
86
+ "pageSize": number,
87
+ "totalPages": number,
88
+ "totalItems": number,
89
+ "hasNext": boolean,
90
+ "hasPrev": boolean
91
+ }
92
+ }
93
+
94
+ For Markdown format:
95
+ A hierarchical list of documentation topics with pagination and token info.
96
+
97
+ Examples:
98
+ - Browse Jamf Pro documentation: product="jamf-pro"
99
+ - Get page 2 of TOC: product="jamf-pro", page=2
100
+ - Limit response size: product="jamf-pro", maxTokens=2000
101
+
102
+ Errors:
103
+ - "Invalid product ID" if the product is not recognized
104
+ - "Version not found" if the specified version doesn't exist
105
+
106
+ Note: Use this to discover what topics are available before searching
107
+ or retrieving specific articles. Large TOCs are paginated.`;
108
+ export function registerGetTocTool(server) {
109
+ server.registerTool(TOOL_NAME, {
110
+ title: 'Get Documentation Table of Contents',
111
+ description: TOOL_DESCRIPTION,
112
+ inputSchema: GetTocInputSchema,
113
+ annotations: {
114
+ readOnlyHint: true,
115
+ destructiveHint: false,
116
+ idempotentHint: true,
117
+ openWorldHint: true
118
+ }
119
+ }, async (args) => {
120
+ // Parse and validate input
121
+ const parseResult = GetTocInputSchema.safeParse(args);
122
+ if (!parseResult.success) {
123
+ return {
124
+ isError: true,
125
+ content: [{ type: 'text', text: `Invalid input: ${parseResult.error.message}` }]
126
+ };
127
+ }
128
+ const params = parseResult.data;
129
+ try {
130
+ // Validate product
131
+ if (!(params.product in JAMF_PRODUCTS)) {
132
+ return {
133
+ isError: true,
134
+ content: [{
135
+ type: 'text',
136
+ text: `Invalid product ID: "${params.product}".\n\nValid options:\n${Object.entries(JAMF_PRODUCTS).map(([id, p]) => `- \`${id}\`: ${p.name}`).join('\n')}`
137
+ }]
138
+ };
139
+ }
140
+ const productId = params.product;
141
+ const productInfo = JAMF_PRODUCTS[productId];
142
+ // Get available versions dynamically
143
+ const availableVersions = await getAvailableVersions(productId);
144
+ const version = params.version ?? 'current';
145
+ // Validate version if specified
146
+ if (params.version !== undefined && params.version !== '' && params.version !== 'current') {
147
+ if (availableVersions.length > 0 && !availableVersions.includes(params.version)) {
148
+ return {
149
+ isError: true,
150
+ content: [{
151
+ type: 'text',
152
+ text: `Version "${params.version}" not found for ${productInfo.name}.\n\nAvailable versions: ${availableVersions.length > 0 ? availableVersions.join(', ') : 'current'}`
153
+ }]
154
+ };
155
+ }
156
+ }
157
+ const tocResult = await fetchTableOfContents(productId, version, {
158
+ ...(params.page !== undefined && { page: params.page }),
159
+ maxTokens: params.maxTokens ?? TOKEN_CONFIG.DEFAULT_MAX_TOKENS
160
+ });
161
+ const { toc, pagination, tokenInfo } = tocResult;
162
+ // Build response
163
+ const response = {
164
+ product: productInfo.name,
165
+ version,
166
+ toc,
167
+ tokenInfo,
168
+ pagination
169
+ };
170
+ // Format output
171
+ if (params.responseFormat === ResponseFormat.JSON) {
172
+ return {
173
+ content: [{
174
+ type: 'text',
175
+ text: JSON.stringify(response, null, 2)
176
+ }]
177
+ };
178
+ }
179
+ // Format as markdown (compact or full)
180
+ const markdown = params.outputMode === OutputMode.COMPACT
181
+ ? formatTocCompact(productInfo.name, toc, pagination)
182
+ : formatTocFull(productInfo.name, version, toc, pagination, tokenInfo);
183
+ return {
184
+ content: [{
185
+ type: 'text',
186
+ text: markdown
187
+ }]
188
+ };
189
+ }
190
+ catch (error) {
191
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
192
+ return {
193
+ isError: true,
194
+ content: [{
195
+ type: 'text',
196
+ text: `Error fetching table of contents: ${errorMessage}`
197
+ }]
198
+ };
199
+ }
200
+ });
201
+ }
202
+ //# sourceMappingURL=get-toc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-toc.js","sourceRoot":"","sources":["../../src/tools/get-toc.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * jamf_docs_list_products tool
3
+ * Lists all available Jamf products and their documentation versions.
4
+ */
5
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
6
+ export declare function registerListProductsTool(server: McpServer): void;
7
+ //# sourceMappingURL=list-products.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-products.d.ts","sourceRoot":"","sources":["../../src/tools/list-products.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAyCzE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA4HhE"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * jamf_docs_list_products tool
3
+ * Lists all available Jamf products and their documentation versions.
4
+ */
5
+ import { ListProductsInputSchema } from '../schemas/index.js';
6
+ import { JAMF_PRODUCTS, JAMF_TOPICS, ResponseFormat, OutputMode, TOKEN_CONFIG } from '../constants.js';
7
+ import { estimateTokens, createTokenInfo } from '../services/tokenizer.js';
8
+ const TOOL_NAME = 'jamf_docs_list_products';
9
+ const TOOL_DESCRIPTION = `List all available Jamf products, topics, and their documentation versions.
10
+
11
+ This tool returns information about all Jamf products with available documentation,
12
+ including Jamf Pro, Jamf School, Jamf Connect, and Jamf Protect. Also lists available
13
+ topic filters for search.
14
+
15
+ Args:
16
+ - maxTokens (number, optional): Maximum tokens in response 100-20000 (default: 5000)
17
+ - outputMode ('full' | 'compact'): Output detail level (default: 'full'). Use 'compact' for brief list
18
+ - responseFormat ('markdown' | 'json'): Output format (default: 'markdown')
19
+
20
+ Returns:
21
+ For JSON format:
22
+ {
23
+ "products": [...],
24
+ "topics": [...],
25
+ "tokenInfo": {
26
+ "tokenCount": number,
27
+ "truncated": boolean,
28
+ "maxTokens": number
29
+ }
30
+ }
31
+
32
+ For Markdown format:
33
+ A formatted list of products and topics with their details.
34
+
35
+ Examples:
36
+ - "What Jamf products are available?" → use this tool
37
+ - "List all Jamf documentation" → use this tool
38
+ - "What topics can I filter by?" → use this tool
39
+
40
+ Note: This is a read-only operation that does not modify any state.`;
41
+ export function registerListProductsTool(server) {
42
+ server.registerTool(TOOL_NAME, {
43
+ title: 'List Jamf Products',
44
+ description: TOOL_DESCRIPTION,
45
+ inputSchema: ListProductsInputSchema,
46
+ annotations: {
47
+ readOnlyHint: true,
48
+ destructiveHint: false,
49
+ idempotentHint: true,
50
+ openWorldHint: false
51
+ }
52
+ }, (args) => {
53
+ // Parse and validate input
54
+ const parseResult = ListProductsInputSchema.safeParse(args);
55
+ if (!parseResult.success) {
56
+ return {
57
+ isError: true,
58
+ content: [{ type: 'text', text: `Invalid input: ${parseResult.error.message}` }]
59
+ };
60
+ }
61
+ const params = parseResult.data;
62
+ const maxTokens = params.maxTokens ?? TOKEN_CONFIG.DEFAULT_MAX_TOKENS;
63
+ try {
64
+ // Build product list
65
+ const products = Object.values(JAMF_PRODUCTS).map(product => ({
66
+ id: product.id,
67
+ name: product.name,
68
+ description: product.description,
69
+ currentVersion: product.latestVersion,
70
+ availableVersions: [...product.versions]
71
+ }));
72
+ // Build topics list
73
+ const topics = Object.entries(JAMF_TOPICS).map(([id, topic]) => ({
74
+ id,
75
+ name: topic.name,
76
+ keywords: topic.keywords
77
+ }));
78
+ // Format output based on requested format
79
+ if (params.responseFormat === ResponseFormat.JSON) {
80
+ const jsonOutput = JSON.stringify({
81
+ products,
82
+ topics,
83
+ tokenInfo: createTokenInfo(JSON.stringify({ products, topics }), maxTokens)
84
+ }, null, 2);
85
+ return {
86
+ content: [{
87
+ type: 'text',
88
+ text: jsonOutput
89
+ }]
90
+ };
91
+ }
92
+ // Compact mode: minimal output
93
+ if (params.outputMode === OutputMode.COMPACT) {
94
+ let markdown = '## Products\n';
95
+ for (const product of products) {
96
+ markdown += `- \`${product.id}\`: ${product.name}\n`;
97
+ }
98
+ markdown += '\n## Topics\n';
99
+ for (const topic of topics) {
100
+ markdown += `- \`${topic.id}\`: ${topic.name}\n`;
101
+ }
102
+ return {
103
+ content: [{
104
+ type: 'text',
105
+ text: markdown
106
+ }]
107
+ };
108
+ }
109
+ // Full markdown format
110
+ let markdown = '# Jamf Documentation Products\n\n';
111
+ for (const product of products) {
112
+ markdown += `## ${product.name}\n\n`;
113
+ markdown += `- **ID**: \`${product.id}\`\n`;
114
+ markdown += `- **Description**: ${product.description}\n`;
115
+ markdown += `- **Current Version**: ${product.currentVersion}\n`;
116
+ markdown += `- **Available Versions**: ${product.availableVersions.join(', ')}\n\n`;
117
+ }
118
+ markdown += '---\n\n';
119
+ markdown += '# Available Topics for Filtering\n\n';
120
+ markdown += 'Use these topic IDs with the `topic` parameter in `jamf_docs_search`:\n\n';
121
+ for (const topic of topics) {
122
+ markdown += `- **\`${topic.id}\`**: ${topic.name}\n`;
123
+ markdown += ` *Keywords: ${topic.keywords.slice(0, 4).join(', ')}${topic.keywords.length > 4 ? '...' : ''}*\n`;
124
+ }
125
+ markdown += '\n---\n\n';
126
+ // Token info
127
+ const tokenCount = estimateTokens(markdown);
128
+ markdown += `*${tokenCount.toLocaleString()} tokens*\n\n`;
129
+ markdown += '*Use `jamf_docs_search` to search within these products, ';
130
+ markdown += 'or `jamf_docs_get_toc` to browse the table of contents.*\n';
131
+ return {
132
+ content: [{
133
+ type: 'text',
134
+ text: markdown
135
+ }]
136
+ };
137
+ }
138
+ catch (error) {
139
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
140
+ return {
141
+ isError: true,
142
+ content: [{
143
+ type: 'text',
144
+ text: `Error listing products: ${errorMessage}`
145
+ }]
146
+ };
147
+ }
148
+ });
149
+ }
150
+ //# sourceMappingURL=list-products.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-products.js","sourceRoot":"","sources":["../../src/tools/list-products.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * jamf_docs_search tool
3
+ * Search Jamf documentation for articles matching a query.
4
+ */
5
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
6
+ export declare function registerSearchTool(server: McpServer): void;
7
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA8KzE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwI1D"}
@@ -0,0 +1,252 @@
1
+ /**
2
+ * jamf_docs_search tool
3
+ * Search Jamf documentation for articles matching a query.
4
+ */
5
+ import { SearchInputSchema } from '../schemas/index.js';
6
+ import { ResponseFormat, OutputMode, JAMF_PRODUCTS, JAMF_TOPICS, TOKEN_CONFIG } from '../constants.js';
7
+ import { searchDocumentation } from '../services/scraper.js';
8
+ import { generateSearchSuggestions, formatSearchSuggestions } from '../services/search-suggestions.js';
9
+ function formatFiltersLine(filters) {
10
+ const parts = [];
11
+ if (filters.product !== undefined) {
12
+ parts.push(`product: ${filters.product}`);
13
+ }
14
+ if (filters.topic !== undefined) {
15
+ parts.push(`topic: ${filters.topic}`);
16
+ }
17
+ if (filters.version !== undefined) {
18
+ parts.push(`version: ${filters.version}`);
19
+ }
20
+ return parts.length > 0 ? `\n*Filtered by: ${parts.join(', ')}*` : '';
21
+ }
22
+ function formatSearchResult(result) {
23
+ let output = `### [${result.title}](${result.url})\n\n`;
24
+ output += `> ${result.snippet}\n\n`;
25
+ if (result.product !== '' || result.version !== undefined) {
26
+ const meta = [];
27
+ if (result.product !== '') {
28
+ meta.push(`**Product**: ${result.product}`);
29
+ }
30
+ if (result.version !== undefined) {
31
+ meta.push(`**Version**: ${result.version}`);
32
+ }
33
+ output += `${meta.join(' | ')}\n\n`;
34
+ }
35
+ output += '---\n\n';
36
+ return output;
37
+ }
38
+ function formatPaginationFooter(pagination, tokenInfo, compact = false) {
39
+ if (compact) {
40
+ let footer = `\n---\n*Page ${pagination.page}/${pagination.totalPages}`;
41
+ if (pagination.hasNext) {
42
+ footer += ` | page=${pagination.page + 1} for more`;
43
+ }
44
+ footer += '*\n';
45
+ return footer;
46
+ }
47
+ let footer = `**Page ${pagination.page} of ${pagination.totalPages}** (${tokenInfo.tokenCount.toLocaleString()} tokens)`;
48
+ if (pagination.hasNext) {
49
+ footer += ` | Use \`page=${pagination.page + 1}\` for more results`;
50
+ }
51
+ if (tokenInfo.truncated) {
52
+ footer += '\n*Results truncated due to token limit. Use a smaller `limit` or increase `maxTokens`.*';
53
+ }
54
+ footer += '\n\n*Use `jamf_docs_get_article` with any URL above to read the full article.*\n';
55
+ return footer;
56
+ }
57
+ /**
58
+ * Format search result in compact mode (single line)
59
+ */
60
+ function formatSearchResultCompact(result, index) {
61
+ // Truncate snippet for compact display
62
+ const snippetPreview = result.snippet.length > 80
63
+ ? `${result.snippet.slice(0, 77)}...`
64
+ : result.snippet;
65
+ return `${index}. [${result.title}](${result.url}) - ${snippetPreview}\n`;
66
+ }
67
+ /**
68
+ * Format search results as compact markdown
69
+ */
70
+ function formatSearchResultsAsCompact(query, results, filters, pagination, tokenInfo) {
71
+ let markdown = `## "${query}" (${pagination.totalItems} results)\n`;
72
+ markdown += formatFiltersLine(filters);
73
+ markdown += '\n\n';
74
+ results.forEach((result, idx) => {
75
+ markdown += formatSearchResultCompact(result, (pagination.page - 1) * pagination.pageSize + idx + 1);
76
+ });
77
+ markdown += formatPaginationFooter(pagination, tokenInfo, true);
78
+ return markdown;
79
+ }
80
+ function formatSearchResultsAsMarkdown(query, results, filters, pagination, tokenInfo) {
81
+ let markdown = `# Search Results for "${query}"\n\n`;
82
+ markdown += `Found ${pagination.totalItems} result(s) | **Page ${pagination.page} of ${pagination.totalPages}** | ${tokenInfo.tokenCount.toLocaleString()} tokens`;
83
+ markdown += formatFiltersLine(filters);
84
+ markdown += '\n\n---\n\n';
85
+ for (const result of results) {
86
+ markdown += formatSearchResult(result);
87
+ }
88
+ markdown += formatPaginationFooter(pagination, tokenInfo);
89
+ return markdown;
90
+ }
91
+ const TOOL_NAME = 'jamf_docs_search';
92
+ const TOOL_DESCRIPTION = `Search Jamf documentation for articles matching your query.
93
+
94
+ This tool searches across all Jamf product documentation including Jamf Pro,
95
+ Jamf School, Jamf Connect, and Jamf Protect. Results include article titles,
96
+ snippets, and direct links.
97
+
98
+ Args:
99
+ - query (string, required): Search keywords (2-200 characters)
100
+ - product (string, optional): Filter by product ID (jamf-pro, jamf-school, jamf-connect, jamf-protect)
101
+ - topic (string, optional): Filter by topic (enrollment, profiles, security, inventory, policies, smart-groups, apps, identity, api, network)
102
+ - version (string, optional): Filter by version (e.g., "11.5.0", "10.x")
103
+ - limit (number, optional): Maximum results per page 1-50 (default: 10)
104
+ - page (number, optional): Page number for pagination 1-100 (default: 1)
105
+ - maxTokens (number, optional): Maximum tokens in response 100-20000 (default: 5000)
106
+ - outputMode ('full' | 'compact'): Output detail level (default: 'full'). Use 'compact' for brief, token-efficient output
107
+ - responseFormat ('markdown' | 'json'): Output format (default: 'markdown')
108
+
109
+ Returns:
110
+ For JSON format:
111
+ {
112
+ "total": number,
113
+ "query": string,
114
+ "results": [...],
115
+ "tokenInfo": {
116
+ "tokenCount": number,
117
+ "truncated": boolean,
118
+ "maxTokens": number
119
+ },
120
+ "pagination": {
121
+ "page": number,
122
+ "pageSize": number,
123
+ "totalPages": number,
124
+ "totalItems": number,
125
+ "hasNext": boolean,
126
+ "hasPrev": boolean
127
+ }
128
+ }
129
+
130
+ For Markdown format:
131
+ A formatted list of search results with pagination and token info.
132
+
133
+ Examples:
134
+ - "How to configure SSO" → query="SSO configuration"
135
+ - "MDM enrollment steps" → query="MDM enrollment", topic="enrollment"
136
+ - "Jamf Pro configuration profiles" → query="configuration profile", product="jamf-pro", topic="profiles"
137
+ - Get page 2 of results → query="policy", page=2
138
+
139
+ Errors:
140
+ - "No results found" if search returns empty
141
+ - "Invalid product ID" if product parameter is not recognized
142
+
143
+ Note: Results are ranked by relevance. Use filters and pagination to navigate large result sets.`;
144
+ export function registerSearchTool(server) {
145
+ server.registerTool(TOOL_NAME, {
146
+ title: 'Search Jamf Documentation',
147
+ description: TOOL_DESCRIPTION,
148
+ inputSchema: SearchInputSchema,
149
+ annotations: {
150
+ readOnlyHint: true,
151
+ destructiveHint: false,
152
+ idempotentHint: true,
153
+ openWorldHint: true
154
+ }
155
+ }, async (args) => {
156
+ // Parse and validate input
157
+ const parseResult = SearchInputSchema.safeParse(args);
158
+ if (!parseResult.success) {
159
+ return {
160
+ isError: true,
161
+ content: [{ type: 'text', text: `Invalid input: ${parseResult.error.message}` }]
162
+ };
163
+ }
164
+ const params = parseResult.data;
165
+ try {
166
+ // Validate product if provided
167
+ if (params.product !== undefined && !(params.product in JAMF_PRODUCTS)) {
168
+ return {
169
+ isError: true,
170
+ content: [{
171
+ type: 'text',
172
+ text: `Invalid product ID: "${params.product}". Valid options: ${Object.keys(JAMF_PRODUCTS).join(', ')}`
173
+ }]
174
+ };
175
+ }
176
+ // Validate topic if provided
177
+ if (params.topic !== undefined && !(params.topic in JAMF_TOPICS)) {
178
+ return {
179
+ isError: true,
180
+ content: [{
181
+ type: 'text',
182
+ text: `Invalid topic ID: "${params.topic}". Valid options: ${Object.keys(JAMF_TOPICS).join(', ')}`
183
+ }]
184
+ };
185
+ }
186
+ // Perform search with new parameters
187
+ const searchResult = await searchDocumentation({
188
+ query: params.query,
189
+ product: params.product,
190
+ topic: params.topic,
191
+ version: params.version,
192
+ limit: params.limit,
193
+ page: params.page,
194
+ maxTokens: params.maxTokens ?? TOKEN_CONFIG.DEFAULT_MAX_TOKENS
195
+ });
196
+ const { results, pagination, tokenInfo } = searchResult;
197
+ // Build response
198
+ const response = {
199
+ total: pagination.totalItems,
200
+ query: params.query,
201
+ results,
202
+ filters: {
203
+ ...(params.product !== undefined ? { product: params.product } : {}),
204
+ ...(params.version !== undefined ? { version: params.version } : {}),
205
+ ...(params.topic !== undefined ? { topic: params.topic } : {})
206
+ },
207
+ tokenInfo,
208
+ pagination
209
+ };
210
+ // Handle no results with suggestions
211
+ if (results.length === 0 && pagination.totalItems === 0) {
212
+ const suggestions = generateSearchSuggestions(params.query, params.product !== undefined, params.topic !== undefined);
213
+ return {
214
+ content: [{
215
+ type: 'text',
216
+ text: formatSearchSuggestions(params.query, suggestions)
217
+ }]
218
+ };
219
+ }
220
+ // Format output
221
+ if (params.responseFormat === ResponseFormat.JSON) {
222
+ return {
223
+ content: [{
224
+ type: 'text',
225
+ text: JSON.stringify(response, null, 2)
226
+ }]
227
+ };
228
+ }
229
+ // Markdown format (full or compact)
230
+ const markdown = params.outputMode === OutputMode.COMPACT
231
+ ? formatSearchResultsAsCompact(params.query, results, response.filters ?? {}, pagination, tokenInfo)
232
+ : formatSearchResultsAsMarkdown(params.query, results, response.filters ?? {}, pagination, tokenInfo);
233
+ return {
234
+ content: [{
235
+ type: 'text',
236
+ text: markdown
237
+ }]
238
+ };
239
+ }
240
+ catch (error) {
241
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
242
+ return {
243
+ isError: true,
244
+ content: [{
245
+ type: 'text',
246
+ text: `Search error: ${errorMessage}\n\nPlease try again or use different search terms.`
247
+ }]
248
+ };
249
+ }
250
+ });
251
+ }
252
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"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"}