Connect with External APIs
Use an extension plus the network capability when an agent needs to call an external service.
Create an API Extension
ts
const agent = await app.agents.create({
title: "API assistant",
config: {
instructions: "Use the weather tool when the user asks about weather.",
capabilities: ["network"],
extensions: [
{
environment: "agent",
name: "get_weather",
description: "Fetch current weather for a city.",
parameters: {
type: "object",
properties: {
city: { type: "string" },
},
required: ["city"],
},
code: `
export default async function ({ city }) {
const url = new URL("https://api.example.com/weather");
url.searchParams.set("city", city);
const res = await fetch(url);
if (!res.ok) throw new Error("Weather API failed");
return await res.json();
}
`,
},
],
},
});Use Secrets for API Keys
Do not hardcode API keys, passwords, or authentication tokens in your extension code or prompts. Instead, store them securely as UClaw secrets, and reference them using placeholders inside your code.
1. Register a Secret
Use the app.secrets.add API on your server to save a secret. This persists the credential in UClaw's secure database.
ts
import { AppClient } from "@uclaw/sdk";
const app = new AppClient({
apiKey: process.env.UCLAW_API_KEY,
});
// Add a secret key (e.g. GitHub API Token), optionally restricting it to specific hosts
await app.secrets.add("GITHUB_TOKEN", "ghp_xxxxxxxxxxxxxxxxxxxx", {
allowedHosts: ["api.github.com", "*.github.com"],
});2. Configure Capabilities
Ensure your agent configuration includes both the network and secret capabilities:
ts
const agent = await app.agents.create({
config: {
capabilities: ["network", "secret"],
// ...
},
});3. Use Secrets in Extension Code
Use the ${{ secrets.<SECRET_KEY> }} placeholder pattern in your extension's network requests. UClaw's runtime proxy will automatically intercept outgoing requests and replace the placeholder with the actual value securely.
ts
const agent = await app.agents.create({
config: {
capabilities: ["network", "secret"],
extensions: [
{
environment: "agent",
name: "get_repo_stars",
description: "Get star count of a GitHub repository.",
parameters: {
type: "object",
properties: {
owner: { type: "string" },
repo: { type: "string" },
},
required: ["owner", "repo"],
},
code: `
export default async function ({ owner, repo }) {
const res = await fetch(\`https://api.github.com/repos/\${owner}/\${repo}\`, {
headers: {
// The placeholder will be securely replaced at runtime
"Authorization": "Bearer \${{ secrets.GITHUB_TOKEN }}",
"User-Agent": "UClaw-Agent"
}
});
if (!res.ok) throw new Error("GitHub API failed");
const data = await res.json();
return { stars: data.stargazers_count };
}
`,
},
],
},
});Run the Agent
ts
const run = await agent.run("What is the weather in San Francisco?");
await run.wait({ until: "running", timeoutMs: 60_000 });
for await (const event of run.stream()) {
if (event.type === "text-delta") process.stdout.write(event.delta);
}