Skip to main content
Glama
navigation.ts4.04 kB
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { navigateSchema, reloadSchema, goBackSchema, goForwardSchema } from '../schemas.js'; import { getPageForOperation } from '../tabs.js'; import { getDefaultTimeout } from '../browser.js'; import { handleResult, ok, err, navigationTimeout, navigationFailed, normalizeError, } from '../errors.js'; import type { WaitUntilOption } from '../types.js'; /** * Register navigation tools */ export function registerNavigationTools(server: McpServer): void { // Navigate to URL server.tool( 'navigate', 'Navigate to a URL in the browser', navigateSchema.shape, async ({ url, waitUntil, timeout, tabId }) => { const pageResult = await getPageForOperation(tabId); if (!pageResult.success) { return handleResult(pageResult); } const page = pageResult.data; const timeoutMs = timeout ?? getDefaultTimeout(); try { const response = await page.goto(url, { waitUntil: (waitUntil ?? 'load') as WaitUntilOption, timeout: timeoutMs, }); if (!response) { return handleResult(err(navigationFailed(url, 'No response received'))); } const status = response.status(); if (status >= 400) { return handleResult(err(navigationFailed(url, `HTTP ${status}`))); } return handleResult(ok({ url: page.url(), title: await page.title(), status, })); } catch (error) { if (error instanceof Error && error.message.includes('timeout')) { return handleResult(err(navigationTimeout(url, timeoutMs))); } return handleResult(err(normalizeError(error))); } } ); // Reload page server.tool( 'reload', 'Reload the current page', reloadSchema.shape, async ({ waitUntil, timeout, tabId }) => { const pageResult = await getPageForOperation(tabId); if (!pageResult.success) { return handleResult(pageResult); } const page = pageResult.data; try { await page.reload({ waitUntil: (waitUntil ?? 'load') as WaitUntilOption, timeout: timeout ?? getDefaultTimeout(), }); return handleResult(ok({ url: page.url(), title: await page.title(), })); } catch (error) { return handleResult(err(normalizeError(error))); } } ); // Go back server.tool( 'go_back', 'Navigate back in browser history', goBackSchema.shape, async ({ waitUntil, timeout, tabId }) => { const pageResult = await getPageForOperation(tabId); if (!pageResult.success) { return handleResult(pageResult); } const page = pageResult.data; try { const response = await page.goBack({ waitUntil: (waitUntil ?? 'load') as WaitUntilOption, timeout: timeout ?? getDefaultTimeout(), }); return handleResult(ok({ url: page.url(), title: await page.title(), navigated: response !== null, })); } catch (error) { return handleResult(err(normalizeError(error))); } } ); // Go forward server.tool( 'go_forward', 'Navigate forward in browser history', goForwardSchema.shape, async ({ waitUntil, timeout, tabId }) => { const pageResult = await getPageForOperation(tabId); if (!pageResult.success) { return handleResult(pageResult); } const page = pageResult.data; try { const response = await page.goForward({ waitUntil: (waitUntil ?? 'load') as WaitUntilOption, timeout: timeout ?? getDefaultTimeout(), }); return handleResult(ok({ url: page.url(), title: await page.title(), navigated: response !== null, })); } catch (error) { return handleResult(err(normalizeError(error))); } } ); }

Implementation Reference

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/andytango/puppeteer-mcp'

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