Inspiration
Influencer marketing is a $32.5 billion industry growing at 33% annually — and the #1 investment priority for marketers in 2026 is AI-powered creator matching. Yet most campaign tools still treat the agent and the human as two separate systems: the agent guesses through a UI, the human reviews a report afterward, out of context and too late to change anything.
Influencer campaigns have a split-second problem: the agent that's fast enough to search hundreds of creators and score them against policy is the same agent you don't trust to commit ¥12,000,000 without asking. We built Campaign Arena to close that gap — not by slowing the agent down, but by giving it a shared workspace where both agent and person operate on the same live page.
What it does
Campaign Arena is a KOC (Key Opinion Consumer) campaign workspace where an AI agent and a human operator work side-by-side through four WebMCP Site tools:
searchKOCs(platform?, category?)— filters the creator roster and updates the dashboard KOC grid in real timeproposeDeliverable(kocKey)— proposes a deal; auto-confirms if safe, or blocks until the human decides if a policy violation is detectedgetTrustScore()— returns the current AEGIS trust score, autonomy tier, and factor breakdownendSession()— closes the session, locks all mutations, and writes the final trust report
A policy engine enforces five rules: blacklist, platform allowlist, campaign budget ceiling (hard limit), split-deal detection, and single-deal approval threshold. An AEGIS trust score tracks the agent's behavior across the session — LOW, MEDIUM, and HIGH autonomy tiers control how much the agent can auto-confirm without asking.
Every event — proposed, blocked, rejected, corrected, confirmed — is recorded in order in the Session Ledger. After a rejection, the agent suggests a policy-safe alternative. That suggestion is a nudge, not an automatic commit.
How we built it
Single HTML page using React 18 (via CDN) and JSX compiled to vanilla JS at build time — no framework build chain, no server. All WebMCP tools are registered with document.modelContext.registerTool directly in the top-level page. The production build strips runtime Babel using esbuild and is served as a fully static site on Vercel.
The core of proposeDeliverable is a Promise-based human-in-the-loop gate: waitForDecision(kocKey) stores a resolver in a Map. The tool awaits that Promise. The human's Approve or Reject button resolves it — and only then does the tool return its result to the agent. ChatGPT is correctly suspended while the dialog is open and cannot proceed until the person has acted.
Challenges we ran into
Making the approval flow genuinely transactional was the hardest part. The tool result must be truthful about what happened — not what was intended — so the agent's next action is always correct.
Concurrency edge cases required the most attention: double-clicking Approve or Reject, closing the session while a simulation is mid-flight, an orphaned Promise resolver when an intermediate await throws. Each of these could silently corrupt the ledger or committed spend. We addressed them with synchronous instance flags and careful finally cleanup — the part that took longest to get right.
The policy engine also required precision: split-deal detection depends on cumulative confirmed spend across proposals, which must account for prior session history to trigger correctly.
Accomplishments that we're proud of
The proposeDeliverable tool genuinely blocks as a Promise until the human decides. This means the agent's next tool call is always based on the real outcome. Agents using Campaign Arena cannot accidentally double-spend, propose the same creator twice, or close the session while a decision is pending — these return bounded error objects instead of hanging or corrupting state.
The shared-page model is the real accomplishment: the agent does not guess through visual controls, and the person never loses context or authority. Both see the same ledger, the same trust score, the same mission progress — in real time.
What we learned
Designing for agents and people simultaneously forces contract clarity that is easy to skip in ordinary apps. Every tool needs a precise description, strict input schema (additionalProperties: false, enum for allowed values), and a result that accurately reflects state — not just the happy path.
We also learned that the shared-page model is fundamentally different from building an API. The tool and the UI must stay in sync: what the ledger shows and what the tool returns must always agree. Getting that right is a design problem as much as an engineering one.
What's next for Campaign Arena
- Persistent session ledger so campaigns survive a reload
- Multi-agent support: a planning agent hands deals to an execution agent, with the human overseeing both
- Audit export: the session ledger as a signed, timestamped record for compliance review
- Expanded policy rules: geo restrictions, budget pacing, and creator exclusivity windows
Built With
- css
- html
- javascript
- react
- vercel
- webmcp
Log in or sign up for Devpost to join the conversation.