@llmindset/hf-mcp 0.2.40 → 0.2.42

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 (50) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +1 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/space/commands/invoke.d.ts +6 -0
  6. package/dist/space/commands/invoke.d.ts.map +1 -0
  7. package/dist/space/commands/invoke.js +236 -0
  8. package/dist/space/commands/invoke.js.map +1 -0
  9. package/dist/space/commands/view-parameters.d.ts +3 -0
  10. package/dist/space/commands/view-parameters.d.ts.map +1 -0
  11. package/dist/space/commands/view-parameters.js +144 -0
  12. package/dist/space/commands/view-parameters.js.map +1 -0
  13. package/dist/space/space-tool.d.ts +35 -0
  14. package/dist/space/space-tool.d.ts.map +1 -0
  15. package/dist/space/space-tool.js +198 -0
  16. package/dist/space/space-tool.js.map +1 -0
  17. package/dist/space/types.d.ts +74 -0
  18. package/dist/space/types.d.ts.map +1 -0
  19. package/dist/space/types.js +24 -0
  20. package/dist/space/types.js.map +1 -0
  21. package/dist/space/utils/parameter-formatter.d.ts +5 -0
  22. package/dist/space/utils/parameter-formatter.d.ts.map +1 -0
  23. package/dist/space/utils/parameter-formatter.js +132 -0
  24. package/dist/space/utils/parameter-formatter.js.map +1 -0
  25. package/dist/space/utils/result-formatter.d.ts +4 -0
  26. package/dist/space/utils/result-formatter.d.ts.map +1 -0
  27. package/dist/space/utils/result-formatter.js +146 -0
  28. package/dist/space/utils/result-formatter.js.map +1 -0
  29. package/dist/space/utils/schema-validator.d.ts +9 -0
  30. package/dist/space/utils/schema-validator.d.ts.map +1 -0
  31. package/dist/space/utils/schema-validator.js +145 -0
  32. package/dist/space/utils/schema-validator.js.map +1 -0
  33. package/dist/space-search.d.ts.map +1 -1
  34. package/dist/space-search.js +5 -4
  35. package/dist/space-search.js.map +1 -1
  36. package/dist/tool-ids.d.ts +4 -2
  37. package/dist/tool-ids.d.ts.map +1 -1
  38. package/dist/tool-ids.js +4 -1
  39. package/dist/tool-ids.js.map +1 -1
  40. package/package.json +2 -1
  41. package/src/index.ts +1 -0
  42. package/src/space/commands/invoke.ts +335 -0
  43. package/src/space/commands/view-parameters.ts +204 -0
  44. package/src/space/space-tool.ts +252 -0
  45. package/src/space/types.ts +127 -0
  46. package/src/space/utils/parameter-formatter.ts +200 -0
  47. package/src/space/utils/result-formatter.ts +226 -0
  48. package/src/space/utils/schema-validator.ts +232 -0
  49. package/src/space-search.ts +5 -4
  50. package/src/tool-ids.ts +4 -0
@@ -0,0 +1,200 @@
1
+ import type { SchemaComplexityResult, ParameterInfo } from '../types.js';
2
+ import { FILE_INPUT_HELP_MESSAGE } from '../types.js';
3
+
4
+ /**
5
+ * Formats parameter schema for display to users
6
+ * Shows parameters in a clear, organized manner with:
7
+ * - Required parameters first
8
+ * - Alphabetical sorting within groups
9
+ * - Clear type information
10
+ * - Default values
11
+ * - Enum options
12
+ */
13
+ export function formatParameters(schemaResult: SchemaComplexityResult, spaceName: string): string {
14
+ const { toolName, toolDescription, parameters } = schemaResult;
15
+
16
+ let output = `# Parameters for: ${toolName}\n\n`;
17
+
18
+ if (toolDescription) {
19
+ output += `**Description:** ${toolDescription}\n\n`;
20
+ }
21
+
22
+ // Sort parameters: required first, then alphabetical
23
+ const sortedParams = [...parameters].sort((a, b) => {
24
+ if (a.required !== b.required) {
25
+ return a.required ? -1 : 1;
26
+ }
27
+ return a.name.localeCompare(b.name);
28
+ });
29
+
30
+ output += `## Parameters:\n\n`;
31
+
32
+ for (const param of sortedParams) {
33
+ output += formatParameter(param);
34
+ }
35
+
36
+ // Add usage example
37
+ output += '\n## Usage Example:\n\n';
38
+ output += formatUsageExample(spaceName, parameters);
39
+
40
+ return output;
41
+ }
42
+
43
+ /**
44
+ * Formats a single parameter for display
45
+ */
46
+ function formatParameter(param: ParameterInfo): string {
47
+ const badge = param.required ? '[REQUIRED]' : '[OPTIONAL]';
48
+ let output = `### ${param.name} ${badge}\n`;
49
+
50
+ // Type
51
+ output += `- **Type:** ${param.type}\n`;
52
+
53
+ // Description
54
+ if (param.description) {
55
+ output += `- **Description:** ${param.description}\n`;
56
+ }
57
+
58
+ // Default value
59
+ if (param.default !== undefined) {
60
+ const defaultStr = formatValue(param.default);
61
+ output += `- **Default:** ${defaultStr}\n`;
62
+ }
63
+
64
+ // Enum values
65
+ if (param.enum && param.enum.length > 0) {
66
+ const enumStr = param.enum.map((v) => formatValue(v)).join(', ');
67
+ output += `- **Allowed values:** ${enumStr}\n`;
68
+ }
69
+
70
+ // File input help
71
+ if (param.isFileData) {
72
+ output += `- **Note:** ${FILE_INPUT_HELP_MESSAGE}\n`;
73
+ }
74
+
75
+ output += '\n';
76
+ return output;
77
+ }
78
+
79
+ /**
80
+ * Formats a value for display
81
+ */
82
+ function formatValue(value: unknown): string {
83
+ if (value === null) return 'null';
84
+ if (value === undefined) return 'undefined';
85
+ if (typeof value === 'string') return `"${value}"`;
86
+ if (typeof value === 'object') {
87
+ try {
88
+ return JSON.stringify(value);
89
+ } catch {
90
+ return '[object]';
91
+ }
92
+ }
93
+ if (typeof value === 'number' || typeof value === 'boolean') {
94
+ return String(value);
95
+ }
96
+ return JSON.stringify(value);
97
+ }
98
+
99
+ /**
100
+ * Formats a usage example
101
+ */
102
+ function formatUsageExample(spaceName: string, parameters: ParameterInfo[]): string {
103
+ // Create example with required parameters and some optional ones
104
+ const exampleParams: Record<string, string> = {};
105
+
106
+ // Add required parameters
107
+ for (const param of parameters.filter((p) => p.required)) {
108
+ exampleParams[param.name] = getExampleValue(param);
109
+ }
110
+
111
+ // Add one or two optional parameters if they exist
112
+ const optionalParams = parameters.filter((p) => !p.required);
113
+ for (let i = 0; i < Math.min(2, optionalParams.length); i++) {
114
+ const param = optionalParams[i];
115
+ if (param) {
116
+ exampleParams[param.name] = getExampleValue(param);
117
+ }
118
+ }
119
+
120
+ const paramsJson = JSON.stringify(exampleParams, null, 2)
121
+ .split('\n')
122
+ .map((line) => ` ${line}`)
123
+ .join('\n')
124
+ .trim();
125
+
126
+ return `\`\`\`json
127
+ {
128
+ "operation": "invoke",
129
+ "space_name": "${spaceName}",
130
+ "parameters": "${paramsJson.replace(/"/g, '\\"')}"
131
+ }
132
+ \`\`\``;
133
+ }
134
+
135
+ /**
136
+ * Gets an example value for a parameter
137
+ */
138
+ function getExampleValue(param: ParameterInfo): string {
139
+ // Use default if available
140
+ if (param.default !== undefined) {
141
+ return formatValue(param.default);
142
+ }
143
+
144
+ // Use first enum value if available
145
+ if (param.enum && param.enum.length > 0) {
146
+ return formatValue(param.enum[0]);
147
+ }
148
+
149
+ // File data
150
+ if (param.isFileData) {
151
+ return '"https://example.com/file.jpg"';
152
+ }
153
+
154
+ // Generate example based on type
155
+ const baseType = param.type.split(' ')[0]?.split('<')[0];
156
+
157
+ switch (baseType) {
158
+ case 'string':
159
+ return '"example value"';
160
+ case 'number':
161
+ case 'integer':
162
+ return '42';
163
+ case 'boolean':
164
+ return 'true';
165
+ case 'array':
166
+ return '["item1", "item2"]';
167
+ case 'object':
168
+ return '{"key": "value"}';
169
+ default:
170
+ return '"value"';
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Formats a complex schema error message
176
+ */
177
+ export function formatComplexSchemaError(spaceName: string, reason: string): string {
178
+ return `Error: Schema too complex for space '${spaceName}'.
179
+
180
+ ${reason}
181
+
182
+ Supported types: strings, numbers, booleans, arrays of primitives, enums, shallow objects, and file URLs.
183
+
184
+ For this space, use the dedicated gr_* prefixed tools instead.`;
185
+ }
186
+
187
+ /**
188
+ * Formats validation errors
189
+ */
190
+ export function formatValidationError(errors: string[], spaceName: string): string {
191
+ let output = `Error: Invalid parameters for space '${spaceName}'.\n\n`;
192
+
193
+ for (const error of errors) {
194
+ output += `- ${error}\n`;
195
+ }
196
+
197
+ output += `\nUse the view_parameters operation to see all required parameters and their types.`;
198
+
199
+ return output;
200
+ }
@@ -0,0 +1,226 @@
1
+ import type { CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';
2
+
3
+ /**
4
+ * Formats tool result for user-friendly display
5
+ * Handles different content types:
6
+ * - Text content (primary)
7
+ * - Image content (with descriptions)
8
+ * - Resource content (with URIs)
9
+ * - Error results
10
+ */
11
+ export function formatToolResult(result: typeof CallToolResultSchema._type): string {
12
+ // Handle error results
13
+ if (result.isError) {
14
+ return formatErrorResult(result);
15
+ }
16
+
17
+ // Handle successful results with content
18
+ if (Array.isArray(result.content) && result.content.length > 0) {
19
+ return formatContentArray(result.content);
20
+ }
21
+
22
+ // Fallback for empty results
23
+ return 'Tool executed successfully (no content returned).';
24
+ }
25
+
26
+ /**
27
+ * Formats error results
28
+ */
29
+ function formatErrorResult(result: typeof CallToolResultSchema._type): string {
30
+ if (!Array.isArray(result.content) || result.content.length === 0) {
31
+ return 'Error: Tool execution failed (no error details provided).';
32
+ }
33
+
34
+ const errorMessages: string[] = [];
35
+
36
+ for (const item of result.content) {
37
+ if (typeof item === 'string') {
38
+ errorMessages.push(item);
39
+ } else if (item && typeof item === 'object') {
40
+ const obj = item as Record<string, unknown>;
41
+ if (typeof obj.text === 'string') {
42
+ errorMessages.push(obj.text);
43
+ } else if (typeof obj.message === 'string') {
44
+ errorMessages.push(obj.message);
45
+ } else if (typeof obj.error === 'string') {
46
+ errorMessages.push(obj.error);
47
+ }
48
+ }
49
+ }
50
+
51
+ if (errorMessages.length > 0) {
52
+ return `Error: ${errorMessages.join('\n')}`;
53
+ }
54
+
55
+ return 'Error: Tool execution failed.';
56
+ }
57
+
58
+ /**
59
+ * Formats an array of content items
60
+ */
61
+ function formatContentArray(content: unknown[]): string {
62
+ const formattedItems: string[] = [];
63
+
64
+ for (const item of content) {
65
+ const formatted = formatContentItem(item);
66
+ if (formatted) {
67
+ formattedItems.push(formatted);
68
+ }
69
+ }
70
+
71
+ if (formattedItems.length === 0) {
72
+ return 'Tool executed successfully (no displayable content).';
73
+ }
74
+
75
+ return formattedItems.join('\n\n');
76
+ }
77
+
78
+ /**
79
+ * Formats a single content item
80
+ */
81
+ function formatContentItem(item: unknown): string | null {
82
+ if (!item) {
83
+ return null;
84
+ }
85
+
86
+ // Handle string content
87
+ if (typeof item === 'string') {
88
+ return item;
89
+ }
90
+
91
+ // Handle non-object content
92
+ if (typeof item !== 'object') {
93
+ if (typeof item === 'number' || typeof item === 'boolean') {
94
+ return String(item);
95
+ }
96
+ return JSON.stringify(item);
97
+ }
98
+
99
+ const obj = item as Record<string, unknown>;
100
+ const type = typeof obj.type === 'string' ? obj.type.toLowerCase() : undefined;
101
+
102
+ switch (type) {
103
+ case 'text':
104
+ return formatTextContent(obj);
105
+
106
+ case 'image':
107
+ return formatImageContent(obj);
108
+
109
+ case 'resource':
110
+ return formatResourceContent(obj);
111
+
112
+ case 'embedded_resource':
113
+ return formatEmbeddedResourceContent(obj);
114
+
115
+ default:
116
+ // Try to extract text from unknown types
117
+ if (typeof obj.text === 'string') {
118
+ return obj.text;
119
+ }
120
+ // Fallback to JSON representation
121
+ try {
122
+ return JSON.stringify(item, null, 2);
123
+ } catch {
124
+ return '[complex object]';
125
+ }
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Formats text content
131
+ */
132
+ function formatTextContent(obj: Record<string, unknown>): string | null {
133
+ if (typeof obj.text === 'string') {
134
+ return obj.text;
135
+ }
136
+ return null;
137
+ }
138
+
139
+ /**
140
+ * Formats image content
141
+ */
142
+ function formatImageContent(obj: Record<string, unknown>): string {
143
+ const parts: string[] = ['[Image Content]'];
144
+
145
+ // Add MIME type if available
146
+ if (typeof obj.mimeType === 'string') {
147
+ parts.push(`Type: ${obj.mimeType}`);
148
+ }
149
+
150
+ // Add URL if available
151
+ if (typeof obj.url === 'string') {
152
+ parts.push(`URL: ${obj.url}`);
153
+ }
154
+
155
+ // Add data indicator if present
156
+ if (typeof obj.data === 'string') {
157
+ const dataLength = obj.data.length;
158
+ parts.push(`Data: ${dataLength} characters (base64)`);
159
+ }
160
+
161
+ return parts.join('\n');
162
+ }
163
+
164
+ /**
165
+ * Formats resource content
166
+ */
167
+ function formatResourceContent(obj: Record<string, unknown>): string {
168
+ const parts: string[] = ['[Resource]'];
169
+
170
+ // Extract resource details
171
+ const resource = obj.resource as Record<string, unknown> | undefined;
172
+ if (resource) {
173
+ if (typeof resource.uri === 'string') {
174
+ parts.push(`URI: ${resource.uri}`);
175
+ }
176
+
177
+ if (typeof resource.name === 'string') {
178
+ parts.push(`Name: ${resource.name}`);
179
+ }
180
+
181
+ if (typeof resource.mimeType === 'string') {
182
+ parts.push(`Type: ${resource.mimeType}`);
183
+ }
184
+
185
+ if (typeof resource.description === 'string') {
186
+ parts.push(`Description: ${resource.description}`);
187
+ }
188
+ }
189
+
190
+ return parts.join('\n');
191
+ }
192
+
193
+ /**
194
+ * Formats embedded resource content
195
+ */
196
+ function formatEmbeddedResourceContent(obj: Record<string, unknown>): string {
197
+ const parts: string[] = ['[Embedded Resource]'];
198
+
199
+ if (typeof obj.uri === 'string') {
200
+ parts.push(`URI: ${obj.uri}`);
201
+ }
202
+
203
+ if (typeof obj.mimeType === 'string') {
204
+ parts.push(`Type: ${obj.mimeType}`);
205
+ }
206
+
207
+ // Add blob indicator if present
208
+ if (typeof obj.blob === 'string') {
209
+ const blobLength = obj.blob.length;
210
+ parts.push(`Data: ${blobLength} characters`);
211
+ }
212
+
213
+ return parts.join('\n');
214
+ }
215
+
216
+ /**
217
+ * Formats a list of warnings
218
+ */
219
+ export function formatWarnings(warnings: string[]): string {
220
+ if (warnings.length === 0) {
221
+ return '';
222
+ }
223
+
224
+ const header = warnings.length === 1 ? 'Warning:' : 'Warnings:';
225
+ return `${header}\n${warnings.map((w) => `- ${w}`).join('\n')}\n\n`;
226
+ }
@@ -0,0 +1,232 @@
1
+ import type { Tool } from '@modelcontextprotocol/sdk/types.js';
2
+ import type {
3
+ JsonSchema,
4
+ JsonSchemaProperty,
5
+ SchemaComplexityResult,
6
+ ParameterInfo,
7
+ } from '../types.js';
8
+ import { isFileDataProperty } from '../types.js';
9
+
10
+ /**
11
+ * Analyzes a tool schema to determine if it's simple enough for the dynamic space tool
12
+ *
13
+ * Supported types:
14
+ * - string, number, boolean
15
+ * - enum (with predefined values)
16
+ * - array of primitives
17
+ * - shallow objects (one level deep with primitive properties)
18
+ * - FileData (as string URLs)
19
+ *
20
+ * Rejected types:
21
+ * - Deeply nested objects (2+ levels)
22
+ * - Arrays of objects
23
+ * - Union types
24
+ * - Recursive schemas
25
+ */
26
+ export function analyzeSchemaComplexity(tool: Tool): SchemaComplexityResult {
27
+ const result: SchemaComplexityResult = {
28
+ isSimple: true,
29
+ parameters: [],
30
+ toolName: tool.name,
31
+ toolDescription: tool.description,
32
+ };
33
+
34
+ const inputSchema = tool.inputSchema as JsonSchema;
35
+ if (!inputSchema || !inputSchema.properties) {
36
+ return result;
37
+ }
38
+
39
+ const properties = inputSchema.properties;
40
+ const required = inputSchema.required || [];
41
+
42
+ for (const [paramName, prop] of Object.entries(properties)) {
43
+ const paramInfo = analyzeProperty(paramName, prop, required.includes(paramName));
44
+
45
+ // Check if this parameter is too complex
46
+ if (paramInfo.complexType) {
47
+ result.isSimple = false;
48
+ result.reason = `Parameter "${paramName}" has complex type: ${paramInfo.complexType}`;
49
+ return result;
50
+ }
51
+
52
+ result.parameters.push(paramInfo);
53
+ }
54
+
55
+ return result;
56
+ }
57
+
58
+ /**
59
+ * Analyzes a single property to extract parameter information
60
+ */
61
+ function analyzeProperty(name: string, prop: JsonSchemaProperty, isRequired: boolean): ParameterInfo {
62
+ const paramInfo: ParameterInfo = {
63
+ name,
64
+ type: prop.type || 'unknown',
65
+ description: prop.description,
66
+ required: isRequired,
67
+ default: prop.default,
68
+ enum: prop.enum,
69
+ };
70
+
71
+ // Check for FileData types - treat as string URLs
72
+ if (isFileDataProperty(prop)) {
73
+ paramInfo.type = 'string (file URL)';
74
+ paramInfo.isFileData = true;
75
+ return paramInfo;
76
+ }
77
+
78
+ // Check for enum types
79
+ if (prop.enum && Array.isArray(prop.enum) && prop.enum.length > 0) {
80
+ paramInfo.type = `enum (${prop.enum.length} values)`;
81
+ return paramInfo;
82
+ }
83
+
84
+ // Check for complex types
85
+ if (prop.type === 'object') {
86
+ // Check if it's a shallow object
87
+ if (prop.properties) {
88
+ const nestedProps = Object.values(prop.properties);
89
+ const hasComplexNested = nestedProps.some(
90
+ (nested) => nested.type === 'object' || nested.type === 'array'
91
+ );
92
+
93
+ if (hasComplexNested) {
94
+ paramInfo.complexType = 'deeply nested object (2+ levels)';
95
+ } else {
96
+ paramInfo.type = 'object (shallow)';
97
+ }
98
+ } else {
99
+ // Object without properties definition is too vague
100
+ paramInfo.complexType = 'object without defined properties';
101
+ }
102
+ return paramInfo;
103
+ }
104
+
105
+ // Check for array types
106
+ if (prop.type === 'array') {
107
+ if (prop.items) {
108
+ const itemType = prop.items.type;
109
+ if (itemType === 'object') {
110
+ paramInfo.complexType = 'array of objects';
111
+ } else if (itemType === 'array') {
112
+ paramInfo.complexType = 'nested arrays';
113
+ } else {
114
+ paramInfo.type = `array<${itemType || 'unknown'}>`;
115
+ }
116
+ } else {
117
+ paramInfo.type = 'array<any>';
118
+ }
119
+ return paramInfo;
120
+ }
121
+
122
+ // Simple types are fine
123
+ if (['string', 'number', 'integer', 'boolean'].includes(prop.type || '')) {
124
+ return paramInfo;
125
+ }
126
+
127
+ // Unknown or unsupported type
128
+ if (!prop.type) {
129
+ paramInfo.complexType = 'unknown type';
130
+ }
131
+
132
+ return paramInfo;
133
+ }
134
+
135
+ /**
136
+ * Validates parameter values against the schema
137
+ */
138
+ export function validateParameters(
139
+ parameters: Record<string, unknown>,
140
+ schemaResult: SchemaComplexityResult
141
+ ): { valid: boolean; errors: string[] } {
142
+ const errors: string[] = [];
143
+
144
+ // Check for missing required parameters
145
+ const requiredParams = schemaResult.parameters.filter((p) => p.required);
146
+ for (const param of requiredParams) {
147
+ if (!(param.name in parameters) || parameters[param.name] === undefined) {
148
+ errors.push(`Missing required parameter: "${param.name}"`);
149
+ }
150
+ }
151
+
152
+ // Check types (basic validation)
153
+ for (const [key, value] of Object.entries(parameters)) {
154
+ const paramInfo = schemaResult.parameters.find((p) => p.name === key);
155
+
156
+ if (!paramInfo) {
157
+ // Unknown parameter - warning but not error (permissive inputs)
158
+ continue;
159
+ }
160
+
161
+ // Type checking
162
+ if (value !== null && value !== undefined) {
163
+ if (!validateType(value, paramInfo)) {
164
+ errors.push(
165
+ `Parameter "${key}" should be type ${paramInfo.type}, got ${typeof value}`
166
+ );
167
+ }
168
+ }
169
+ }
170
+
171
+ return {
172
+ valid: errors.length === 0,
173
+ errors,
174
+ };
175
+ }
176
+
177
+ /**
178
+ * Validates a value against a parameter type
179
+ */
180
+ function validateType(value: unknown, paramInfo: ParameterInfo): boolean {
181
+ // FileData as string URL
182
+ if (paramInfo.isFileData) {
183
+ return typeof value === 'string';
184
+ }
185
+
186
+ // Enum validation
187
+ if (paramInfo.enum && Array.isArray(paramInfo.enum)) {
188
+ return paramInfo.enum.includes(value);
189
+ }
190
+
191
+ // Basic type validation
192
+ const baseType = paramInfo.type.split(' ')[0]?.split('<')[0]; // Extract base type
193
+
194
+ switch (baseType) {
195
+ case 'string':
196
+ return typeof value === 'string';
197
+ case 'number':
198
+ case 'integer':
199
+ return typeof value === 'number';
200
+ case 'boolean':
201
+ return typeof value === 'boolean';
202
+ case 'array':
203
+ return Array.isArray(value);
204
+ case 'object':
205
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
206
+ case 'enum':
207
+ // Already checked above
208
+ return true;
209
+ default:
210
+ // Unknown type, allow it (permissive)
211
+ return true;
212
+ }
213
+ }
214
+
215
+ /**
216
+ * Applies default values to parameters
217
+ */
218
+ export function applyDefaults(
219
+ parameters: Record<string, unknown>,
220
+ schemaResult: SchemaComplexityResult
221
+ ): Record<string, unknown> {
222
+ const result = { ...parameters };
223
+
224
+ for (const param of schemaResult.parameters) {
225
+ // Only apply defaults for optional parameters that are missing
226
+ if (!param.required && !(param.name in result) && param.default !== undefined) {
227
+ result[param.name] = param.default;
228
+ }
229
+ }
230
+
231
+ return result;
232
+ }
@@ -34,7 +34,8 @@ const RESULTS_TO_RETURN = 10;
34
34
  export const SEMANTIC_SEARCH_TOOL_CONFIG = {
35
35
  name: 'space_search',
36
36
  description:
37
- 'Find Hugging Face Spaces using semantic search. ' + 'Include links to the Space when presenting the results.',
37
+ 'Find Hugging Face Spaces using semantic search. IMPORTANT Only MCP Servers can be used with the dynamic_space tool' +
38
+ 'Include links to the Space when presenting the results.',
38
39
  schema: z.object({
39
40
  query: z.string().min(1, 'Query is required').max(100, 'Query too long').describe('Semantic Search Query'),
40
41
  limit: z.number().optional().default(RESULTS_TO_RETURN).describe('Number of results to return'),
@@ -115,7 +116,7 @@ export class SpaceSearchTool extends HfApiCall<SpaceSearchParams, SpaceSearchRes
115
116
  return {
116
117
  formatted: `No matching Hugging Face Spaces found referencing ${filter}.`,
117
118
  totalResults: 0,
118
- resultsShared: 0
119
+ resultsShared: 0,
119
120
  };
120
121
  }
121
122
 
@@ -150,7 +151,7 @@ export const formatSearchResults = (
150
151
  return {
151
152
  formatted: `No matching Hugging Face Spaces found for the query '${query}'. Try a different query.`,
152
153
  totalResults: 0,
153
- resultsShared: 0
154
+ resultsShared: 0,
154
155
  };
155
156
  }
156
157
 
@@ -185,6 +186,6 @@ export const formatSearchResults = (
185
186
  return {
186
187
  formatted: markdown,
187
188
  totalResults: totalCount,
188
- resultsShared: results.length
189
+ resultsShared: results.length,
189
190
  };
190
191
  };