Quickstart

This guide shows how to use Magnitude with Steel to create an AI browser agent that visits the Steel leaderboard Github repo, extracts the details behind the latest commit, and if associated with a pull request, it will summarize the details.

Scroll to the bottom to see a full example!

Requirements

  • Anthropic API Key

  • Steel API Key

  • Node.js 20+

Step 1: Project Setup

Create a new TypeScript project and basic script:

Terminal
mkdir steel-magnitude && \
cd steel-magnitude && \
npm init -y && \
npm install -D typescript @types/node ts-node && \
npx tsc --init && \
npm pkg set scripts.start="ts-node index.ts" && \
touch index.ts .env

Step 2: Install Dependencies

Terminal
$
npm install steel-sdk magnitude-core zod dotenv

Step 3: Environment Variables

Create a .env file with your API keys:

ENV
.env
1
STEEL_API_KEY=your-steel-api-key-here
2
ANTHROPIC_API_KEY=your-anthropic-api-key-here

Step 4: Initialize Steel & Magnitude

Set up Steel, load env vars, and prepare to start the Magnitude agent.

Typescript
index.ts
1
import * as dotenv from "dotenv";
2
import { Steel } from "steel-sdk";
3
import { startBrowserAgent } from "magnitude-core";
4
import { z } from "zod";
5
6
dotenv.config();
7
8
const STEEL_API_KEY = process.env.STEEL_API_KEY || "your-steel-api-key-here";
9
const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY || "your-anthropic-api-key-here";
10
11
const client = new Steel({ steelAPIKey: STEEL_API_KEY });
12

Step 5: Create a Steel Session & Start the Agent

Create a Steel session, then connect Magnitude via CDP. Turn on narrate for easy debugging.

Typescript
index.ts
1
async function main() {
2
console.log("🚀 Steel + Magnitude Node Starter");
3
console.log("=".repeat(60));
4
5
if (STEEL_API_KEY === "your-steel-api-key-here") {
6
console.warn("⚠️ Please set STEEL_API_KEY in your .env");
7
console.warn(" Get one at https://app.steel.dev/settings/api-keys");
8
return;
9
}
10
11
if (ANTHROPIC_API_KEY === "your-anthropic-api-key-here") {
12
console.warn("⚠️ Please set ANTHROPIC_API_KEY in your .env");
13
console.warn(" Get one at https://console.anthropic.com/");
14
return;
15
}
16
17
let session: any;
18
let agent: any;
19
20
try {
21
console.log("\nCreating Steel session...");
22
session = await client.sessions.create({
23
// Optional knobs:
24
// useProxy: true,
25
// proxyUrl: 'http://user:pass@host:port',
26
// solveCaptcha: true,
27
// sessionTimeout: 1800000, // ms
28
// userAgent: 'custom-ua'
29
});
30
31
console.log(`Steel session created!`);
32
console.log(`View session at: ${session.sessionViewerUrl}`);
33
34
agent = await startBrowserAgent({
35
url: "https://github.com/steel-dev/leaderboard",
36
narrate: true,
37
llm: {
38
provider: "anthropic",
39
options: {
40
model: "claude-3-7-sonnet-latest",
41
apiKey: process.env.ANTHROPIC_API_KEY,
42
},
43
},
44
browser: {
45
cdp: `${session.websocketUrl}&apiKey=${STEEL_API_KEY}`,
46
},
47
});
48
49
console.log("Connected to browser via Magnitude");

Use Magnitude’s agent.extract to pull structured data (user behind commit + commit itself) using a Zod schema.

Typescript
index.ts
1
console.log("Looking for commits");
2
3
const mostRecentCommitter = await agent.extract(
4
"Find the user with the most recent commit",
5
z.object({
6
user: z.string(),
7
commit: z.string(),
8
})
9
);
10
11
console.log("\n\x1b[1;92mMost recent committer:\x1b[0m");
12
console.log(`${mostRecentCommitter.user} has the most recent commit`);
13

Step 7: Perform Natural-Language Actions

Use agent.act to summarize the pull request (if there’s a pull request behind the commit).

Typescript
index.ts
1
console.log("\nLooking for pull request behind the most recent commit\x1b[0m");
2
3
try {
4
await agent.act(
5
"Find the pull request behind the most recent commit if there is one"
6
);
7
console.log("Found pull request!");
8
9
const pullRequest = await agent.extract(
10
"What was added in this pull request?",
11
z.object({
12
summary: z.string(),
13
})
14
);
15
console.log("Pull request found!");
16
console.log(`${pullRequest.summary}`);
17
} catch (error) {
18
console.log("No pull request found or accessible");
19
}
20
21
await new Promise((resolve) => setTimeout(resolve, 2000));
22
23
console.log("\nAutomation completed successfully!");

Step 8: Clean Up

Stop the agent and release the Steel session.

Typescript
index.ts
1
} catch (error) {
2
console.error("Error during automation:", error);
3
} finally {
4
if (agent) {
5
console.log("Stopping Magnitude agent...");
6
try {
7
await agent.stop();
8
} catch (error) {
9
console.error("Error stopping agent:", error);
10
}
11
}
12
13
if (session) {
14
console.log("Releasing Steel session...");
15
try {
16
await client.sessions.release(session.id);
17
console.log("Steel session released successfully");
18
} catch (error) {
19
console.error("Error releasing session:", error);
20
}
21
}
22
}
23
}
24
25
main().catch((error) => {
26
console.error("Unhandled error:", error);
27
process.exit(1);
28
});

Run It

You’ll see a session viewer URL in your console, open it to watch the automation live.

Full Example

Complete index.ts you can paste and run:

Typescript
index.ts
1
/*
2
* AI-powered browser automation using Magnitude with Steel browsers.
3
* https://github.com/steel-dev/steel-cookbook/tree/main/examples/steel-magnitude-starter
4
*/
5
6
import * as dotenv from "dotenv";
7
import { Steel } from "steel-sdk";
8
import { z } from "zod";
9
import { startBrowserAgent } from "magnitude-core";
10
11
dotenv.config();
12
13
// Replace with your own API keys
14
const STEEL_API_KEY = process.env.STEEL_API_KEY || "your-steel-api-key-here";
15
const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY || "your-anthropic-api-key-here";
16
17
// Initialize Steel client with the API key from environment variables
18
const client = new Steel({ steelAPIKey: STEEL_API_KEY });
19
20
async function main() {
21
console.log("🚀 Steel + Magnitude Node Starter");
22
console.log("=".repeat(60));
23
24
if (STEEL_API_KEY === "your-steel-api-key-here") {
25
console.warn("⚠️ WARNING: Please replace 'your-steel-api-key-here' with your actual Steel API key");
26
console.warn(" Get your API key at: https://app.steel.dev/settings/api-keys");
27
return;
28
}
29
30
if (ANTHROPIC_API_KEY === "your-anthropic-api-key-here") {
31
console.warn("⚠️ WARNING: Please replace 'your-anthropic-api-key-here' with your actual Anthropic API key");
32
console.warn(" Get your API key at: https://console.anthropic.com/");
33
return;
34
}
35
36
let session: any;
37
let agent: any;
38
39
try {
40
console.log("\nCreating Steel session...");
41
session = await client.sessions.create({
42
// Optional knobs:
43
// useProxy: true,
44
// proxyUrl: 'http://user:pass@host:port',
45
// solveCaptcha: true,
46
// sessionTimeout: 1800000, // ms
47
// userAgent: 'custom-ua'
48
});
49
50
console.log(`Steel session created!`);
51
console.log(`View session at: ${session.sessionViewerUrl}`);
52
53
agent = await startBrowserAgent({
54
url: "https://github.com/steel-dev/leaderboard",
55
narrate: true,
56
llm: {
57
provider: "anthropic",
58
options: {
59
model: "claude-3-7-sonnet-latest",
60
apiKey: process.env.ANTHROPIC_API_KEY,
61
},
62
},
63
browser: {
64
cdp: `${session.websocketUrl}&apiKey=${STEEL_API_KEY}`,
65
},
66
});
67
68
console.log("Connected to browser via Magnitude");
69
console.log("Looking for commits");
70
71
const mostRecentCommitter = await agent.extract(
72
"Find the user with the most recent commit",
73
z.object({
74
user: z.string(),
75
commit: z.string(),
76
})
77
);
78
79
console.log("Most recent committer:");
80
console.log(`${mostRecentCommitter.user} has the most recent commit`);
81
82
console.log("\nLooking for pull request behind the most recent commit\x1b[0m");
83
84
try {
85
await agent.act(
86
"Find the pull request behind the most recent commit if there is one"
87
);
88
console.log("Found pull request!");
89
90
const pullRequest = await agent.extract(
91
"What was added in this pull request?",
92
z.object({
93
summary: z.string(),
94
})
95
);
96
console.log("Pull request found!");
97
console.log(`${pullRequest.summary}`);
98
} catch (error) {
99
console.log("No pull request found or accessible");
100
}
101
102
await new Promise((resolve) => setTimeout(resolve, 2000));
103
104
console.log("\nAutomation completed successfully!");
105
} catch (error) {
106
console.error("Error during automation:", error);
107
} finally {
108
if (agent) {
109
console.log("Stopping Magnitude agent...");
110
try {
111
await agent.stop();
112
} catch (error) {
113
console.error("Error stopping agent:", error);
114
}
115
}
116
117
if (session) {
118
console.log("Releasing Steel session...");
119
try {
120
await client.sessions.release(session.id);
121
console.log("Steel session released successfully");
122
} catch (error) {
123
console.error("Error releasing session:", error);
124
}
125
}
126
}
127
}
128
129
main().catch((error) => {
130
console.error("Unhandled error:", error);
131
process.exit(1);
132
});
133

Next Steps