#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { JsmClient } from './api/jsmClient.js';
import { getConfig, logDebug } from './utils/index.js';
import {
searchAssetsAqlTool,
handleSearchAssetsAql
} from './tools/searchAssetsAql.js';
import {
getObjectSchemasTool,
handleGetObjectSchemas
} from './tools/getObjectSchemas.js';
import {
getObjectTypesTool,
handleGetObjectTypes
} from './tools/getObjectTypes.js';
import {
getObjectAttributesTool,
handleGetObjectAttributes
} from './tools/getObjectAttributes.js';
import {
searchChildObjectsTool,
handleSearchChildObjects
} from './tools/searchChildObjects.js';
class JsmAssetsMcpServer {
private server: Server;
private jsmClient: JsmClient;
constructor() {
this.server = new Server(
{
name: 'jsm-assets-mcp',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
);
try {
const config = getConfig();
this.jsmClient = new JsmClient(config);
logDebug('JSM Assets MCP Server initialized', {
workspaceId: config.workspaceId,
baseUrl: config.baseUrl
});
} catch (error) {
console.error('Failed to initialize JSM client:', error);
process.exit(1);
}
this.setupToolHandlers();
}
private setupToolHandlers(): void {
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
searchAssetsAqlTool,
getObjectSchemasTool,
getObjectTypesTool,
getObjectAttributesTool,
searchChildObjectsTool,
],
};
});
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
switch (name) {
case 'search_assets_aql':
return await handleSearchAssetsAql(this.jsmClient, args);
case 'get_object_schemas':
return await handleGetObjectSchemas(this.jsmClient);
case 'get_object_types':
return await handleGetObjectTypes(this.jsmClient, args);
case 'get_object_attributes':
return await handleGetObjectAttributes(this.jsmClient, args);
case 'search_child_objects':
return await handleSearchChildObjects(this.jsmClient, args);
default:
throw new Error(`Unknown tool: ${name}`);
}
} catch (error) {
logDebug('Tool execution error', { name, error });
return {
content: [
{
type: 'text',
text: `Error executing tool ${name}: ${error instanceof Error ? error.message : String(error)}`,
},
],
};
}
});
}
async run(): Promise<void> {
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error('JSM Assets MCP Server running on stdio');
logDebug('Server started and connected via stdio transport');
}
}
const server = new JsmAssetsMcpServer();
server.run().catch((error) => {
console.error('Fatal error running server:', error);
process.exit(1);
});