mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
feat: lead the MCP tool list with what the globe shows
MCP no longer lists place search, routing, plain weather and wind, the regional brief, the HUD caption, radio, bike share and transit. Assistants already cover these or they add little without the globe; voice keeps them, and tools that combine others still reach them.
This commit is contained in:
1 parent
d6473b6049
commit
af8856cedf
3 files changed
+43
-13
No files matched your search
@@ -4,7 +4,7 @@ import { PassThrough } from 'node:stream';
|
||||
import { createLocalMcpServer } from '../../server/mcp/server.js';
|
||||
import { createApiFetch } from '../../server/mcp/services.js';
|
||||
import { parseArgs, serveStdio } from '../../server/mcp/stdio.js';
|
||||
import { coreTools } from './index.js';
|
||||
import { coreTools, toolsForSurface } from './index.js';
|
||||
|
||||
const usgs = {
|
||||
type: 'FeatureCollection',
|
||||
@@ -70,7 +70,7 @@ test('the stdio server answers newline-delimited requests using only its data so
|
||||
// Every Core tool's services are composed locally.
|
||||
assert.deepEqual(
|
||||
byId.get(2).result.tools.map((tool) => tool.name),
|
||||
coreTools.map((tool) => tool.name),
|
||||
toolsForSurface(coreTools, 'mcp').map((tool) => tool.name),
|
||||
);
|
||||
assert.equal(
|
||||
byId.get(3).result.content[0].text,
|
||||
|
||||
+16
-2
@@ -2,6 +2,8 @@
|
||||
* Which surfaces offer each tool. A tool is on every surface unless this
|
||||
* table turns it off; edit an entry to turn a tool on or off for MCP, voice,
|
||||
* or both. Applications can pass overrides when they compose a surface.
|
||||
* Tools off a surface stay reachable from tools that combine others, such as
|
||||
* situation_brief using get_weather.
|
||||
*/
|
||||
|
||||
import { ToolError } from './catalog.js';
|
||||
@@ -9,6 +11,7 @@ import { ToolError } from './catalog.js';
|
||||
export const SURFACES = Object.freeze(['mcp', 'voice']);
|
||||
|
||||
const voiceOff = Object.freeze({ voice: false });
|
||||
const mcpOff = Object.freeze({ mcp: false });
|
||||
|
||||
export const TOOL_SURFACES = Object.freeze({
|
||||
// Voice runs inside the app, so a link to it adds nothing.
|
||||
@@ -19,8 +22,8 @@ export const TOOL_SURFACES = Object.freeze({
|
||||
get_weather_map: voiceOff,
|
||||
get_recent_imagery: voiceOff,
|
||||
get_cctv_snapshot: voiceOff,
|
||||
// Voice shows the HUD caption in the app itself.
|
||||
get_hud_caption: voiceOff,
|
||||
// The app shows its HUD caption itself, and assistants write their own.
|
||||
get_hud_caption: Object.freeze({ voice: false, mcp: false }),
|
||||
// Voice answers these from the loaded layers with analyst_query.
|
||||
aircraft_in_area: voiceOff,
|
||||
vessels_in_area: voiceOff,
|
||||
@@ -30,6 +33,17 @@ export const TOOL_SURFACES = Object.freeze({
|
||||
get_active_fires: voiceOff,
|
||||
find_infrastructure: voiceOff,
|
||||
satellites_overhead: voiceOff,
|
||||
// MCP leads with what the globe shows; assistants already search places,
|
||||
// plan routes and report weather, and these layers add little in a chat.
|
||||
search_places: mcpOff,
|
||||
places_nearby: mcpOff,
|
||||
plan_route: mcpOff,
|
||||
get_weather: mcpOff,
|
||||
get_wind: mcpOff,
|
||||
get_regional_brief: mcpOff,
|
||||
find_radio_stations: mcpOff,
|
||||
get_bike_share: mcpOff,
|
||||
get_transit_vehicles: mcpOff,
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,17 +11,32 @@ import {
|
||||
|
||||
const names = (tools) => tools.map((tool) => tool.name);
|
||||
|
||||
test('MCP offers every tool and voice leaves out the table entries', () => {
|
||||
assert.deepEqual(names(toolsForSurface(coreTools, 'mcp')), names(coreTools));
|
||||
test('each surface offers the tools the table does not turn off', () => {
|
||||
for (const surface of ['mcp', 'voice']) {
|
||||
const offered = names(toolsForSurface(coreTools, surface));
|
||||
const expected = names(coreTools).filter(
|
||||
(name) => TOOL_SURFACES[name]?.[surface] !== false,
|
||||
);
|
||||
assert.deepEqual(offered, expected, surface);
|
||||
}
|
||||
const mcp = names(toolsForSurface(coreTools, 'mcp'));
|
||||
for (const name of [
|
||||
'open_in_gods_eye_view',
|
||||
'situation_brief',
|
||||
'aircraft_in_area',
|
||||
])
|
||||
assert.ok(mcp.includes(name), name);
|
||||
for (const name of [
|
||||
'search_places',
|
||||
'plan_route',
|
||||
'get_weather',
|
||||
'get_hud_caption',
|
||||
])
|
||||
assert.ok(!mcp.includes(name), name);
|
||||
const voice = names(toolsForSurface(coreTools, 'voice'));
|
||||
assert.equal(
|
||||
voice.length,
|
||||
coreTools.length - Object.keys(TOOL_SURFACES).length,
|
||||
);
|
||||
for (const name of Object.keys(TOOL_SURFACES))
|
||||
assert.ok(!voice.includes(name), name);
|
||||
assert.ok(voice.includes('get_weather'));
|
||||
assert.ok(voice.includes('military_awareness'));
|
||||
assert.ok(!voice.includes('aircraft_in_area'));
|
||||
});
|
||||
|
||||
test('overrides turn a tool on or off for one surface', () => {
|
||||
@@ -44,7 +59,8 @@ test('every table entry names a core tool and a known surface', () => {
|
||||
const names = new Set(coreTools.map((tool) => tool.name));
|
||||
for (const [name, entry] of Object.entries(TOOL_SURFACES)) {
|
||||
assert.ok(names.has(name), name);
|
||||
assert.deepEqual(Object.keys(entry), ['voice']);
|
||||
for (const key of Object.keys(entry))
|
||||
assert.ok(['voice', 'mcp'].includes(key), `${name}: ${key}`);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user