HomeDocsB2B2C-Agent Prompt

B2B2C Coding-Agent Prompt

Paste everything between the markers into Claude Code (or another coding agent) when you want it to build a B2B2C agent on Agentic Fabriq — i.e. your product has its own end users, AF is invisible to them, and your backend mints per-end-user AF tokens. For a single-user/internal agent, use the General Agent Prompt instead.

Open your codebase in the coding agent and paste everything between the ===== PROMPT START ===== and ===== PROMPT END ===== markers below as a single message.

===== PROMPT START =====

You are integrating Agentic Fabriq (AF) into this codebase to build a B2B2C
agent: this product has its own end users, those users do not have AF
accounts, and the backend mints a per-end-user AF token to act on each
user's behalf. Your job is to set this up correctly the first time — including
the part that lets each end user connect their own tools, not just the part that
calls them.

Source of truth

The authoritative references live on the public docs site:
https://www.agenticfabriq.com/docs. The full docs are also published as plain
text for agents at https://www.agenticfabriq.com/llms-full.txt — fetch that to
read any section reliably. Open these sections (by title) and read them before
writing anything:

Build an Agent with AF — the SDK + auth patterns. For B2B2C, the
structural template is the token method and its B2B2C example: the
two-step token mint and per-user token caching.
External Users (B2B2C) — the lifecycle: enabling B2B2C on the app,
creating external users, onboarding their tool connections via OAuth,
listing/disconnecting/deleting connections, the seller-domain callback. (Also
see External Facing Agents Setup Guide if present.)
MCP Client Setup Guide and Token Broker Guide — connection and auth
specifics.
The human docs site at /docs is a single-page app and may return an empty shell
to a plain fetch, so prefer llms-full.txt. If you still cannot read a section,
stop and ask the user to paste that section's text rather than guessing API
shapes or endpoint paths.

Conform to them exactly:

Use from af_sdk import MCPClient — do not invent alternate import paths.
Use method="token" for the agent's MCP calls. The per-user AF token is
minted at runtime, never read from a static secret.
Do not hardcode gateway, MCP, or Keycloak URLs. Always read from env.
Do not invent tool names. Confirm them against client.list_tools() output
for a specific connected external user, or ask the user.

How B2B2C actually works (build to this model — get it right)

Two identities, two tokens. Your backend holds the app credentials. It
first gets an app service token (POST /api/v1/applications/token with
{app_id, secret_key}), then mints a per-external-user token
(POST /api/v1/apps/{app_id}/external-users/{external_user_id}/token with that
bearer). MCP calls use the per-user token, never the app token.
End users must connect their tools first. A brand-new external user has
zero connections, so tools/list returns nothing until they connect
something. You must build (or confirm there already exists) an onboarding flow:
create the external user -> initiate OAuth per provider
(.../external-users/{id}/oauth/{provider}/initiate) -> handle the callback on
the seller's domain -> list connections. Do not assume connections exist.
tools/list is per-external-user. It returns only what that user has
connected and is authorized for. The agent must handle the empty /
not_connected / auth_expired states gracefully and surface a "connect your
tools" path rather than erroring out.
The app secret stays on the backend. End users never see AF; never ship
AF_APP_SECRET or the app token to a client; never expose AF tokens in URLs or
logs.
Mint per request/session, cache per (external_user_id, expiry). Do not
set one user's token in env and reuse it for everyone.

Env-var contract

Use exactly these names. App-level secrets are backend-only.

AF_GATEWAY_URL, AF_MCP_URL — AF endpoints (from env, never hardcoded)
AF_APP_ID, AF_APP_SECRET — app credentials (backend only; never to client)
EXTERNAL_USER_ID — convenience for local single-user testing only; in
production this is a per-request value, not a static secret
Loop/backoff (if a long-running shape): LOG_LEVEL, TICK_SECONDS,
TOOL_RETRY_ATTEMPTS, INITIAL_BACKOFF_SECONDS, MAX_BACKOFF_SECONDS,
MAX_TOOL_BACKOFF_SECONDS, AUTH_BACKOFF_SECONDS, RECONNECT_BACKOFF_SECONDS
Do not introduce an AF_USER_TOKEN env var — the per-user token is minted,
not configured.

Hard rules

Never commit secrets. Don't write AF_APP_SECRET or any token value into a
tracked file. If you create .env, ensure .env is in .gitignore.
Never bake secrets into Docker images, CI configs, or .env.example.
.env.example holds key names only, with blank/placeholder values.
Don't run pip install or any side-effecting command without asking first.
Propose, wait for approval, then run.
Don't generate fake values for AF_APP_ID, AF_APP_SECRET, redirect URIs, or
external user IDs. Use placeholders the user will fill, or stop and ask.
Don't modify the user's AF app config or auth-provider settings yourself —
surface what they must change (B2B2C enablement, callback URL, scopes).
If the guide conflicts with existing code, surface the conflict; don't silently
overwrite.

Step 1 — Discover the user's setup

Ask all of these in one numbered message; wait for answers before continuing.

App registration (B2B2C prerequisite). Is your AF app already registered
with B2B2C mode enabled (Growth plan or above), with a callback URL on
your domain and the provider scopes your users will connect (e.g. Gmail,
Slack)? If not, you'll need to do that first — I can't mint per-user tokens
until B2B2C is enabled.
Connection onboarding. Does your product already have a flow for end users
to connect their tools (the per-provider OAuth initiate + callback), or
should I scaffold it (create external user -> initiate OAuth -> handle callback
-> list connections)?
Backend stack — FastAPI, Flask, Django, Express, other? (Token minting +
the OAuth callback live here.)
Frontend stack — React/Vite, Next.js, plain HTML, or backend-only? (Where
end users trigger "connect a tool.")
Agent shape — one-shot per request, long-running loop, or a
request-driven service handler invoked per end user?
Runtime target — local, generic Docker, Cloud Run, GKE/K8s, Lambda,
other?
Secret loading in prod — plain env, GCP Secret Manager, AWS Secrets
Manager, Vault, K8s Secret, or "local .env for now"?
First tools — which AF tool(s) should the agent call first once a user has
connected (e.g. google_gmail_list_messages)? If unsure, say "list them for a
connected user and I'll pick."
Where should the code live — a path (e.g. services/agent/) or "you
choose."

Step 2 — Confirm the plan

Once you have answers, respond with:

Here's what I'll do:

Files I'll add: <list, one-line purpose each — must include: token-mint helper (app token -> per-user token, cached), the MCP client call path, and (if scaffolding) the external-user create + OAuth-initiate + callback handlers>

Files I'll modify: <list with changes>

Dependencies I'll add: <list with versions>

Env vars the user must set (go in .env.example, blank): <list>

External setup the user must do (I won't touch):

Enable B2B2C mode on the AF app (Growth plan), set the callback URL,
select provider scopes — if not already done (Q1)
Register the OAuth callback/redirect URL for each environment
Create secret-manager entries for AF_APP_SECRET
I'll follow the B2B2C (token) example from the Build an Agent with AF
guide as the structural template, plus the external-user + connection endpoints
from the External Users (B2B2C) guide.

OK to proceed?
Write no files until the user approves. If they request changes, revise and
re-confirm.

Step 3 — Implement

Mint tokens server-side: a helper that gets the app token, then the per-user
token, and caches per (external_user_id, expiry). Never expose either to
the client.
Use MCPClient(method="token", af_token=<minted per-user token>, ...). Read all
URLs/IDs from env at use sites, not module init.
If onboarding doesn't already exist (Q2), scaffold it: an endpoint to create an
external user, an endpoint to start OAuth for a provider, and the callback
handler on the seller domain — following the B2B2C guide's shapes.
Handle the not-connected path: if list_tools() is empty or a call returns
not_connected / auth_expired, return a clear "this user needs to connect
<provider>" response, not a 500.
Error handling per the guide: catch AuthenticationError,
MCPConnectionError, MCPError at the right layers; for loops, outer
try/except for auth/connection, inner retry for MCPError.
.env.example with every var (blank + one-line comment). Add a RUN.md:
install, env checklist, how to run, how to verify.
Match existing tooling (Poetry vs pip) and style. If containerized, add the
Dockerfile / deployment manifest from the guide, secret-bearing fields blank.

Step 4 — Show how to run and verify

Done. To run this:

Set env vars: <shell block; secrets as 'fill_me_in'>
Enable B2B2C on the app + register the callback URL (if not done).
Create a test external user and connect one tool via the onboarding flow.
Run: <exact command>
You should see: <for the connected user, "N tools available" and a successful
call>. For a brand-new user with no connections, you should see the
"connect your tools" path, not an error.

Things I did NOT do (you need to): <B2B2C enablement, callback registration,
secret-manager entries>

Step 5 — Stay honest

If you couldn't find a guide, say so; don't guess API shapes.
If something isn't covered by the guides, say "the guide doesn't cover that;
here's what I'd do and why."
Flag your own choices (framework, layout) so the user can override.
If a step fails when you run it, report the actual error verbatim. Never claim
success without evidence — especially "tools are listed," which is meaningless
until a real external user has connected something.

Defaults if the user says "you decide"

Async over sync; method="token" (this is B2B2C).
Per-request token minting with (external_user_id, expiry) caching.
Request-driven service shape (the agent runs per end-user request), unless the
user clearly wants a one-shot or a loop.
Scaffold the onboarding flow if the user can't confirm one already exists.
Generic Docker target if production matters but no platform is named; GCP
Secret Manager if the repo shows GCP signs, K8s Secret if there's k8s/ or
helm/, else local .env.
Place code under services/agent/ (or agent/ if the repo is flat).

===== PROMPT END =====

Need help?

Our team is here to help you get started.