Parent roadmap: #1439
Summary
Think should include an optional, conservative fetch tool for agents that need to read HTTP resources without enabling arbitrary browser automation or unrestricted network access.
This should be a small capability in the execution ladder: more powerful than plain model knowledge, less powerful than Browser Run, and safer than letting generated code call any URL.
Problem
A lot of agent tasks need simple network reads:
- fetch public docs pages or API references
- retrieve JSON from a known service endpoint
- inspect a changelog, release note, RSS feed, or status page
- call a first-party internal endpoint that the app owner explicitly allows
Today, Think has workspace tools and codemode execution, and browser tools exist for full CDP/browser workflows. But there is no clear built-in path for “read this allowlisted URL safely”. Users either need to write their own tool, use browser automation for a simple fetch, or expose broader network access than intended.
Goals
- Provide a simple Think tool for HTTP reads against an explicit allowlist.
- Make the safe path obvious for common docs/API lookup use cases.
- Keep the tool deterministic and bounded: limits, redirects, content types, and output size should be explicit.
- Avoid creating a general-purpose SSRF primitive.
Non-goals
- Do not add unrestricted outbound network access.
- Do not replace Browser Run for rendered pages, screenshots, auth flows, or CDP/browser automation.
- Do not make this a generic HTTP client for mutating APIs in v1.
- Do not persist fetched content automatically as memory unless the caller explicitly does that through existing tools.
Proposed API shape
Names are illustrative:
createFetchTool({
allowlist: [
"https://developers.cloudflare.com/**",
"https://api.github.com/repos/cloudflare/agents/**"
],
methods: ["GET"],
maxBytes: 512_000,
timeoutMs: 10_000,
followRedirects: "same-origin",
response: "text" // or "json" / "auto"
})
Possible Think usage:
getTools() {
return {
...createWorkspaceTools(this.workspace),
...createFetchTool({
allowlist: this.getAllowedFetchOrigins()
})
};
}
The AI-facing tool could be one tool:
fetch_url({ url, headers? })
or two tools:
fetch_text({ url })
fetch_json({ url })
Prefer the smallest surface that keeps output predictable.
Security / design questions
- What allowlist syntax should we support? Exact URLs, origins, glob paths, URLPattern, or caller-provided predicate?
- Should redirects be disabled by default, same-origin only, or allowlisted destination only?
- Should private IPs, localhost,
.internal, link-local, and metadata-service ranges be blocked even if a caller misconfigures the allowlist?
- Should request headers be fully blocked, fixed by the app, or allowlisted by header name?
- Should only
GET be supported in v1? If POST is supported later, it likely belongs in a separate explicit API/action tool with approval.
- How should content be normalized? Raw text, Markdown extraction, JSON parsing, or content-type aware auto mode?
- How should large responses be handled? Hard byte cap, truncation with metadata, or write-to-workspace option?
- Should robots.txt/cache semantics be documented or enforced?
- How should errors be represented so models can distinguish disallowed URL, timeout, non-2xx, unsupported content type, and truncation?
Suggested v1 behavior
- Only
GET and HEAD.
- Require explicit allowlist.
- Deny private-network targets by default.
- Follow redirects only when the final URL is also allowlisted.
- Cap response bytes and tool-output tokens.
- Return structured metadata: final URL, status, content type, byte length, truncated flag.
- Support
text, json, and maybe arrayBuffer only if the caller opts into writing binaries to Workspace.
- Do not include credentials unless the app supplies fixed server-side headers for a specific allowlisted origin.
Acceptance criteria
@cloudflare/think exposes a documented fetch tool factory or clearly documented example pattern.
- The tool cannot fetch URLs outside the configured allowlist.
- Redirects cannot escape the allowlist.
- Private-network / localhost SSRF cases are blocked or explicitly addressed.
- Response size, timeout, and content-type handling are tested.
- Error messages are actionable for users and models.
- Docs compare this with Browser Run and codemode so developers know when to use each.
Parent roadmap: #1439
Summary
Think should include an optional, conservative
fetchtool for agents that need to read HTTP resources without enabling arbitrary browser automation or unrestricted network access.This should be a small capability in the execution ladder: more powerful than plain model knowledge, less powerful than Browser Run, and safer than letting generated code call any URL.
Problem
A lot of agent tasks need simple network reads:
Today, Think has workspace tools and codemode execution, and browser tools exist for full CDP/browser workflows. But there is no clear built-in path for “read this allowlisted URL safely”. Users either need to write their own tool, use browser automation for a simple fetch, or expose broader network access than intended.
Goals
Non-goals
Proposed API shape
Names are illustrative:
Possible Think usage:
The AI-facing tool could be one tool:
fetch_url({ url, headers? })or two tools:
fetch_text({ url })fetch_json({ url })Prefer the smallest surface that keeps output predictable.
Security / design questions
.internal, link-local, and metadata-service ranges be blocked even if a caller misconfigures the allowlist?GETbe supported in v1? IfPOSTis supported later, it likely belongs in a separate explicit API/action tool with approval.Suggested v1 behavior
GETandHEAD.text,json, and maybearrayBufferonly if the caller opts into writing binaries to Workspace.Acceptance criteria
@cloudflare/thinkexposes a documented fetch tool factory or clearly documented example pattern.