Connect+Documentation
AI plugins

The plugin api

The capability api a tool receives — api.fetch (host-allowlisted) and api.secret (declared, encrypted), per method with examples.

Every AI-plugin tool receives two arguments: (args, api). args is the JSON the assistant filled in against your parameters schema; api is the capability object — the entire surface a tool can reach. There is no require, no fetch, no filesystem, no session — only what api exposes, and only what your manifest declared and the user approved.

  • Members: api.fetch, api.secret
  • Enforced in: the main process (not on the plugin's honor)

New to plugins? Start with Create an AI plugin for the concepts and manifest; this page is the runtime api reference.

Walkthrough

Call an authenticated API from a tool.

  1. Declare the host and the secret in your manifest's permissions.
  2. Read the secret with api.secret and send it in a header.
  3. Fetch the host with api.fetch and return the parsed result.
// plugin.json
"permissions": {
  "network": ["api.example.com"],
  "secrets": ["API_TOKEN"]
}
// index.js — one exported async function per tool
export async function lookup(args, api) {
  const token = api.secret('API_TOKEN');                 // declared → allowed
  const res = await api.fetch(`https://api.example.com/things/${args.id}`, {
    headers: { Authorization: `Bearer ${token}` },
  });
  if (res.status !== 200) throw new Error(`upstream ${res.status}`);
  return res.json();                                      // returned to the assistant
}

Members

api.fetch(url, init?)

Make an HTTP request to a host your manifest declared in permissions.network. The call runs in the main process, bound to the profile's session (its cookies, proxy, and user-agent) — not in the worker.

How to use it

  1. Make sure the URL's host is listed in permissions.network (exact hostname).
  2. Pass init (method / headers / body) if you need more than a GET.
  3. await the result; read the body with res.text() or res.json().

Signature

await api.fetch(url, init?)

Parameters

ParameterTypeRequiredDescription
urlstringyeshttp/https only. Its host must be an exact match in permissions.network.
init.methodstringnoHTTP method (default GET).
init.headersRecord<string, string>noRequest headers.
init.bodystringnoRequest body (already serialised).

ReturnsPromise<{ status, headers, text(), json() }>:

MemberTypeDescription
statusnumberHTTP status code.
headersRecord<string, string>Response headers.
text()() => stringThe body as text.
json()() => unknownThe body parsed as JSON (throws on invalid JSON).

Errors & edge cases

  • Throws if the URL's host isn't in permissions.network, or the scheme isn't http/https — enforced before the request is ever made.
  • Host matching is an exact hostname compare (case-insensitive); api.example.com does not cover www.api.example.com. List each host you need.
  • res.json() throws if the body isn't valid JSON — guard it or use text().

Examples

// GET + JSON
const res = await api.fetch('https://catfact.ninja/fact');
return res.json().fact;
// POST with a body and a header
const res = await api.fetch('https://api.example.com/notes', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({ text: args.text }),
});
return res.status === 201 ? 'saved' : `error ${res.status}`;

api.secret(name)

Read a secret the user entered for your plugin. Secrets are stored encrypted on the device, never written to logs, and never shown to the assistant — only your tool code sees the value.

How to use it

  1. Declare the name in permissions.secrets (UPPER_SNAKE).
  2. Call api.secret('NAME') — it's synchronous.
  3. Handle null (declared, but the user hasn't filled it in yet).

Signature

const value = api.secret(name)   // synchronous

Parameters

ParameterTypeRequiredDescription
namestringyesMust be declared in permissions.secrets.

Returnsstring | null — the user's value, or null if they haven't set it.

Errors & edge cases

  • Throws if name isn't declared in permissions.secrets (no reaching for undeclared secrets).
  • Returns null when the secret is declared but empty — check for it and fail clearly.

Example

const token = api.secret('API_TOKEN');
if (!token) throw new Error('Set API_TOKEN in the plugin settings first.');

What a tool cannot do

The api object is the whole surface. A tool runs in an isolated worker with no access to Node, the filesystem, the browser session, other plugins, or any host you didn't declare. api.page.* (read/act on the current tab) is coming and will require the page permission plus a per-site grant.

See also: Create an AI plugin · SDK & aip CLI reference.

On this page