import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { ListToolsRequestSchema, CallToolRequestSchema, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
import { z } from 'zod';
import { v4 as uuidv4 } from 'uuid';
import { BecknClient } from '../lib/becknClient.js';
import { WebhookManager } from '../lib/webhookManager.js';
export function registerMobilityTools(server: Server, becknClient: BecknClient) {
const webhookManager = WebhookManager.getInstance();
// Helper to create context
const createContext = (action: string) => {
return {
domain: 'mobility',
action,
version: '1.1.0',
bap_id: becknClient.bapId,
bap_uri: becknClient.bapUri,
location: {
city: {
code: 'std:080'
},
country: {
code: 'IND'
}
},
transaction_id: uuidv4(),
message_id: uuidv4(),
timestamp: new Date().toISOString(),
ttl: 'PT30S',
};
};
const tools = {
search_cabs: {
description: 'Search for cabs from origin to destination',
inputSchema: {
type: 'object',
properties: {
start_gps: { type: 'string', description: 'Origin GPS coordinates (lat,long)' },
end_gps: { type: 'string', description: 'Destination GPS coordinates (lat,long)' }
},
required: ['start_gps', 'end_gps']
},
handler: async (args: any) => {
const { start_gps, end_gps } = args;
const context = createContext('search');
const message = {
intent: {
fulfillment: {
start: { location: { gps: start_gps } },
end: { location: { gps: end_gps } },
},
},
};
await becknClient.sendRequest(context.action, { context, message });
const response = await webhookManager.waitForResponse(context.message_id);
return {
content: [{ type: 'text', text: JSON.stringify(response) }]
};
}
},
select_ride: {
description: 'Select a specific ride option',
inputSchema: {
type: 'object',
properties: {
provider_id: { type: 'string' },
item_id: { type: 'string' },
transaction_id: { type: 'string' }
},
required: ['provider_id', 'item_id', 'transaction_id']
},
handler: async (args: any) => {
const { provider_id, item_id, transaction_id } = args;
const context = createContext('select');
context.transaction_id = transaction_id;
const message = {
order: {
provider: { id: provider_id },
items: [{ id: item_id }],
},
};
await becknClient.sendRequest(context.action, { context, message });
const response = await webhookManager.waitForResponse(context.message_id);
return {
content: [{ type: 'text', text: JSON.stringify(response) }]
};
}
}
};
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: Object.entries(tools).map(([name, tool]) => ({
name,
description: tool.description,
inputSchema: tool.inputSchema
}))
};
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const toolName = request.params.name;
const tool = tools[toolName as keyof typeof tools];
if (!tool) {
throw new McpError(ErrorCode.MethodNotFound, `Tool ${toolName} not found`);
}
try {
return await tool.handler(request.params.arguments);
} catch (error) {
return {
content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }],
isError: true
};
}
});
}