-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathGetReferenceTool.ts
More file actions
103 lines (94 loc) · 3.09 KB
/
GetReferenceTool.ts
File metadata and controls
103 lines (94 loc) · 3.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Copyright (c) Mapbox, Inc.
// Licensed under the MIT License.
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
import { BaseTool } from '../BaseTool.js';
import {
GetReferenceSchema,
GetReferenceInput
} from './GetReferenceTool.input.schema.js';
import { getAllResources } from '../../resources/resourceRegistry.js';
/**
* Tool to access Mapbox reference documentation and schemas
* This tool provides access to static reference data that helps understand
* Mapbox concepts, field definitions, token scopes, and layer type mappings.
*/
export class GetReferenceTool extends BaseTool<typeof GetReferenceSchema> {
readonly name = 'get_reference_tool';
readonly description =
'Get Mapbox reference documentation including Streets v8 field definitions, token scopes, layer type mappings, and style specifications. Use this tool to understand what fields, scopes, or layer types are available before creating styles or tokens.';
readonly annotations = {
readOnlyHint: true,
destructiveHint: false,
idempotentHint: true,
openWorldHint: false,
title: 'Get Mapbox Reference Documentation'
};
constructor() {
super({ inputSchema: GetReferenceSchema });
}
protected async execute(input: GetReferenceInput): Promise<CallToolResult> {
const resources = getAllResources();
const resource = resources.find((r) => r.uri === input.reference);
if (!resource) {
return {
content: [
{
type: 'text',
text: `Reference not found: ${input.reference}\n\nAvailable references:\n${resources.map((r) => `- ${r.uri}: ${r.description}`).join('\n')}`
}
],
isError: true
};
}
try {
// Call the resource's readCallback to get the content
const uri = new URL(resource.uri);
// Pass empty object for extra parameter (not used by resources)
const result = await resource.readCallback(uri, {} as any);
// Return the first content item (resources can return multiple but we typically have one)
if (result.contents.length === 0) {
return {
content: [
{
type: 'text',
text: `No content available for reference: ${input.reference}`
}
],
isError: true
};
}
const content = result.contents[0];
// Type guard: check if content has 'text' property (vs 'blob' for binary resources)
if (!('text' in content)) {
return {
content: [
{
type: 'text',
text: `Reference ${input.reference} returned binary content, expected text`
}
],
isError: true
};
}
return {
content: [
{
type: 'text',
text: content.text
}
],
isError: false
};
} catch (error) {
return {
content: [
{
type: 'text',
text: `Error reading reference: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
}
}