Skip to main content

A chatbot that only answers questions is half an agent. Attach a governed Tool and it can act — file a ticket, update a record — but only for people who are actually allowed to, with a graceful fallback for everyone else instead of a hard failure.

Agentplan → retrieve → act
Glean retrievalgrounded in the index
Custom toolgoverned write action
Agent builder access in your Glean instance
Permission to register a custom tool (or admin help)
A work email for tenant discovery and OAuth sign-in; an AGENTS-scoped API token is the fallback
uv and cloudflared installed locally
Your own email, to put on (and take off) the tool server's allow-list between the two runs
1

Scaffold the project

npx -y tiged@2.12.8 --mode=git gleanwork/glean-cookbook/recipes/multi-step-agent multi-step-agent
2

Set the tool server's allow-list

Set AUTHORIZED_EMAILS to your own email for the first run. You'll remove it for the second run to see the denied branch — changing the allow-list is how both governance paths get demonstrated, since the agent always runs as you. The server refuses to start on an empty allow-list, since that denies everyone and makes the permitted branch unobservable.

(cd multi-step-agent/tool-server && cp .env.example .env)
3

Run the tool server

Listens on port 8080. Keep this running in its own terminal — the agent calls it over HTTP once registered.

(cd multi-step-agent/tool-server && uv run server.py)
4

Expose the demo tool over HTTPS

Keep this running in a second terminal. Copy the printed https://<random>.trycloudflare.com origin into tool-server/openapi.yaml as servers[0].url, with no path. Confirm that <origin>/file_incident_ticket returns the expected 403 for a denied email. This public demo route accepts a spoofable identity header and only creates fake in-memory tickets; authenticate requests from Glean before connecting a real write action.

cloudflared tunnel --url http://localhost:8080
5

Register the tool

Manual, UI-only step. After replacing the OpenAPI placeholder with the tunnel origin, use Admin > Platform > Tools > Add and upload multi-step-agent/tool-server/openapi.yaml. The operation URL must be <origin>/file_incident_ticket.

6

Create the agent

Manual, UI-only step. In Agent Builder: paste the recipe's instructions, turn retrieval on, attach the tool you just registered. Copy the agent's ID for the next step.

7

Set credentials

Use the shipped login flow, then set GLEAN_AGENT_ID from the agent created above. Never implement authentication.

(cd multi-step-agent/invoke-agent && node scripts/glean-auth.mjs login --scopes agents --email "<work-email>")
8

Run it

Dependencies are declared inline (PEP 723) and locked, so uv installs them into an isolated environment on first run — no requirements.txt, venv, or activate step.

(cd multi-step-agent/invoke-agent && uv run main.py)
9

Verify

With your email on the allow-list, confirm the ticket actually gets filed. Then restart the tool server without it and confirm the agent produces a read-only fallback summary instead of a hard failure.

Take it further
  • Add a second governed tool (e.g., escalate to PagerDuty) and let the agent choose between them based on severity.
  • Switch to run_stream() and parse the SSE text yourself for a live-updating UI.
  • Combine with permissions-aware-retrieval's retrieval pattern if you want the agent's grounding to come from your own index instead of Glean's default retrieval.

Summarize our open incidents and file a tracking ticket

With your email on the tool server's allow-list: the agent summarizes and the demo tool call succeeds (200, a fake in-memory ticket id). With it removed: the tool returns 403 and the agent falls back to a read-only summary rather than failing the run. The allow-list demonstrates authorization logic; authenticate requests from Glean before connecting a real write action.

View source

Runs the recipe through the Glean cookbook plugin.

Auth

Run the authenticate step on this page. It discovers your tenant from work email and signs you in with OAuth, using the shipped login command. If OAuth is unavailable, create a scoped Glean-issued token in Token Management (AGENTS).

At a glance
SurfacesAgents, Tools
StatusProduction pattern
Time~2 hr
Required scopes
AGENTSTOOLS