Skip to main content
Glama
campertunity

Campertunity MCP Server

Official
by campertunity

place-search

Find campgrounds and outdoor accommodations with specific amenities, availability dates, and location filters for camping trips.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
limitNoNumber of places to return. Default is 50, max is 1000.
startDateNoStart date for availability search. Format: YYYY-MM-DD
endDateNoEnd date for availability search. Format: YYYY-MM-DD
adultsNoNumber of adults. Default is 1.
childrenNoNumber of children. Default is 0.
latitudeNoLatitude to filter by.
longitudeNoLongitude to filter by.
radiusNoRadius to filter by (in km).
filtersNoFilter out places that have specific tags.
campgroundDescriptionNoDescribe the campground you are looking for. Note: not the location, but something about the campground like "has a pool" or "near a lake" or "has a playground"

Implementation Reference

  • The handler function that builds query parameters from inputs and fetches search results from the Campertunity API endpoint `/place/search`, returning JSON or error.
    async ({ limit, startDate, endDate, adults, children, latitude, longitude, radius, filters, campgroundDescription }) => { try { const params = new URLSearchParams(); if (limit) params.set('limit', limit.toString()); if (startDate) params.set('startDate', startDate); if (endDate) params.set('endDate', endDate); if (adults) params.set('adults', adults.toString()); if (children) params.set('children', children.toString()); if (latitude) params.set('latitude', latitude.toString()); if (longitude) params.set('longitude', longitude.toString()); if (radius) params.set('radius', radius.toString()); if (filters) params.set('filters', filters.join(',')); if (campgroundDescription) params.set('campgroundDescription', campgroundDescription); const places = await campertunityClient.get(`/place/search?${params.toString()}`); return { content: [{ type: 'text', text: JSON.stringify(places), mimeType: 'application/json' }], }; } catch (error) { return { content: [{ type: 'text', text: 'Error: ' + (error as Error).message }], isError: true, }; } }
  • Zod input schema defining parameters for the place search tool, including limits, dates, location filters, and tags.
    { limit: z.number().default(50).optional().describe('Number of places to return. Default is 50, max is 1000.'), startDate: z.string().optional().describe('Start date for availability search. Format: YYYY-MM-DD'), endDate: z.string().optional().describe('End date for availability search. Format: YYYY-MM-DD'), adults: z.number().optional().describe('Number of adults. Default is 1.'), children: z.number().optional().describe('Number of children. Default is 0.'), latitude: z.number().optional().describe('Latitude to filter by.'), longitude: z.number().optional().describe('Longitude to filter by.'), radius: z.number().optional().default(20).describe('Radius to filter by (in km).'), filters: z.array(z.enum(Object.values(Tag) as [string, ...string[]])).optional().describe('Filter out places that have specific tags.'), campgroundDescription: z.string().optional().describe('Describe the campground you are looking for. Note: not the location, but something about the campground like "has a pool" or "near a lake" or "has a playground"'), },
  • The server.tool call that registers the 'place-search' tool with its schema and handler function.
    server.tool( 'place-search', { limit: z.number().default(50).optional().describe('Number of places to return. Default is 50, max is 1000.'), startDate: z.string().optional().describe('Start date for availability search. Format: YYYY-MM-DD'), endDate: z.string().optional().describe('End date for availability search. Format: YYYY-MM-DD'), adults: z.number().optional().describe('Number of adults. Default is 1.'), children: z.number().optional().describe('Number of children. Default is 0.'), latitude: z.number().optional().describe('Latitude to filter by.'), longitude: z.number().optional().describe('Longitude to filter by.'), radius: z.number().optional().default(20).describe('Radius to filter by (in km).'), filters: z.array(z.enum(Object.values(Tag) as [string, ...string[]])).optional().describe('Filter out places that have specific tags.'), campgroundDescription: z.string().optional().describe('Describe the campground you are looking for. Note: not the location, but something about the campground like "has a pool" or "near a lake" or "has a playground"'), }, async ({ limit, startDate, endDate, adults, children, latitude, longitude, radius, filters, campgroundDescription }) => { try { const params = new URLSearchParams(); if (limit) params.set('limit', limit.toString()); if (startDate) params.set('startDate', startDate); if (endDate) params.set('endDate', endDate); if (adults) params.set('adults', adults.toString()); if (children) params.set('children', children.toString()); if (latitude) params.set('latitude', latitude.toString()); if (longitude) params.set('longitude', longitude.toString()); if (radius) params.set('radius', radius.toString()); if (filters) params.set('filters', filters.join(',')); if (campgroundDescription) params.set('campgroundDescription', campgroundDescription); const places = await campertunityClient.get(`/place/search?${params.toString()}`); return { content: [{ type: 'text', text: JSON.stringify(places), mimeType: 'application/json' }], }; } catch (error) { return { content: [{ type: 'text', text: 'Error: ' + (error as Error).message }], isError: true, }; } } );
  • src/index.ts:26-26 (registration)
    Invocation of placeSearchTool to register the tool on the MCP server.
    placeSearchTool(server, campertunityClient);
  • Enum defining all possible tags for filtering places, used in the schema for filters parameter.
    export enum Tag { // SiteType tent = 'tent', rv = 'rv', lodging = 'lodging', glamping = 'glamping', cabin = 'cabin', // AccessType driveIn = 'driveIn', walkIn = 'walkIn', equestrian = 'equestrian', boat = 'boat', // Activities biking = 'biking', boating = 'boating', fishing = 'fishing', hiking = 'hiking', horsebackRiding = 'horsebackRiding', paddling = 'paddling', windSports = 'windSports', surfing = 'surfing', swimming = 'swimming', whitewaterPaddling = 'whitewaterPaddling', wildlifeWatching = 'wildlifeWatching', // Amenities picnicTable = 'picnicTable', fires = 'fires', toilets = 'toilets', outhouse = 'outhouse', potableWater = 'potableWater', petFriendly = 'petFriendly', rvHookup = 'rvHookup', rvSanitation = 'rvSanitation', trash = 'trash', showers = 'showers', wifi = 'wifi', handicap = 'handicap', // Terrain beach = 'beach', cave = 'cave', desert = 'desert', forest = 'forest', hotSpring = 'hotSpring', lake = 'lake', river = 'river', swimmingHole = 'swimmingHole', waterfall = 'waterfall', creek = 'creek', }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/campertunity/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server