/**
* LiteFarm MCP Server - Location Management Tools
*/
import { z } from "zod";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import type { LiteFarmClient } from "../litefarm-client.js";
import { ResponseFormat, type LiteFarmLocation } from "../types.js";
import { createToolResponse, createErrorResponse, formatListResponse } from "../tool-utils.js";
export function registerLocationTools(server: McpServer, client: LiteFarmClient): void {
// List locations
server.registerTool(
"litefarm_list_locations",
{
title: "List Farm Locations",
description: `List all locations (fields, greenhouses, gardens, etc.) for a specific farm.
Args:
- farm_id (string): Farm ID to get locations for
- response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: Array of location objects with details (name, type, area, etc.)`,
inputSchema: z.object({
farm_id: z.string().describe("Farm ID"),
response_format: z.nativeEnum(ResponseFormat).default(ResponseFormat.MARKDOWN)
}).strict(),
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }
},
async (params) => {
try {
const locations = await client.getLocations({ farm_id: params.farm_id });
if (!locations || locations.length === 0) {
return createToolResponse("No locations found on this farm.");
}
const formatter = (loc: LiteFarmLocation) => {
const type = loc.figure?.type || 'unknown';
const areaValue = loc.figure?.area as any;
const area = areaValue && typeof areaValue === 'number' ? ` (${areaValue.toFixed(2)} ha)` : '';
return `**${loc.name}** (${type})${area}\n- ID: ${loc.location_id}`;
};
const response = formatListResponse(locations, formatter, params.response_format);
return createToolResponse(response.text, response.structuredContent);
} catch (error) {
return createErrorResponse(error);
}
}
);
// Get specific location
server.registerTool(
"litefarm_get_location",
{
title: "Get Location Details",
description: `Get detailed information about a specific location.
Args:
- location_id (string): Location ID
- response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: Location object with full details`,
inputSchema: z.object({
location_id: z.string().describe("Location ID"),
response_format: z.nativeEnum(ResponseFormat).default(ResponseFormat.MARKDOWN)
}).strict(),
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }
},
async (params) => {
try {
const location = await client.getLocation(params.location_id);
if (params.response_format === ResponseFormat.JSON) {
return createToolResponse("Location details", location);
}
const type = location.figure?.type || 'unknown';
const areaValue = location.figure?.area as any;
const area = areaValue && typeof areaValue === 'number' ? `${areaValue.toFixed(2)} ha` : 'N/A';
const text = `**${location.name}**\n- Type: ${type}\n- Area: ${area}\n- ID: ${location.location_id}`;
return createToolResponse(text, location);
} catch (error) {
return createErrorResponse(error);
}
}
);
}