Skip to content
Projects
AI inside4 min read

X Engagement Agent (POC)

A human-approval-gated dashboard for an AI-assisted X (Twitter) engagement agent that finds relevant tweets and drafts replies, but can never publish anything itself; built as a proof of concept with the X and Claude integrations mocked.

Role
Sole engineer
Year
2026
Status
prototype
AIagentssocial-mediadashboardhuman-in-the-loopsafety

// AI capabilities

  • Mocked drafting engine that generates reply and original-post drafts from templated content, standing in for a real Claude integration
  • Natural-language chatbox that can draft, change tone, or pause the agent, but hard-refuses any phrasing that asks it to skip approval or auto-post
  • Designed wiring path for a real LLM: a system prompt built from a project-level voice/brand spec file, plus an automated content filter that screens every generated draft before a human sees it

Overview

A proof-of-concept web dashboard for an AI-assisted X (Twitter) engagement agent. It watches for relevant tweets, drafts replies and original posts, and puts every draft into an approval queue where a human must approve, edit, or reject it before anything goes out. Built solo end to end: a Node.js/Express/SQLite backend and a React/Vite dashboard, with JWT auth and a granular per-user permission model. In this POC the X and Claude integrations are mocked (fake authors, fake tweets, templated draft text) so the full workflow can be demoed with no external API calls or credentials.

Problem

Teams that want AI to speed up social-media monitoring and drafting face an asymmetric risk: a single wrong auto-posted tweet can be reputationally serious, especially for accounts representing a person or brand publicly. The system needed to prove that an agent can do the discovery-and-drafting work end to end while making it structurally impossible for it to publish on its own, not just discouraged by a setting.

Approach

Design started from the safety model rather than the feature list. A single function is the only code path allowed to call the platform's post endpoint, and it runs five sequential checks that all must pass before anything goes out: the agent must not be paused, a global kill switch must be off, the draft must be explicitly marked approved by a real user, that approver's account must still exist, and only then is the post call made. Every other feature (search, drafting, the approval queue, notifications, activity log, analytics) was built around that constraint. The X and Claude clients are mocked in this POC: fake authors and tweets, template-based fake reply and original-post drafts, and a pattern-matched chatbox, so the entire workflow demoes safely before any real API keys are wired in.

Architecture

  • Node.js/Express backend with better-sqlite3 (a SQLite database that is auto-created and auto-seeded with mock data), JWT auth, bcrypt password hashing, and node-cron for the scheduled agent cycle
  • React 18 + Vite + Tailwind + framer-motion dashboard (mobile-first), talking to the backend through an axios client with a JWT interceptor
  • server/scheduler.js runs the mock "search for tweets, then draft" cycle on a timer and is the only place that gates publishing through the five-layer check
  • server/mock-clients.js stands in for the X and Claude APIs: fake authors, fake tweets, reply and original-post templates, and a pattern-matched chatbox that can create drafts but has no code path to approve or post
  • Permission middleware on the backend (returns 403 and logs the attempt) paired with route guards and hidden UI on the frontend, so enforcement is not a purely cosmetic frontend concern
  • A dedicated security module adds account lockout after repeated failed logins, login-specific rate limiting, a login-attempt audit log, and brute-force alerting, on top of helmet security headers and locked-down CORS

AI work

  • Mock "drafting brain" that produces reply and original-tweet drafts from templated content, in place of a real Anthropic API call
  • AI chatbox in the dashboard that pattern-matches natural-language requests ("draft something about X", "change the tone", "pause the agent") and performs the corresponding safe action
  • Explicit refusal logic: any message asking the chatbox to auto-post, skip approval, or bypass the queue is intercepted and declined before normal intent-matching runs
  • A designed (documented in code) path for wiring in a real LLM: a system prompt assembled from a project-level voice/brand specification file, plus a post-generation content filter intended to run on every draft before a human ever sees it

Engineering highlights

  • Human-in-the-loop by construction: only one function can call the publish endpoint, and it enforces five sequential defense layers (agent running, kill switch off, draft approved with an approver on record, approver still exists, then the API call)
  • Global kill switch in the Settings page that blocks publishing instantly, even for drafts that are already approved
  • JWT auth with a granular, per-user permission model; the admin role holds every permission, and other users default to read-only until an admin explicitly grants more
  • Defense in depth on permissions: backend middleware returns 403 and logs denied attempts, while the frontend independently hides UI for actions a user cannot perform
  • Full activity log: every approval, rejection, edit, settings change, permission change, login, logout, and kill-switch toggle is recorded with a user id and timestamp
  • An account-security layer separate from the posting safety model: login rate limiting, lockout after repeated failed attempts, and brute-force alerting

Status

Proof of concept: auth, permissions, the approval queue, activity log, notifications, and analytics all run against a real local SQLite database, but the X and Claude integrations are mocked (fake tweets, fake authors, templated drafts, no live API calls or credentials), so the workflow can be demoed safely before any real API keys are connected.

Want to dig deeper?

Ask my AI agent anything about how this was built, what tradeoffs I made, or how it could fit your team.

Ask my AI →