Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-Claude) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
54 lines
1.8 KiB
TypeScript
54 lines
1.8 KiB
TypeScript
import { z } from 'zod';
|
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
import type { RestClient } from '../clients/rest-client.js';
|
|
import { formatQueryResponse } from '../utils/response.js';
|
|
import { formatToolError, classifyError, getErrorHint } from '../utils/errors.js';
|
|
|
|
function buildWhereClause(entity: string, searchTerm: string, searchFields?: string[]): string {
|
|
const fields = searchFields && searchFields.length > 0
|
|
? searchFields
|
|
: [`${entity}NUM`, `${entity}NAM`];
|
|
|
|
const conditions = fields.map((field) => `contains(${field},'${searchTerm}')`);
|
|
return conditions.length === 1
|
|
? conditions[0]
|
|
: `(${conditions.join(' or ')})`;
|
|
}
|
|
|
|
export function registerSearchTool(server: McpServer, restClient: RestClient): void {
|
|
server.registerTool(
|
|
'sage_search',
|
|
{
|
|
description:
|
|
'Search Sage X3 records with flexible text matching. Builds SData where clauses from a search term across common fields.',
|
|
inputSchema: {
|
|
entity: z.string(),
|
|
searchTerm: z.string(),
|
|
searchFields: z.array(z.string()).optional(),
|
|
count: z.number().min(1).max(200).optional(),
|
|
},
|
|
annotations: {
|
|
readOnlyHint: true,
|
|
destructiveHint: false,
|
|
idempotentHint: true,
|
|
openWorldHint: true,
|
|
},
|
|
},
|
|
async (args) => {
|
|
try {
|
|
const where = buildWhereClause(args.entity, args.searchTerm, args.searchFields);
|
|
const result = await restClient.query({
|
|
entity: args.entity,
|
|
where,
|
|
count: args.count,
|
|
});
|
|
return formatQueryResponse(result.records, result.pagination);
|
|
} catch (error) {
|
|
return formatToolError(error, getErrorHint(classifyError(error)));
|
|
}
|
|
},
|
|
);
|
|
}
|
|
|
|
export { buildWhereClause };
|