MCPcopy Create free account
hub / github.com/ForestHubAI/edge-agents / fetch

Method fetch

go/engine/node/webfetch.go:113–162  ·  view source on GitHub ↗

fetch validates the URL, applies SSRF pre-checks, performs the GET, reads up to webFetchMaxBytes, extracts text from HTML payloads, and truncates the result to maxChars.

(ctx context.Context, rawURL string, maxChars int)

Source from the content-addressed store, hash-verified

111 return "", fmt.Errorf("web_fetch %s: url: %w", n.ID(), err)
112 }
113 text, err := n.webFetch(ctx, webFetchArgs{URL: urlStr})
114 if err != nil {
115 return "", err
116 }
117 if err := engine.ApplyOutput(scope, n.ID(), webFetchOutID, n.binding, expr.StringVal(text)); err != nil {
118 return "", fmt.Errorf("web_fetch %s: applying output: %w", n.ID(), err)
119 }
120 return n.Next(engine.PortCtrl, scope)
121}
122
123// webFetchArgs is the tool-call payload. A URL is always a string, so the
124// schema is derivable from this type.
125type webFetchArgs struct {
126 URL string `json:"url"`
127}
128
129// Tools exposes this node as `web_fetch(url)`. maxChars is not a parameter —
130// the author's cap applies to model-issued fetches too.
131func (n *WebFetch) Tools() ([]llmproxy.FunctionTool, error) {
132 ft, err := llmproxy.NewFunctionTool("web_fetch", n.toolDescription, n.webFetch)
133 if err != nil {
134 return nil, fmt.Errorf("web_fetch %s: %w", n.ID(), err)
135 }
136 return []llmproxy.FunctionTool{ft}, nil
137}
138
139// webFetch is the actual implementation of the tool call, unwrapped from the
140// node execution signature.
141func (n *WebFetch) webFetch(ctx context.Context, args webFetchArgs) (string, error) {
142 text, err := n.fetch(ctx, args.URL, n.maxChars)
143 if err != nil {
144 return "", fmt.Errorf("web_fetch %s: %w", n.ID(), err)
145 }
146 return text, nil
147}
148
149// fetch validates the URL, applies SSRF pre-checks, performs the GET, reads up
150// to webFetchMaxBytes, extracts text from HTML payloads, and truncates the
151// result to maxChars.
152func (n *WebFetch) fetch(ctx context.Context, rawURL string, maxChars int) (string, error) {
153 parsed, err := url.Parse(strings.TrimSpace(rawURL))
154 if err != nil {
155 return "", fmt.Errorf("invalid url: %w", err)
156 }
157 if parsed.Scheme != "http" && parsed.Scheme != "https" {
158 return "", fmt.Errorf("only http/https urls allowed, got %q", parsed.Scheme)
159 }
160 if parsed.Host == "" {
161 return "", fmt.Errorf("missing host in url")
162 }
163 if isObviousPrivateHost(parsed.Hostname()) {
164 return "", fmt.Errorf("fetching private or local hosts is not allowed")
165 }

Callers 1

ExecuteMethod · 0.95

Calls 8

isObviousPrivateHostFunction · 0.85
looksLikeHTMLFunction · 0.85
extractTextFromHTMLFunction · 0.85
DoMethod · 0.80
GetMethod · 0.80
StringMethod · 0.65
CloseMethod · 0.65
SetMethod · 0.45

Tested by

no test coverage detected