generate_pin_map
Create visual point maps to display location distributions of points of interest (POIs) like attractions, hospitals, and supermarkets using keywords and customizable settings like map size and marker styles.
Instructions
Generate a point map to display the location and distribution of point data on the map, such as the location distribution of attractions, hospitals, supermarkets, etc.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| data | Yes | A list of keywords for the names of points of interest (POIs) in Chinese. These POIs usually contain a group of places with similar locations, so the names should be more descriptive, must adding attributives to indicate that they are different places in the same area, such as "北京市" is better than "北京", "杭州西湖" is better than "西湖"; in addition, if you can determine that a location may appear in multiple areas, you can be more specific, such as "杭州西湖的苏堤春晓" is better than "苏堤春晓". The tool will use these keywords to search for specific POIs and query their detailed data, such as latitude and longitude, location photos, etc. For example, ["西安钟楼", "西安大唐不夜城", "西安大雁塔"]. | |
| height | No | Set the height of map, default is 1000. | |
| markerPopup | No | Marker type, one is simple mode, which is just an icon and does not require `markerPopup` configuration; the other is image mode, which displays location photos and requires `markerPopup` configuration. Among them, `width`/`height`/`borderRadius` can be combined to realize rectangular photos and square photos. In addition, when `borderRadius` is half of the width and height, it can also be a circular photo. | |
| title | Yes | The map title should not exceed 16 characters. The content should be consistent with the information the map wants to convey and should be accurate, rich, creative, and attractive. | |
| width | No | Set the width of map, default is 1600. |
Implementation Reference
- src/charts/pin-map.ts:1-42 (schema)Defines the Zod input schema and tool metadata (name, description, inputSchema) for the 'generate_pin_map' tool, exported as pinMap for use in Charts.import { z } from "zod"; import { zodToJsonSchema } from "../utils"; import { MapHeightSchema, MapTitleSchema, MapWidthSchema, POIsSchema, } from "./base"; const schema = { title: MapTitleSchema, data: POIsSchema, markerPopup: z .object({ type: z.string().default("image").describe('Must be "image".'), width: z.number().default(40).describe("Width of the photo."), height: z.number().default(40).describe("Height of the photo."), borderRadius: z .number() .default(8) .describe("Border radius of the photo."), }) .optional() .describe( "Marker type, one is simple mode, which is just an icon and does not require `markerPopup` configuration; the other is image mode, which displays location photos and requires `markerPopup` configuration. Among them, `width`/`height`/`borderRadius` can be combined to realize rectangular photos and square photos. In addition, when `borderRadius` is half of the width and height, it can also be a circular photo.", ), width: MapWidthSchema, height: MapHeightSchema, }; // https://modelcontextprotocol.io/specification/2025-03-26/server/tools#listing-tools const tool = { name: "generate_pin_map", description: "Generate a point map to display the location and distribution of point data on the map, such as the location distribution of attractions, hospitals, supermarkets, etc.", inputSchema: zodToJsonSchema(schema), }; export const pinMap = { schema, tool, };
- src/server.ts:64-77 (registration)Registers the MCP tool handlers: listTools returns all enabled chart.tools including generate_pin_map; callTool handler invokes utils/callTool for execution.function setupToolHandlers(server: Server): void { logger.info("setting up tool handlers..."); server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: getEnabledTools().map((chart) => chart.tool), })); // biome-ignore lint/suspicious/noExplicitAny: <explanation> server.setRequestHandler(CallToolRequestSchema, async (request: any) => { logger.info("calling tool", request.params.name, request.params.arguments); return await callTool(request.params.name, request.params.arguments); }); logger.info("tool handlers set up"); }
- src/utils/callTool.ts:43-110 (handler)The dispatched handler for all chart tools: maps 'generate_pin_map' to 'pin-map', validates input, detects as map chart and calls generateMap(tool, args) to execute.export async function callTool(tool: string, args: object = {}) { logger.info(`Calling tool: ${tool}`); const chartType = CHART_TYPE_MAP[tool as keyof typeof CHART_TYPE_MAP]; if (!chartType) { logger.error(`Unknown tool: ${tool}`); throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${tool}.`); } try { // Validate input using Zod before sending to API. // Select the appropriate schema based on the chart type. const schema = Charts[chartType].schema; if (schema) { // Use safeParse instead of parse and try-catch. const result = z.object(schema).safeParse(args); if (!result.success) { logger.error(`Invalid parameters: ${result.error.message}`); throw new McpError( ErrorCode.InvalidParams, `Invalid parameters: ${result.error.message}`, ); } } const isMapChartTool = [ "generate_district_map", "generate_path_map", "generate_pin_map", ].includes(tool); if (isMapChartTool) { // For map charts, we use the generateMap function, and return the mcp result. const { metadata, ...result } = await generateMap(tool, args); return result; } const url = await generateChartUrl(chartType, args); logger.info(`Generated chart URL: ${url}`); return { content: [ { type: "text", text: url, }, ], _meta: { description: "This is the chart's spec and configuration, which can be renderred to corresponding chart by AntV GPT-Vis chart components.", spec: { type: chartType, ...args }, }, }; // biome-ignore lint/suspicious/noExplicitAny: <explanation> } catch (error: any) { logger.error( `Failed to generate chart: ${error.message || "Unknown error"}.`, ); if (error instanceof McpError) throw error; if (error instanceof ValidateError) throw new McpError(ErrorCode.InvalidParams, error.message); throw new McpError( ErrorCode.InternalError, `Failed to generate chart: ${error?.message || "Unknown error."}`, ); } }
- src/utils/callTool.ts:9-35 (helper)Maps tool name 'generate_pin_map' to internal chart type 'pin-map' for Charts lookup and generation.const CHART_TYPE_MAP = { generate_area_chart: "area", generate_bar_chart: "bar", generate_boxplot_chart: "boxplot", generate_column_chart: "column", generate_district_map: "district-map", generate_dual_axes_chart: "dual-axes", generate_fishbone_diagram: "fishbone-diagram", generate_flow_diagram: "flow-diagram", generate_funnel_chart: "funnel", generate_histogram_chart: "histogram", generate_line_chart: "line", generate_liquid_chart: "liquid", generate_mind_map: "mind-map", generate_network_graph: "network-graph", generate_organization_chart: "organization-chart", generate_path_map: "path-map", generate_pie_chart: "pie", generate_pin_map: "pin-map", generate_radar_chart: "radar", generate_sankey_chart: "sankey", generate_scatter_chart: "scatter", generate_treemap_chart: "treemap", generate_venn_chart: "venn", generate_violin_chart: "violin", generate_word_cloud_chart: "word-cloud", } as const;
- src/utils/generate.ts:56-82 (handler)Executes the map tool by sending HTTP POST to visualization service with tool='generate_pin_map' and input args, returns the result.export async function generateMap( tool: string, input: unknown, ): Promise<ResponseResult> { const url = getVisRequestServer(); const response = await axios.post( url, { serviceId: getServiceIdentifier(), tool, input, source: "mcp-server-chart", }, { headers: { "Content-Type": "application/json", }, }, ); const { success, errorMessage, resultObj } = response.data; if (!success) { throw new Error(errorMessage); } return resultObj; }