AI Agent Web Requests And Notes

What It Is

Every AI agent, assistant or builder, has a small set of tools of its own next to the tenant's MCP tools:

  • http_request calls an outside HTTP API or web page, with any method, headers and body.
  • response_query reads part of a response that http_request saved.
  • notes_write, notes_read and notes_delete keep notes in the conversation's workspace.

They run in the AI Sidecar, not on the tenant's MCP server, so external MCP clients never get them. No setting turns them on: every agent has them in the chat and in agent runs.

Why It Matters

Many configuration tasks start from data that lives somewhere else. "Build a Country enumeration from the registry's API" or "map our CRM's pipeline stages to a status field" used to mean copying a response into the chat by hand. Now the person pastes the URL and the agent reads the API itself, looks at the parts it needs and builds the configuration from them.

Notes solve a different problem: a long conversation. Once a conversation outgrows the agent's conversation memory, its oldest part is summarised, and details such as record IDs, decisions or a half-finished plan can drop out. What the agent writes in a note is sent with every later turn of that conversation, however long it gets.

How It Works

http_request

The agent gives a URL and, optionally, a method (GET when omitted), headers, a body and a timeout. A body is sent as JSON, as a form (a=1&b=2) or as plain text; the agent can say which, or it is guessed from the body and the Content-Type header.

Every response is saved in the conversation's workspace under an id: r1, r2 and so on. What the model gets back depends on the size:

  • A small body (up to about 12,000 characters) comes back whole, together with the status and headers.
  • A larger body comes back as a preview, an outline of its structure (each object's fields with a sample value, each list's length) and the id to read it with response_query. The model then reads only the parts it needs instead of the whole document.
  • A binary body (an image, a PDF) is described by type and size but not kept.

Everything a response contains is marked as coming from outside the platform: the agent is told to treat it as data to analyse, never as instructions to follow.

response_query

Reads a saved response without calling the API again:

  • JSON: a JSONPath in path ($.data[*], $.items[0:20], $..id, $['odd key']), fields to keep only some fields of each match (dotted paths such as address.city reach nested ones), where to keep matches whose fields equal given values ({"active": true}; a list of values means any of them), and offset / limit for paging. Long results are cut to fit and say where to continue.
  • Text (CSV, XML, HTML): lines containing a text (contains, case-insensitive) or a range of lines (start_line, line_count).
  • No arguments: the outline of the document.

Notes

notes_write saves a named note (plan, api-findings), replacing it or adding to it; notes_read reads one note or all of them; notes_delete removes one. Notes are Markdown.

In the chat, the notes and the list of saved responses belong to the conversation: they are sent to the model with every turn, and the person can read them, but not change them, under the Notes button in the chat's header, which appears once the conversation has any. In an agent run, notes and saved responses last only for the run.

Using a secret in a request

An API that needs a key gets it from the Secret Store, never from the chat. The agent writes {{secret:NAME}} where the key belongs: in a header (Authorization: Bearer {{secret:CRM_TOKEN}}), the query string or the body. The sidecar puts the value in just before sending, encoded for where it stands. The model never sees the value: if the API echoes the key back, the agent reads [secret:CRM_TOKEN] instead.

A secret can be used this way only after a Tenant Admin lists the hosts it may be sent to. A request that names any other secret, or sends a secret to another host, is refused before anything is sent. The system prompt lists the secrets an agent can use and their hosts, so people never need to paste keys into the chat.

Security Model

Anyone who can talk to an agent can ask it to call a URL, and a page or API response the agent reads can try to give it instructions. The rules below keep that from reaching what it should not:

  • Public internet only. Requests may go only to public internet addresses. Names that resolve to the local machine, private networks, the cloud metadata service or other reserved ranges are refused, and the connection goes to the address that was checked, so a name that changes its answer cannot slip through. Each redirect is checked again.
  • Secrets stay with their hosts. A secret is sent only to the hosts listed for it, never as part of a host name, and a request that carries one does not follow a redirect to another host. Authorization and cookie headers are dropped on any redirect to another host.
  • External content is data. Responses are labelled as external, and the agent's instructions say to ignore instructions found in them and never to send the platform's data somewhere because external content asked for it.
  • Everything is visible. Each call is a step in the chat (for example Call a web API · POST api.example.com/orders), recorded with the conversation's other tool calls; a call that is not a GET, HEAD or OPTIONS counts as a change in the reply's list of changes. The person can read every saved response's address and status under Notes.
  • Permissions do not change. What the agent may read or change in the tenant is still decided by its user and its tool scope. An outside API never widens it.

There is no allow-list of destinations for requests in general: a query string can carry data as well as a body can, so limiting methods or adding per-agent switches would not stop a determined misuse. Scope what the agent can read in the tenant instead, and list hosts only for the secrets agents really need.

Limits

WhatLimit
Time for one request, redirects included30 s, up to 60 s when the agent asks
Redirects followed5
Response body kept5 MB (after decompression); the rest is cut and the response says so
Request body1 MB
Saved responses per conversationthe latest 30
Notes per conversation30, up to 32,000 characters each and 128,000 together

Example: An Enumeration From An Outside API

  1. A Tenant Admin stores the registry's API key in the Secret Store as REGISTRY_TOKEN, with the host api.registry.example.com.
  2. In a builder agent's chat: "Create a Country enumeration from https://api.registry.example.com/v2/countries, only the active ones, code as the item and name as the label."
  3. The agent calls the URL with Authorization: Bearer {{secret:REGISTRY_TOKEN}}. The answer is large, so it gets an outline, sees $.data[*] with code, name and active, and notes the plan.
  4. It reads $.data[*] with fields: ["code", "name"] and where: {"active": true}, page by page, and creates the enumeration and its items with the builder's model tools.
  5. The person sees the steps, the changes made, and under Notes the plan and the saved responses.

Best Practices

  • Give agents the secrets they need by host, not by pasting keys into a conversation or a system prompt.
  • List exact hosts (api.example.com) rather than wildcards (*.example.com) unless the API really spreads over subdomains.
  • Ask the agent to note its plan in long tasks; it keeps the thread when older messages are summarised.
  • Keep builders scoped as before: a request to an outside API is one more source of input, not a reason to widen what the agent can change.