augmenttoolkit / server /src /mcp /tools /mapsWeather.ts
Leon4gr45's picture
Upload folder using huggingface_hub (part 5)
57a889c verified
Raw
History Blame Contribute Delete
5.36 kB
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp';
import { z } from 'zod';
import { findByIata, searchAirports } from '../../services/airportService';
import { searchPlaces, getPlaceDetails, reverseGeocode, resolveGoogleMapsUrl } from '../../services/mapsService';
import { getWeather, getDetailedWeather } from '../../services/weatherService';
import {
TOOL_ANNOTATIONS_READONLY,
ok,
} from './_shared';
import { canRead } from '../scopes';
export function registerMapsWeatherTools(server: McpServer, userId: number, scopes: string[] | null): void {
const canGeo = canRead(scopes, 'geo');
const canWeather = canRead(scopes, 'weather');
// --- MAPS EXTRAS ---
if (canGeo) server.registerTool(
'get_place_details',
{
description: 'Fetch detailed information about a place by its Google Place ID.',
inputSchema: {
placeId: z.string().describe('Google Place ID'),
lang: z.string().optional().default('en'),
},
annotations: TOOL_ANNOTATIONS_READONLY,
},
async ({ placeId, lang }) => {
const details = await getPlaceDetails(userId, placeId, lang ?? 'en');
if (!details) return { content: [{ type: 'text' as const, text: 'Place not found or maps service not configured.' }], isError: true };
return ok({ details });
}
);
if (canGeo) server.registerTool(
'reverse_geocode',
{
description: 'Get a human-readable address for given coordinates.',
inputSchema: {
lat: z.number(),
lng: z.number(),
lang: z.string().optional().default('en'),
},
annotations: TOOL_ANNOTATIONS_READONLY,
},
async ({ lat, lng, lang }) => {
const result = await reverseGeocode(String(lat), String(lng), lang ?? 'en');
if (!result) return { content: [{ type: 'text' as const, text: 'Reverse geocode failed or maps service not configured.' }], isError: true };
return ok(result);
}
);
if (canGeo) server.registerTool(
'resolve_maps_url',
{
description: 'Resolve a Google Maps share URL to coordinates and place name.',
inputSchema: {
url: z.string().describe('Google Maps share URL'),
},
annotations: TOOL_ANNOTATIONS_READONLY,
},
async ({ url }) => {
const result = await resolveGoogleMapsUrl(url);
if (!result) return { content: [{ type: 'text' as const, text: 'Could not resolve URL or maps service not configured.' }], isError: true };
return ok(result);
}
);
// --- WEATHER ---
if (canWeather) server.registerTool(
'get_weather',
{
description: 'Get weather forecast for a location and date.',
inputSchema: {
lat: z.number(),
lng: z.number(),
date: z.string().describe('ISO date YYYY-MM-DD'),
lang: z.string().optional().default('en'),
},
annotations: TOOL_ANNOTATIONS_READONLY,
},
async ({ lat, lng, date, lang }) => {
try {
const weather = await getWeather(String(lat), String(lng), date, lang ?? 'en');
return ok({ weather });
} catch (err: any) {
return { content: [{ type: 'text' as const, text: err?.message ?? 'Weather service not available.' }], isError: true };
}
}
);
if (canWeather) server.registerTool(
'get_detailed_weather',
{
description: 'Get hourly/detailed weather forecast for a location and date.',
inputSchema: {
lat: z.number(),
lng: z.number(),
date: z.string().describe('ISO date YYYY-MM-DD'),
lang: z.string().optional().default('en'),
},
annotations: TOOL_ANNOTATIONS_READONLY,
},
async ({ lat, lng, date, lang }) => {
try {
const weather = await getDetailedWeather(String(lat), String(lng), date, lang ?? 'en');
return ok({ weather });
} catch (err: any) {
return { content: [{ type: 'text' as const, text: err?.message ?? 'Weather service not available.' }], isError: true };
}
}
);
// --- AIRPORTS ---
if (canGeo) server.registerTool(
'search_airports',
{
description: 'Search for airports by name, city, or IATA code. Returns matching airports with IATA code, name, city, country, coordinates, and timezone. Use before create_transport (flight) to get the correct IATA code and timezone for endpoints.',
inputSchema: {
query: z.string().min(1).max(200).describe('Airport name, city, or IATA code (e.g. "zurich", "ZRH", "charles de gaulle")'),
limit: z.number().int().min(1).max(50).optional().default(10),
},
annotations: TOOL_ANNOTATIONS_READONLY,
},
async ({ query, limit }) => {
const airports = searchAirports(query, limit ?? 10);
return ok({ airports });
}
);
if (canGeo) server.registerTool(
'get_airport',
{
description: 'Get a single airport by its IATA code. Returns name, city, country, coordinates, and timezone.',
inputSchema: {
iata: z.string().length(3).toUpperCase().describe('IATA airport code (e.g. "ZRH", "AMS", "CDG")'),
},
annotations: TOOL_ANNOTATIONS_READONLY,
},
async ({ iata }) => {
const airport = findByIata(iata);
if (!airport) return { content: [{ type: 'text' as const, text: 'Airport not found.' }], isError: true };
return ok({ airport });
}
);
}