better-chatbot

from jackspace/claudeskillz

ClaudeSkillz: For when you need skills, but lazier

8 stars2 forksUpdated Nov 20, 2025
npx skills add https://github.com/jackspace/claudeskillz --skill better-chatbot

SKILL.md

better-chatbot Contribution & Standards Skill

Status: Production Ready Last Updated: 2025-11-04 (v2.1.0 - Added extension points + UX patterns) Dependencies: None (references better-chatbot project) Latest Versions: Next.js 15.3.2, Vercel AI SDK 5.0.82, Better Auth 1.3.34, Drizzle ORM 0.41.0


Overview

better-chatbot is an open-source AI chatbot platform for individuals and teams, built with Next.js 15 and Vercel AI SDK v5. It combines multi-model AI support (OpenAI, Anthropic, Google, xAI, Ollama, OpenRouter) with advanced features like MCP (Model Context Protocol) tool integration, visual workflow builder, realtime voice assistant, and team collaboration.

This skill teaches Claude the project-specific conventions and patterns used in better-chatbot to ensure contributions follow established standards and avoid common pitfalls.


Project Architecture

Directory Structure

better-chatbot/
├── src/
│   ├── app/                    # Next.js App Router + API routes
│   │   ├── api/[resource]/     # RESTful API organized by domain
│   │   ├── (auth)/             # Auth route group
│   │   ├── (chat)/             # Chat UI route group
│   │   └── store/              # Zustand stores
│   ├── components/             # UI components by domain
│   │   ├── layouts/
│   │   ├── agent/
│   │   ├── chat/
│   │   └── export/
│   ├── lib/                    # Core logic and utilities
│   │   ├── action-utils.ts     # Server action validators (CRITICAL)
│   │   ├── ai/                 # AI integration (models, tools, MCP, speech)
│   │   ├── db/                 # Database (Drizzle ORM + repositories)
│   │   ├── validations/        # Zod schemas
│   │   └── [domain]/           # Domain-specific helpers
│   ├── hooks/                  # Custom React hooks
│   │   ├── queries/            # Data fetching hooks
│   │   └── use-*.ts
│   └── types/                  # TypeScript types by domain
├── tests/                      # E2E tests (Playwright)
├── docs/                       # Setup guides and tips
├── docker/                     # Docker configs
└── drizzle/                    # Database migrations

API Architecture & Design Patterns

Route Structure Philosophy

Convention: RESTful resources with Next.js App Router conventions

/api/[resource]/route.ts         → GET/POST collection endpoints
/api/[resource]/[id]/route.ts    → GET/PUT/DELETE item endpoints
/api/[resource]/actions.ts       → Server actions (mutations)

Standard Route Handler Pattern

Location: src/app/api/

Template structure:

export async function POST(request: Request) {
  try {
    // 1. Parse and validate request body with Zod
    const json = await request.json();
    const parsed = zodSchema.parse(json);

    // 2. Check authentication
    const session = await getSession();
    if (!session?.user.id) return new Response("Unauthorized", { status: 401 });

    // 3. Check authorization (ownership/permissions)
    if (resource.userId !== session.user.id) return new Response("Forbidden", { status: 403 });

    // 4. Load/compose dependencies (tools, context, etc.)
    const tools = await loadMcpTools({ mentions, allowedMcpServers });

    // 5. Execute with streaming if applicable
    const stream = createUIMessageStream({ execute: async ({ writer }) => { ... } });

    // 6. Return response
    return createUIMessageStreamResponse({ stream });
  } catch (error) {
    logger.error(error);
    return Response.json({ message: error.message }, { status: 500 });
  }
}

Shared Business Logic Pattern

Key Insight: Extract complex orchestration logic into shared utilities

Example: src/app/api/chat/shared.chat.ts

This file demonstrates how to handle:

  • Tool loading (loadMcpTools, loadWorkFlowTools, loadAppDefaultTools)
  • Filtering and composition (filterMCPToolsByMentions, excludeToolExecution)
  • System prompt building (mergeSystemPrompt)
  • Manual tool execution handling

Pattern:

// Shared utility function
export const loadMcpTools = (opt?) =>
  safe(() => mcpClientsManager.tools())
    .map((tools) => {
      if (opt?.mentions?.length) {
        return filterMCPToolsByMentions(tools, opt.mentions);
      }
      return filterMCPToolsByAllowedMCPServers(tools, opt?.allowedMcpServers);
    })
    .orElse({} as Record<string, VercelAIMcpTool>);

// Used in multiple routes
// - /api/chat/route.ts
// - /api/chat/temporary/route.ts
// - /api/workflow/[id]/execute/route.ts

Why: DRY principle, single source of truth, consistent behavior

Defensive Programming with safe()

Library: ts-safe for functional error handling

Philosophy: Never crash the chat - degrade features gracefully

// Returns empty object on failure, chat continues
const MCP_TOOLS = await safe()
  .map(errorIf(() => !isToolCallAllowed && "Not allowed"))
  .map(() => loadMcpTools({ mentions, allowedMcpServers })

...
Read full content

Repository Stats

Stars8
Forks2
LicenseMIT License