mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
feat: add a submarine cable tool
Add find_submarine_cables over the bundled TeleGeography data: cables passing through or landing in an area, or matching a name, with landing points and the dataset's attribution. The local MCP server's fetch reads the bundled data files a browser would load by URL, and nothing outside that directory.
This commit is contained in:
1 parent
9be90fff44
commit
c1957d884e
9 files changed
+226
-7
No files matched your search
+33
-3
@@ -3,11 +3,20 @@
|
||||
* running God's Eye View server's `/api` routes.
|
||||
*/
|
||||
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { createToolServices } from '../../src/tools/services.js';
|
||||
|
||||
// Bundled data some sources read by module-relative URL.
|
||||
const BUNDLED_DATA = new URL('../../src/data/local_data/', import.meta.url);
|
||||
|
||||
export const DEFAULT_API_BASE = 'http://localhost:4173';
|
||||
|
||||
/** Resolve the sources' relative `/api/...` requests against `apiBase`. */
|
||||
/**
|
||||
* Resolve the sources' relative `/api/...` requests against `apiBase`, and
|
||||
* serve `file:` URLs inside the bundled data directory from disk, as a
|
||||
* browser would load those module-relative assets.
|
||||
*/
|
||||
export function createApiFetch({
|
||||
apiBase = DEFAULT_API_BASE,
|
||||
fetchImpl = (...args) => globalThis.fetch(...args),
|
||||
@@ -15,13 +24,34 @@ export function createApiFetch({
|
||||
const base = new URL(apiBase);
|
||||
if (!['http:', 'https:'].includes(base.protocol))
|
||||
throw new TypeError(`apiBase must be an http(s) URL: ${apiBase}`);
|
||||
return (input, init) =>
|
||||
fetchImpl(
|
||||
return (input, init) => {
|
||||
const url = String(input instanceof Request ? input.url : input);
|
||||
if (url.startsWith('file:')) return readBundled(url);
|
||||
return fetchImpl(
|
||||
typeof input === 'string' && input.startsWith('/')
|
||||
? new URL(input, base)
|
||||
: input,
|
||||
init,
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
async function readBundled(url) {
|
||||
const href = new URL(url).href;
|
||||
if (!href.startsWith(BUNDLED_DATA.href) || href.includes('/../'))
|
||||
return new Response(null, { status: 404 });
|
||||
try {
|
||||
const body = await readFile(fileURLToPath(href));
|
||||
return new Response(body, {
|
||||
headers: {
|
||||
'Content-Type': href.endsWith('.json')
|
||||
? 'application/json'
|
||||
: 'application/octet-stream',
|
||||
},
|
||||
});
|
||||
} catch {
|
||||
return new Response(null, { status: 404 });
|
||||
}
|
||||
}
|
||||
|
||||
/** Construct every service Core's tools read, backed by the local server. */
|
||||
|
||||
Reference in new issue
Block a user