Skip to content

Commit a844c8f

Browse files
committed
navigate forward, navigate backward
1 parent ac43a8b commit a844c8f

File tree

3 files changed

+116
-55
lines changed

3 files changed

+116
-55
lines changed

browserbase/src/index.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,9 @@ Object.entries(requiredEnvVars).forEach(([name, value]) => {
3838

3939
// const serverVersion = "0.5.1";
4040

41-
export async function createServer(config: Config): Promise<Server> {
42-
// Assume true for captureSnapshot for keyboard, adjust if needed
43-
const captureSnapshotFlag = true;
44-
45-
// Create the server
46-
const server = new Server(
41+
export async function createServer(config: Config): Promise<Server> {
42+
// Create the server
43+
const server = new Server(
4744
{ name: "mcp-server-browserbase", version: "0.5.1" },
4845
{
4946
capabilities: {
@@ -61,7 +58,7 @@ export async function createServer(config: Config): Promise<Server> {
6158
const tools: Tool<any>[] = [
6259
...common,
6360
...snapshot,
64-
...keyboard(captureSnapshotFlag), // Call the function and spread the result array
61+
...keyboard, // Call the function and spread the result array
6562
// getText, // Include the tool object directly
6663
// navigate, // Include the tool object directly
6764
// session, // Include the tool object directly

browserbase/src/tools/keyboard.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ const pressKey: ToolFactory = captureSnapshot => defineTool({
104104
},
105105
});
106106

107-
// Changed export to match the factory pattern
108-
export default (captureSnapshot: boolean) => [
109-
pressKey(captureSnapshot),
107+
const captureSnapshotValue = true;
108+
109+
export default [
110+
pressKey(captureSnapshotValue),
110111
];

browserbase/src/tools/navigate.ts

Lines changed: 108 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,122 @@
1+
/**
2+
* Copyright (c) Microsoft Corporation.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
117
import { z } from 'zod';
2-
import { Page, errors as PlaywrightErrors } from "playwright-core";
3-
import type { Tool, ToolSchema, ToolContext, ToolResult } from "./tool.js";
4-
import { createErrorResult, createSuccessResult } from "./toolUtils.js";
5-
import type { Context } from '../context.js';
18+
import { defineTool, type ToolFactory } from './tool.js';
619
import type { ToolActionResult } from '../context.js';
7-
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
820

9-
// Define Zod schema
10-
const NavigateInputSchema = z.object({
11-
url: z.string().url().describe("URL to navigate to"),
12-
sessionId: z.string().optional(),
13-
});
14-
type NavigateInput = z.infer<typeof NavigateInputSchema>;
21+
const navigate: ToolFactory = captureSnapshot => defineTool({
22+
capability: 'core',
1523

16-
const navigateSchema: ToolSchema<typeof NavigateInputSchema> = {
17-
name: "browserbase_navigate",
18-
description: "Navigate the current page to a new URL",
19-
inputSchema: NavigateInputSchema,
20-
};
24+
schema: {
25+
name: 'browser_navigate',
26+
description: 'Navigate to a URL',
27+
inputSchema: z.object({
28+
url: z.string().describe('The URL to navigate to'),
29+
}),
30+
},
2131

22-
// Handle function for Navigate
23-
async function handleNavigate(context: Context, params: NavigateInput): Promise<ToolResult> {
32+
handle: async (context, params) => {
33+
const page = await context.getActivePage();
34+
if (!page) {
35+
throw new Error('No active page found for navigate');
36+
}
2437
const action = async (): Promise<ToolActionResult> => {
25-
const page = await context.getActivePage();
26-
if (!page) {
27-
throw new Error('No active page found for navigate');
28-
}
29-
try {
30-
await page.goto(params.url, { waitUntil: 'domcontentloaded', timeout: 30000 });
31-
return { content: [{ type: 'text', text: `Navigated to ${params.url}` }] };
32-
} catch (error) {
33-
console.error(`Navigate action failed: ${error}`);
34-
throw error; // Rethrow
35-
}
38+
await page.goto(params.url);
39+
return { content: [{ type: 'text', text: `Navigated to ${params.url}` }] };
3640
};
3741

42+
const code = [
43+
`// Navigate to ${params.url}`,
44+
`await page.goto('${params.url}');`,
45+
];
46+
3847
return {
39-
action,
40-
code: [], // Add code property
41-
captureSnapshot: true, // Navigation changes page state
42-
waitForNetwork: false, // page.goto handles waiting implicitly
48+
action,
49+
code,
50+
captureSnapshot,
51+
waitForNetwork: false,
52+
};
53+
},
54+
});
55+
56+
const goBack: ToolFactory = captureSnapshot => defineTool({
57+
capability: 'history',
58+
schema: {
59+
name: 'browserbase_navigate_back',
60+
description: 'Go back to the previous page',
61+
inputSchema: z.object({}),
62+
},
63+
64+
handle: async context => {
65+
const page = await context.getActivePage();
66+
if (!page) {
67+
throw new Error('No active page found for goBack');
68+
}
69+
const action = async (): Promise<ToolActionResult> => {
70+
await page.goBack();
71+
return { content: [{ type: 'text', text: 'Navigated back' }] };
4372
};
44-
}
73+
const code = [
74+
`// Navigate back`,
75+
`await page.goBack();`,
76+
];
4577

46-
// Define tool using handle
47-
const navigateTool: Tool<typeof NavigateInputSchema> = {
48-
capability: 'core', // Add capability
49-
schema: navigateSchema,
50-
handle: handleNavigate,
51-
};
78+
return {
79+
action,
80+
code,
81+
captureSnapshot,
82+
waitForNetwork: true,
83+
};
84+
},
85+
});
5286

53-
// Export the single tool object as default
54-
export default [navigateTool]; // Export as an array containing the tool
87+
const goForward: ToolFactory = captureSnapshot => defineTool({
88+
capability: 'history',
89+
schema: {
90+
name: 'browserbase_navigate_forward',
91+
description: 'Go forward to the next page',
92+
inputSchema: z.object({}),
93+
},
94+
handle: async context => {
95+
const page = await context.getActivePage();
96+
if (!page) {
97+
throw new Error('No active page found for goForward');
98+
}
99+
const action = async (): Promise<ToolActionResult> => {
100+
await page.goForward();
101+
return { content: [{ type: 'text', text: 'Navigated forward' }] };
102+
};
103+
const code = [
104+
`// Navigate forward`,
105+
`await page.goForward();`,
106+
];
107+
return {
108+
action,
109+
code,
110+
captureSnapshot,
111+
waitForNetwork: true,
112+
};
113+
},
114+
});
55115

56-
// If you have multiple navigation tools (back, forward), group them:
57-
// export const navigationTools: Tool[] = [navigateTool, backTool, forwardTool];
116+
const captureSnapshotValue = true;
58117

59-
// TODO: Add handlers for navigate_back, navigate_forward if needed
118+
export default [
119+
navigate(captureSnapshotValue),
120+
goBack(captureSnapshotValue),
121+
goForward(captureSnapshotValue),
122+
];

0 commit comments

Comments
 (0)