# Connect an agent

Point an agent at a Glyphfield deployment, read the discovery routes in order, send a first generation request, and hand Design Lab documents to the browser.

An agent connects to a Glyphfield origin: the base URL of a deployment, or `http://localhost:3012` for a local development server. The API routes send `Access-Control-Allow-Origin: *`, so a web page on another origin can call them.

## Discovery order [#discovery-order]

Follow these steps for each new origin:

1. Read `/llms.txt` for the short guide. Read `/llms-full.txt` when the task needs the complete product model.
2. Read `/api/agent` for the API version, policies, resources and contracts.
3. Read `/api/labs` for the Studio tools.
4. Read `/api/catalog` when choosing a background or tactile surface. Its `surfaceLibrary` holds every surface preset with its attribution and controls.
5. Read `/api/materials` when choosing a shader or an image effect.
6. Read `/api/identities` when using a built-in identity.
7. Read `/api/elements` when choosing a brand element.
8. Read `GET /api/generate` right before building a request. Validate the body against its `requestSchema` when the client supports JSON Schema.
9. Send the request to `/api/generate` as `POST` with `Content-Type: application/json`.
10. Save the returned artifact. For a `design-sequence` response, apply its `document` through `window.glyphfield.studio` and export in the browser.

Use only the enum values that the contract lists. Read the structured routes instead of the client JavaScript bundle.

## Shell check [#shell-check]

```bash
BASE_URL=http://localhost:3012

curl -fsS "$BASE_URL/llms.txt"
curl -fsS "$BASE_URL/api/agent" | jq '{ version, schemaVersion, resources, interfaces, execution }'
curl -fsS "$BASE_URL/api/labs" | jq '{ count, plugins: [.plugins[].id] }'
curl -fsS "$BASE_URL/api/catalog" | jq '{ surfaces: .surfaceLibrary.count, surfaceControls: (.surfaceLibrary.controls | keys) }'
curl -fsS "$BASE_URL/api/materials" | jq '{ count, engines, sharedBy }'
curl -fsS "$BASE_URL/api/generate" | jq '{kinds: (.kinds | keys), requestSchema}'
```

For a deployed instance, set `BASE_URL` to its origin.

## TypeScript discovery client [#typescript-discovery-client]

```ts
const baseUrl = 'http://localhost:3012';

const [manifest, labs, materials, generation, identities, elements] = await Promise.all([
  fetch(`${baseUrl}/api/agent`).then((response) => response.json()),
  fetch(`${baseUrl}/api/labs`).then((response) => response.json()),
  fetch(`${baseUrl}/api/materials`).then((response) => response.json()),
  fetch(`${baseUrl}/api/generate`).then((response) => response.json()),
  fetch(`${baseUrl}/api/identities`).then((response) => response.json()),
  fetch(`${baseUrl}/api/elements`).then((response) => response.json()),
]);

console.log(manifest.version, labs.count, materials.count, generation.schemaVersion);
console.log(identities.identities.length, elements.elements.length);
console.log(manifest.studioBrowserApi.global);
```

The discovery requests do not depend on each other, so they can run in parallel. Read the generation contract again if much time passes before the request.

## First generation request [#first-generation-request]

```ts
const response = await fetch(`${baseUrl}/api/generate`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    kind: 'template',
    template: 'slides',
    slideLayout: 'title',
    texture: 'white',
    title: 'Code is the source of truth.',
    identity: { preset: 'gt' },
    output: 'raw',
  }),
});

if (!response.ok) throw new Error(await response.text());
const svg = await response.text();
```

With `output: 'raw'`, the response body is a complete SVG document.

## Design Lab sequence [#design-lab-sequence]

`POST /api/generate` builds the source document for Design Lab, the layered composition tool. The Browser API then renders it with the same shader canvases and compositor as the Studio UI.

```ts
const response = await fetch(`${baseUrl}/api/generate`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    kind: 'design-sequence',
    identity: { preset: 'gt' },
    shader: { materialId: 'paper-gem-smoke' },
    sequence: { cutCount: 10, finalHoldMs: 5000, pace: 'accelerating' },
    effect: { kind: 'bayer', opacity: 0.76 },
    texts: [{ value: 'Open Source', weight: 500 }],
    export: { width: 1920, fps: 30, quality: 'best' },
  }),
});
const generated = await response.json();

// Run inside /studio?tool=material, the Design Lab page.
const studio = window.glyphfield.studio;
if (studio.activeTool() !== 'material') throw new Error('Open Design Lab first.');
await studio.applySource(generated.document);
const artifact = await studio.invoke('design.export', {
  format: 'mp4',
  mode: 'shader-sequence',
  download: true,
});
```

Call `studio.describe()` before tool-specific actions. It returns each action's input and output contract. Its capability record marks each export as a direct Browser action (`browser-action`), a visible control (`browser-control`) or HTTP generation (`http`). `studio.controls()`, `activate(label)` and `set(label, value)` operate the visible controls of the active tool by accessible label, which covers tools that have no export action. `design.export` takes `png`, `jpg`, `gif` or `mp4`. Leave out `download` to receive only the returned Blob, and call `studio.download(artifact)` to save it later.

## Agent prompt [#agent-prompt]

Give a language model the guide URL instead of pasting the schema into the prompt:

```text
Read https://YOUR_ORIGIN/llms.txt and the linked agent manifest.
Generate a white GT agenda slide titled “One system, every market.”
Save the raw SVG response as gt-agenda.svg.
Do not use undocumented enum values.
```

The deployment's own contract then decides which fields are valid.

For broad implementation work, point to `/llms-full.txt` instead. For a focused task, point to one page, such as `/api/docs/studio/design-lab` or `/api/docs/reference/browser-api`.

## Browser source workflow [#browser-source-workflow]

When `POST /api/generate` cannot express the artifact, open the matching Studio tool and use `window.glyphfield.studio`. Use `readSource` and `applySource` for exact documents, and use `controls`, `activate` and `set` for visible operations. Source stays readable while the tool is active, whether or not the source drawer is open. The source drawer (**File** → **Edit source code**) shows the same document to a person.

Do not send a Studio source document to `POST /api/generate`. A source document is the browser-local state of one open tool, and the generation route has its own versioned contract. Only a `design-sequence` response contains an apply-ready `document`. See [Browser-agent workflow](/docs/agents/browser-workflow), [Source code editing](/docs/studio/source-editing) and [Source format reference](/docs/reference/source-formats).
