Next Step Finisher is a cross-platform tool designed to eliminate the repetitive operational work that follows meetings, approvals, and client interactions — especially within advertising agency workflows. After campaign approvals, insertion orders, scope changes, or performance reviews, agencies face predictable follow-up tasks like updating CRM fields, generating IOs and SOWs, preparing billing packets, renaming assets, and logging activity across multiple systems. Next Step Finisher automates that mechanical layer.
- Multi-chat interface with create/select/delete chat
- Real-time messaging over WebSocket
- Long-lived Claude agent session per chat
- File attachments with upload + agent processing
- Tool-use visibility in the UI (
Read,Write,Edit,Bash,Grep,Glob,WebSearch,WebFetch,Skill) - Download links for agent-generated files from
/api/files/output/... - Project-level Claude skills enabled from
.claude/skills - Google OAuth authentication with JWT sessions
- Team management: invite members by email, assign roles (admin/member), track invite status
- Frontend: React 18, TypeScript, Vite, Tailwind CSS
- Backend: Node.js, Express,
ws,multer - Agent runtime:
@anthropic-ai/claude-agent-sdk - Database: Prisma ORM + SQLite
- Frontend loads chats via REST (
/api/chats) and subscribes to a chat over WebSocket (/ws). - User messages (and optional uploaded files) are sent to the server.
- Server persists chats and messages to SQLite via Prisma and forwards content to a per-chat
AgentSession. - Agent output streams back as assistant messages, tool-use events, and final result events.
- Generated files saved under
/tmp/uploads/outputare served at/api/files/output/....
- Node.js 18+
- Anthropic API key (
ANTHROPIC_API_KEY) - Google OAuth credentials (
GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET) — required for production login; dev auto-login is available viaPOST /api/auth/dev - Resend API key (
RESEND_API_KEY) — optional; invitation emails are skipped when absent
npm install
cp .env.example .envSet your keys in .env:
ANTHROPIC_API_KEY=your_key_here
PORT=3001
DATABASE_URL=file:./prisma/dev.dbStart development:
npm run dev- Frontend:
http://localhost:5173 - Backend API + WebSocket:
http://localhost:3001andws://localhost:3001/ws
Build the frontend and run the server:
npm run build
npm startThe server serves both API/WebSocket and built frontend from dist/.
npm run dev: Run client and server concurrentlynpm run dev:client: Start Vite dev server on port 5173npm run dev:server: Start backend withtsx watchnpm run build: Build frontend todist/npm start: Run backend in production mode
Auth:
POST /api/auth/dev: Dev auto-login (development only)GET /api/auth/google: Redirect to Google OAuthGET /api/auth/google/callback: OAuth callback — returns JWT via redirectGET /api/auth/me: Get current user (requiresAuthorization: Bearer <token>)
Chats:
GET /api/chats: List chatsPOST /api/chats: Create chatGET /api/chats/:id: Get chatDELETE /api/chats/:id: Delete chatGET /api/chats/:id/messages: List messagesPOST /api/upload: Upload a file (multipart/form-data, field name:file)
Team (all require auth):
GET /api/team: Current user's team + membersPOST /api/team/invite: Invite by email (admin only)PUT /api/team/members/:id/role: Change role —adminormember(admin only)DELETE /api/team/members/:id: Remove member (admin only)POST /api/team/members/:id/resend-invite: Resend invitation email (admin only)
Client -> server:
{ "type": "subscribe", "chatId": "..." }{ "type": "chat", "chatId": "...", "content": "...", "attachments": [...] }
Server -> client:
connectedhistoryuser_messageassistant_messagetool_useresulterror
- Max file size: 10 MB per file
- Allowed file types:
- Images: PNG, JPEG, GIF, WEBP
- Documents: PDF, DOCX, XLSX
- Text: TXT, HTML, CSS, JS, Markdown, CSV, JSON
- DOCX/XLSX files are written to
/tmp/uploads/...for tool-based processing - Downloadable outputs should be written to
/tmp/uploads/output/and linked as:[Download file](/api/files/output/filename.ext)
Project skills are enabled with settingSources: ["project"] and include:
.claude/skills/generating-insertion-order- Triggered for insertion order generation requests
- Uses a user-provided XLSX template and fills it via
exceljs
client/
App.tsx
components/
ChatList.tsx
ChatWindow.tsx
server/
server.ts
session.ts
ai-client.ts
chat-store.ts
file-store.ts
types.ts
.claude/skills/
SOUL.md
- No persistent agent transcript/session recovery across restarts
- Single-process runtime (no horizontal session coordination)
railway.json is included and uses:
- Build:
npm install --include=dev && npm run build - Start:
npm start