syia-mcp-vessel-accounts
Version:
MCP server for vessel account management including EyeShare API integration, vessel expenses, and purchase orders
366 lines • 13.9 kB
JavaScript
import { MongoDBManager } from '../utils/mongodb.js';
import { logger } from '../utils/logger.js';
// Vessel Expenses Tool (ShipNet - budget_expenses_raw_data)
export const vesselExpensesTool = {
name: 'vessel_expenses',
description: 'Get vessel expenses data from ShipNet system (budget_expenses_raw_data collection) with category lookup and vessel code filtering.',
inputSchema: {
type: "object",
properties: {
vesselCode: {
type: "string",
description: "Vessel code to filter vessel expenses (optional)"
},
limit: {
type: "number",
description: "Maximum number of documents to return",
maximum: 10000
},
timeout: {
type: "number",
description: "Query timeout in milliseconds (max 5 minutes)",
maximum: 300000
}
},
additionalProperties: false
},
async execute(args) {
try {
const { vesselCode, limit, timeout } = args;
logger.info(`Getting ShipNet vessel expenses data${vesselCode ? ` for vessel: ${vesselCode}` : ''}`);
// Get MongoDB configuration from environment variables
const mongodbUri = process.env.MONGODB_URI;
const mongodbDatabase = process.env.MONGODB_DATABASE;
if (!mongodbUri || !mongodbDatabase) {
return {
content: [
{
type: 'text',
text: 'MongoDB configuration not found in environment variables. Please set MONGODB_URI and MONGODB_DATABASE.',
},
],
};
}
const mongodbConfig = {
uri: mongodbUri,
database: mongodbDatabase
};
const mongoManager = new MongoDBManager(mongodbConfig);
// Set timeout if provided
if (timeout) {
setTimeout(() => {
mongoManager.disconnect();
}, timeout);
}
// Build pipeline with vessel code filter if provided
const pipeline = [];
// Add vessel code filter if provided
if (vesselCode) {
pipeline.push({
'$match': {
'vesselCode': vesselCode
}
});
}
// Add the category lookup pipeline (ShipNet specific)
pipeline.push({
'$lookup': {
'from': 'budget_category_raw_data',
'localField': 'accountNo',
'foreignField': 'accountCode',
'as': 'category_data'
}
}, {
'$unwind': {
'path': '$category_data',
'preserveNullAndEmptyArrays': true
}
}, {
'$addFields': {
'category': {
'$ifNull': [
'$category_data.category', null
]
}
}
}, {
'$project': {
'category_data': 0
}
});
// Add limit stage if provided
if (limit) {
pipeline.push({ '$limit': limit });
}
const result = await mongoManager.executeAggregation('budget_expenses_raw_data', pipeline);
await mongoManager.disconnect();
if (result.success) {
return {
content: [
{
type: 'text',
text: `ShipNet vessel expenses data retrieved successfully!\n\nExecution Time: ${result.executionTime}ms\nDocuments Returned: ${result.count}\n\nResults:\n${JSON.stringify(result.data, null, 2)}`,
},
],
};
}
else {
return {
content: [
{
type: 'text',
text: `Failed to get ShipNet vessel expenses data: ${result.error}`,
},
],
};
}
}
catch (error) {
logger.error(`Get ShipNet vessel expenses tool error: ${error}`);
return {
content: [
{
type: 'text',
text: `Error getting ShipNet vessel expenses data: ${error instanceof Error ? error.message : String(error)}`,
},
],
};
}
},
};
// Vessel Expenses Previous Year Tool (ShipNet - budget_expenses_previous_year_raw_data)
export const vesselExpensesPreviousYearTool = {
name: 'vessel_expenses_previous_year',
description: 'Get vessel expenses data from the previous year (budget_expenses_previous_year_raw_data collection) with category lookup and vessel code filtering.',
inputSchema: {
type: "object",
properties: {
vesselCode: {
type: "string",
description: "Vessel code to filter vessel expenses (optional)"
},
limit: {
type: "number",
description: "Maximum number of documents to return",
maximum: 10000
},
timeout: {
type: "number",
description: "Query timeout in milliseconds (max 5 minutes)",
maximum: 300000
}
},
additionalProperties: false
},
async execute(args) {
try {
const { vesselCode, limit, timeout } = args;
logger.info(`Getting previous year vessel expenses data${vesselCode ? ` for vessel: ${vesselCode}` : ''}`);
// Get MongoDB configuration from environment variables
const mongodbUri = process.env.MONGODB_URI;
const mongodbDatabase = process.env.MONGODB_DATABASE;
if (!mongodbUri || !mongodbDatabase) {
return {
content: [
{
type: 'text',
text: 'MongoDB configuration not found in environment variables. Please set MONGODB_URI and MONGODB_DATABASE.',
},
],
};
}
const mongodbConfig = {
uri: mongodbUri,
database: mongodbDatabase
};
const mongoManager = new MongoDBManager(mongodbConfig);
// Set timeout if provided
if (timeout) {
setTimeout(() => {
mongoManager.disconnect();
}, timeout);
}
// Build pipeline with vessel code filter if provided
const pipeline = [];
// Add vessel code filter if provided
if (vesselCode) {
pipeline.push({
'$match': {
'vesselCode': vesselCode
}
});
}
// Add the category lookup pipeline (ShipNet specific)
pipeline.push({
'$lookup': {
'from': 'budget_category_raw_data',
'localField': 'accountNo',
'foreignField': 'accountCode',
'as': 'category_data'
}
}, {
'$unwind': {
'path': '$category_data',
'preserveNullAndEmptyArrays': true
}
}, {
'$addFields': {
'category': {
'$ifNull': [
'$category_data.category', null
]
}
}
}, {
'$project': {
'category_data': 0
}
});
// Add limit stage if provided
if (limit) {
pipeline.push({ '$limit': limit });
}
const result = await mongoManager.executeAggregation('budget_expenses_previous_year_raw_data', pipeline);
await mongoManager.disconnect();
if (result.success) {
return {
content: [
{
type: 'text',
text: `Previous year vessel expenses data retrieved successfully!\n\nExecution Time: ${result.executionTime}ms\nDocuments Returned: ${result.count}\n\nResults:\n${JSON.stringify(result.data, null, 2)}`,
},
],
};
}
else {
return {
content: [
{
type: 'text',
text: `Failed to get previous year vessel expenses data: ${result.error}`,
},
],
};
}
}
catch (error) {
logger.error(`Get previous year vessel expenses tool error: ${error}`);
return {
content: [
{
type: 'text',
text: `Error getting previous year vessel expenses data: ${error instanceof Error ? error.message : String(error)}`,
},
],
};
}
},
};
// Purchase Order Tool (ShipPalm V2/V3 - purchase_order)
export const purchaseOrderTool = {
name: 'purchase_orders',
description: 'Get purchase order data from ShipPalm V2 and V3 systems (purchase_order collection) with vessel code filtering.',
inputSchema: {
type: "object",
properties: {
vesselCode: {
type: "string",
description: "Vessel code to filter purchase orders (optional)"
},
limit: {
type: "number",
description: "Maximum number of documents to return",
maximum: 10000
},
timeout: {
type: "number",
description: "Query timeout in milliseconds (max 5 minutes)",
maximum: 300000
}
},
additionalProperties: false
},
async execute(args) {
try {
const { vesselCode, limit, timeout } = args;
logger.info(`Getting ShipPalm purchase order data${vesselCode ? ` for vessel: ${vesselCode}` : ''}`);
// Get MongoDB configuration from environment variables
const mongodbUri = process.env.MONGODB_URI;
const mongodbDatabase = process.env.MONGODB_DATABASE;
if (!mongodbUri || !mongodbDatabase) {
return {
content: [
{
type: 'text',
text: 'MongoDB configuration not found in environment variables. Please set MONGODB_URI and MONGODB_DATABASE.',
},
],
};
}
const mongodbConfig = {
uri: mongodbUri,
database: mongodbDatabase
};
const mongoManager = new MongoDBManager(mongodbConfig);
// Set timeout if provided
if (timeout) {
setTimeout(() => {
mongoManager.disconnect();
}, timeout);
}
// Build pipeline with vessel code filter if provided
const pipeline = [];
// Add vessel code filter if provided
if (vesselCode) {
pipeline.push({
'$match': {
'vesselCode': vesselCode
}
});
}
// Add limit stage if provided
if (limit) {
pipeline.push({ '$limit': limit });
}
const result = await mongoManager.executeAggregation('purchase_order', pipeline);
await mongoManager.disconnect();
if (result.success) {
return {
content: [
{
type: 'text',
text: `ShipPalm purchase order data retrieved successfully!\n\nExecution Time: ${result.executionTime}ms\nDocuments Returned: ${result.count}\n\nResults:\n${JSON.stringify(result.data, null, 2)}`,
},
],
};
}
else {
return {
content: [
{
type: 'text',
text: `Failed to get ShipPalm purchase order data: ${result.error}`,
},
],
};
}
}
catch (error) {
logger.error(`Get ShipPalm purchase order tool error: ${error}`);
return {
content: [
{
type: 'text',
text: `Error getting ShipPalm purchase order data: ${error instanceof Error ? error.message : String(error)}`,
},
],
};
}
},
};
export const mongodbTools = [
vesselExpensesTool,
vesselExpensesPreviousYearTool,
purchaseOrderTool,
];
//# sourceMappingURL=mongodb.js.map