tools.ts•4.19 kB
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { Tool, ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
import { z } from 'zod';
import axios from 'axios';
// Create axios instance with base configuration
const tracxnClient = axios.create({
baseURL: 'https://platform.tracxn.com/api/2.2/playground',
headers: {
'Authorization': `Bearer ${process.env.TRACXN_API_KEY}`,
'Content-Type': 'application/json',
'Accept': 'application/json',
},
});
// Add request interceptor for debugging
tracxnClient.interceptors.request.use(
(config) => {
console.error(`Making request to: ${config.method?.toUpperCase()} ${config.url}`);
console.error(`Headers:`, config.headers);
return config;
},
(error) => {
return Promise.reject(error);
}
);
// Add response interceptor for better error handling
tracxnClient.interceptors.response.use(
(response) => {
console.error(`Response status: ${response.status}`);
console.error(`Response headers:`, response.headers);
return response;
},
async (error) => {
console.error(`Request failed:`, error.message);
if (error.response) {
console.error(`Response status: ${error.response.status}`);
console.error(`Response data:`, error.response.data);
}
if (error.response?.status === 429) {
const retryAfter = error.response.headers['retry-after'] || 5;
const jitter = Math.random() * 1000;
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000 + jitter));
return tracxnClient(error.config);
}
return Promise.reject(error);
}
);
interface ToolArgs {
companyId: string;
}
export async function registerTracxnTools(server: Server) {
// Example tool for fetching company information
const getCompanyTool: Tool = {
name: 'get_company',
description: 'Fetch detailed information about a company from Tracxn',
inputSchema: {
type: 'object',
properties: {
companyId: {
type: 'string',
description: 'The unique identifier of the company'
}
},
required: ['companyId']
},
outputSchema: {
type: 'object',
properties: {
id: { type: 'string' },
name: { type: 'string' },
description: { type: 'string' }
},
required: ['id', 'name']
}
};
// Register the tool with the server
server.setRequestHandler(ListToolsRequestSchema, async (request) => {
return {
tools: [getCompanyTool]
};
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
if (!args) {
throw new Error('No arguments provided');
}
if (name !== 'get_company') {
throw new Error(`Unknown tool: ${name}`);
}
// Check if API key is available
if (!process.env.TRACXN_API_KEY) {
throw new Error('TRACXN_API_KEY environment variable is not set');
}
const toolArgs = args as unknown as ToolArgs;
if (!toolArgs.companyId) {
throw new Error('companyId is required');
}
try {
const response = await tracxnClient.get(`/companies/${toolArgs.companyId}`);
// Check if response is HTML (login page)
if (typeof response.data === 'string' && response.data.includes('<!DOCTYPE html>')) {
throw new Error('Received HTML response instead of JSON. This usually means authentication failed. Please check your API key.');
}
return {
content: [{ type: 'text', text: JSON.stringify(response.data, null, 2) }],
isError: false
};
} catch (error: any) {
if (error.response?.status === 401) {
throw new Error('Authentication failed. Please check your API key.');
} else if (error.response?.status === 403) {
throw new Error('Access forbidden. Please check your API key permissions.');
} else if (error.response?.status === 404) {
throw new Error(`Company with ID ${toolArgs.companyId} not found.`);
} else {
throw new Error(`API request failed: ${error.message}`);
}
}
});
}