#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
Tool,
} from "@modelcontextprotocol/sdk/types.js";
import { fetchZenrusData } from "./api.js";
// Создаем сервер
const server = new Server(
{
name: "zenrus-mcp",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
// Определяем инструменты
const tools: Tool[] = [
{
name: "get_usd_rate",
description: "Get current USD/RUB exchange rate from zenrus.ru",
inputSchema: {
type: "object",
properties: {},
},
},
{
name: "get_eur_rate",
description: "Get current EUR/RUB exchange rate from zenrus.ru",
inputSchema: {
type: "object",
properties: {},
},
},
{
name: "get_brent_usd_rate",
description: "Get current Brent crude oil price in USD per barrel from zenrus.ru",
inputSchema: {
type: "object",
properties: {},
},
},
{
name: "get_brent_rub_rate",
description: "Get current Brent crude oil price in RUB per barrel from zenrus.ru",
inputSchema: {
type: "object",
properties: {},
},
},
{
name: "calculate_barrels_for_rub",
description: "Calculate how many barrels of Brent crude oil can be purchased for a given amount in Russian Rubles",
inputSchema: {
type: "object",
properties: {
amount: {
type: "number",
description: "Amount in Russian Rubles",
},
},
required: ["amount"],
},
},
{
name: "calculate_barrels_for_usd",
description: "Calculate how many barrels of Brent crude oil can be purchased for a given amount in US Dollars",
inputSchema: {
type: "object",
properties: {
amount: {
type: "number",
description: "Amount in US Dollars",
},
},
required: ["amount"],
},
},
{
name: "calculate_barrels_for_eur",
description: "Calculate how many barrels of Brent crude oil can be purchased for a given amount in Euros",
inputSchema: {
type: "object",
properties: {
amount: {
type: "number",
description: "Amount in Euros",
},
},
required: ["amount"],
},
},
];
// Обработчик списка инструментов
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools,
};
});
// Обработчик вызова инструментов
server.setRequestHandler(CallToolRequestSchema, async (request) => {
try {
const data = await fetchZenrusData();
switch (request.params.name) {
case "get_usd_rate": {
const result = {
rate: data.usd !== "N/A" ? parseFloat(data.usd) : null,
currency: "USD/RUB",
description: "US Dollar to Russian Ruble exchange rate",
};
return {
content: [
{
type: "text",
text: JSON.stringify(result, null, 2),
},
],
};
}
case "get_eur_rate": {
const result = {
rate: data.eur !== "N/A" ? parseFloat(data.eur) : null,
currency: "EUR/RUB",
description: "Euro to Russian Ruble exchange rate",
};
return {
content: [
{
type: "text",
text: JSON.stringify(result, null, 2),
},
],
};
}
case "get_brent_usd_rate": {
const result = {
price: data.brent !== "N/A" ? parseFloat(data.brent) : null,
commodity: "Brent Crude Oil",
currency: "USD",
unit: "per barrel",
};
return {
content: [
{
type: "text",
text: JSON.stringify(result, null, 2),
},
],
};
}
case "get_brent_rub_rate": {
const result = {
price: data.brentRub !== "N/A" ? parseFloat(data.brentRub) : null,
commodity: "Brent Crude Oil",
currency: "RUB",
unit: "per barrel",
};
return {
content: [
{
type: "text",
text: JSON.stringify(result, null, 2),
},
],
};
}
case "calculate_barrels_for_rub": {
const amount = (request.params.arguments as { amount: number }).amount;
const pricePerBarrel = data.brentRub !== "N/A" ? parseFloat(data.brentRub) : null;
if (pricePerBarrel === null || pricePerBarrel === 0) {
return {
content: [
{
type: "text",
text: JSON.stringify({
error: "Price data not available",
barrels: null,
}, null, 2),
},
],
isError: true,
};
}
const barrels = amount / pricePerBarrel;
const result = {
amount,
currency: "RUB",
barrels: parseFloat(barrels.toFixed(4)),
pricePerBarrel,
commodity: "Brent Crude Oil",
};
return {
content: [
{
type: "text",
text: JSON.stringify(result, null, 2),
},
],
};
}
case "calculate_barrels_for_usd": {
const amount = (request.params.arguments as { amount: number }).amount;
const pricePerBarrel = data.brent !== "N/A" ? parseFloat(data.brent) : null;
if (pricePerBarrel === null || pricePerBarrel === 0) {
return {
content: [
{
type: "text",
text: JSON.stringify({
error: "Price data not available",
barrels: null,
}, null, 2),
},
],
isError: true,
};
}
const barrels = amount / pricePerBarrel;
const result = {
amount,
currency: "USD",
barrels: parseFloat(barrels.toFixed(4)),
pricePerBarrel,
commodity: "Brent Crude Oil",
};
return {
content: [
{
type: "text",
text: JSON.stringify(result, null, 2),
},
],
};
}
case "calculate_barrels_for_eur": {
const amount = (request.params.arguments as { amount: number }).amount;
const eurRate = data.eur !== "N/A" ? parseFloat(data.eur) : null;
const usdRate = data.usd !== "N/A" ? parseFloat(data.usd) : null;
const pricePerBarrelUsd = data.brent !== "N/A" ? parseFloat(data.brent) : null;
if (eurRate === null || usdRate === null || pricePerBarrelUsd === null || usdRate === 0) {
return {
content: [
{
type: "text",
text: JSON.stringify({
error: "Price data not available",
barrels: null,
}, null, 2),
},
],
isError: true,
};
}
// Конвертируем EUR -> RUB -> USD -> Barrels
// EUR/RUB * amount = RUB, RUB / (USD/RUB) = USD, USD / (Brent USD) = Barrels
const amountInRub = amount * eurRate;
const amountInUsd = amountInRub / usdRate;
const barrels = amountInUsd / pricePerBarrelUsd;
const result = {
amount,
currency: "EUR",
barrels: parseFloat(barrels.toFixed(4)),
pricePerBarrel: parseFloat(((amountInRub / barrels)).toFixed(2)),
pricePerBarrelCurrency: "RUB",
commodity: "Brent Crude Oil",
};
return {
content: [
{
type: "text",
text: JSON.stringify(result, null, 2),
},
],
};
}
default:
throw new Error(`Unknown tool: ${request.params.name}`);
}
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
return {
content: [
{
type: "text",
text: JSON.stringify({
error: errorMessage,
success: false,
}, null, 2),
},
],
isError: true,
};
}
});
// Запускаем сервер
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Zenrus MCP Server запущен");
}
main().catch((error) => {
console.error("Ошибка запуска сервера:", error);
process.exit(1);
});