Skip to main content
Glama

init_hive

Initialize a new knowledge base project for storing debugging solutions and reusable skills, with guided setup for storage options and project structure.

Instructions

Create a new project hive (knowledge base). TRIGGERS: 'create a new hive', 'start a hive', 'initialize hive'. Onboarding flow: First call checks if user ever used Hivemind before. If first time, asks 'Is this your first time using Claude Code?' If yes, creates CLAUDE.md with starter config. Then guides through storage choice (cloud/local). If no project_path provided, creates empty hive with starter categories. IMPORTANT: Display the 'message' field to the user EXACTLY as returned - do not condense, reformat, or summarize it.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
project_idYesProject identifier (e.g., from package.json name or directory)
project_nameYesHuman-readable project name
is_first_time_userNoAnswer to 'Is this your first time using Claude Code?' (only used when onboarding flag not set)
storage_choiceNoUser's storage choice (omit on first call to get options)
project_pathNoOptional: Absolute path to project directory (for scanning). If not provided, creates empty hive with starter categories only.

Implementation Reference

  • src/index.ts:218-250 (registration)
    Registration of the 'init_hive' tool in the ListToolsRequestHandler, defining name, description, and input schema.
    { name: "init_hive", description: "Create a new project hive (knowledge base). TRIGGERS: 'create a new hive', 'start a hive', 'initialize hive'. Onboarding flow: First call checks if user ever used Hivemind before. If first time, asks 'Is this your first time using Claude Code?' If yes, creates CLAUDE.md with starter config. Then guides through storage choice (cloud/local). If no project_path provided, creates empty hive with starter categories. IMPORTANT: Display the 'message' field to the user EXACTLY as returned - do not condense, reformat, or summarize it.", inputSchema: { type: "object", properties: { project_id: { type: "string", description: "Project identifier (e.g., from package.json name or directory)", }, project_name: { type: "string", description: "Human-readable project name", }, is_first_time_user: { type: "boolean", description: "Answer to 'Is this your first time using Claude Code?' (only used when onboarding flag not set)", }, storage_choice: { type: "string", enum: ["cloud", "local"], description: "User's storage choice (omit on first call to get options)", }, project_path: { type: "string", description: "Optional: Absolute path to project directory (for scanning). If not provided, creates empty hive with starter categories only.", }, }, required: ["project_id", "project_name"], }, }, {
  • Dispatch case in CallToolRequestHandler that invokes the initHive function with parsed arguments and returns JSON response.
    case "init_hive": { const result = await initHive( args?.project_id as string, args?.project_name as string, args?.storage_choice as 'cloud' | 'local' | undefined, args?.project_path as string | undefined, args?.is_first_time_user as boolean | undefined ); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }], }; }
  • Core implementation of initHive tool. Handles guided onboarding flow: detects first-time users, creates config files, chooses storage (cloud/local), scans project for tech stack/architecture/database/etc., auto-contributes foundational knowledge entries, adds starter guides and categories to the hive.
    export async function initHive( projectId: string, projectName: string, storageChoice?: 'cloud' | 'local', projectPath?: string, isFirstTimeUser?: boolean ): Promise<InitHiveResult> { // Step 0: Check onboarding flag const hasOnboarded = await checkOnboardingFlag(); if (!hasOnboarded && isFirstTimeUser === undefined) { // First time ever - ask if they're new to Claude Code return { step: 'ask_first_time', message: 'Welcome to Hivemind! Quick question: Is this your first time using Claude Code?', options: { yes: 'Yes, I\'m new to Claude Code (I\'ll help you get set up)', no: 'No, I\'ve used Claude Code before (skip setup)' } }; } // If they answered the first time question, handle CLAUDE.md creation if (!hasOnboarded && isFirstTimeUser !== undefined) { if (isFirstTimeUser) { // Create CLAUDE.md for new users await createClaudeMD(); } // Mark as onboarded regardless of answer await createOnboardingFlag(); // Continue to storage choice (don't return early) } // Step 1: No choice yet, return options (always cloud by default for new users) if (!storageChoice) { return { step: 'ask_storage', message: 'Choose storage type for your project hive:', options: { cloud: '10x limits (1000/hour) + syncs wherever you go + helps everyone (RECOMMENDED)', local: '100/hour + stays on this computer only + fully private' } }; } // Step 2: User chose, initialize let result; if (storageChoice === 'local') { // Create local .hive.json file const userId = `local-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; if (projectPath) { await createLocalHive(projectPath, projectId, projectName, userId); } result = { user_id: userId, project_id: projectId, project_name: projectName }; } else { // Use cloud storage (Supabase) result = await initProjectKB(projectId, projectName, storageChoice); } let scannedEntries = 0; let scanResult: ProjectScanResult | undefined; // Step 3a: If no project path, create empty hive with starter categories if (!projectPath && result.user_id) { scannedEntries = await createStarterCategories(result.user_id, projectId, projectName); const storageLocation = storageChoice === 'cloud' ? 'Supabase cloud database (ksethrexopllfhyrxlrb.supabase.co)' : 'Supabase cloud database (ksethrexopllfhyrxlrb.supabase.co)'; const statusMessage = `Empty hive created with ${scannedEntries} starter category guides. User ID: ${result.user_id} (save this)`; const nextStepsMessage = `Your hive is ready! When you're working on an actual project: 1. **Open Claude Code in your project folder** 2. **Say: "scan my hive"** - I'll detect your tech stack and populate your hive For now, try these: **See what's in your hive:** Say: "show me my hive" **Search for help:** Say: "search my hive for how to use" **Add your first entry:** Say: "add to hive" - I'll walk you through it --- **What would you like to work on today?** - Research a topic - Build a feature - Debug an issue - Learn something new Just tell me what you need.`; return { step: 'confirm_setup', message: `${statusMessage}\n\n${nextStepsMessage}`, user_id: result.user_id, project_id: result.project_id, storage_type: storageChoice, scanned_entries: scannedEntries, _ctx: "SEARCH FIRST, CODE SECOND. HIVE = PROJECT BRAIN: Contains YOUR proven approaches, not generic answers." }; } // Step 3b: Scan project and auto-contribute base knowledge if (projectPath && result.user_id) { try { scanResult = await scanProject(projectPath); // Contribute project overview const overviewParts = []; if (scanResult.description) overviewParts.push(scanResult.description); if (scanResult.version) overviewParts.push(`Version: ${scanResult.version}`); if (scanResult.tech_stack.length > 0) overviewParts.push(`Tech: ${scanResult.tech_stack.join(', ')}`); if (scanResult.database) overviewParts.push(`Database: ${scanResult.database}`); if (overviewParts.length > 0) { await contributeProject( result.user_id, projectId, `What is ${projectName}? Give me a project overview.`, overviewParts.join('. '), 'project-overview', false, projectPath ); scannedEntries++; } // Contribute tech stack if (scanResult.tech_stack.length > 0) { await contributeProject( result.user_id, projectId, `What is the tech stack for ${projectName}?`, `Tech stack: ${scanResult.tech_stack.join(', ')}`, 'tech-stack', false, projectPath ); scannedEntries++; } // Contribute architecture if (scanResult.architecture.length > 0) { await contributeProject( result.user_id, projectId, `What is the architecture of ${projectName}?`, `Architecture: ${scanResult.architecture.join(', ')}`, 'architecture', false, projectPath ); scannedEntries++; } // Contribute database info if (scanResult.database) { await contributeProject( result.user_id, projectId, `What database does ${projectName} use?`, `Database: ${scanResult.database}`, 'database', false, projectPath ); scannedEntries++; } // Contribute build system if (scanResult.build_system) { await contributeProject( result.user_id, projectId, `What build system does ${projectName} use?`, `Build system: ${scanResult.build_system}`, 'tooling', false, projectPath ); scannedEntries++; } // Contribute git repository if (scanResult.git_repo && scanResult.git_repo !== 'No git repository') { await contributeProject( result.user_id, projectId, `What is the git repository for ${projectName}?`, `Repository: ${scanResult.git_repo}, Branch: ${scanResult.git_branch || 'main'}`, 'git', false, projectPath ); scannedEntries++; } // Contribute testing framework if (scanResult.testing_framework && scanResult.testing_framework !== 'No tests detected') { await contributeProject( result.user_id, projectId, `What testing framework does ${projectName} use?`, `Testing: ${scanResult.testing_framework}`, 'testing', false, projectPath ); scannedEntries++; } // Contribute deployment if (scanResult.deployment && scanResult.deployment !== 'No deployment config') { await contributeProject( result.user_id, projectId, `How is ${projectName} deployed?`, `Deployment: ${scanResult.deployment}`, 'deployment', false, projectPath ); scannedEntries++; } // Contribute roadmap if (scanResult.roadmap && scanResult.roadmap !== 'No roadmap file') { await contributeProject( result.user_id, projectId, `Does ${projectName} have a roadmap or planning document?`, `Roadmap: ${scanResult.roadmap}`, 'planning', false, projectPath ); scannedEntries++; } // Create patterns category (always, even if empty) await contributeProject( result.user_id, projectId, `What development patterns should be followed in ${projectName}?`, `This category tracks recurring patterns, best practices, and lessons learned during development. Add entries here when you discover patterns worth remembering.`, 'patterns', false, projectPath ); scannedEntries++; // Add getting-started guide (ALWAYS FIRST) await contributeProject( result.user_id, projectId, `How do I use my hive?`, `Your hive is your command center. Here's what you can do: **SEARCH YOUR HIVE:** Say: "search my hive for [topic]" or "how do we handle auth?" **ADD TO YOUR HIVE:** Say: "add to hive" or "contribute to hive" - I'll ask what to store Or: "update hive" - I'll analyze what we worked on and add it automatically **CATEGORIES:** You can use ANY category name you want. Create them as you go: - solution: Bug fixes that worked - patterns: Code patterns to follow - pitfall: What NOT to do / failed approaches - roadmap: Future features and plans - architecture: Design decisions - features: How things work - deployment: How to deploy/release ...or make your own! **VIEW YOUR HIVE:** Say: "show me my hive" to see all categories and recent entries **EDIT ENTRIES:** Say: "update entry [id]" to fix or improve existing entries Your hive compounds - the more you add, the smarter I get about YOUR project.`, 'getting-started', false, projectPath ); scannedEntries++; // Pre-create key categories with helpful starters await contributeProject( result.user_id, projectId, `What should go in the 'solution' category?`, `Store bug fixes and problems you solved here. When you fix an error, add it so you never debug it twice. Example: "Fixed CORS error by adding credentials: true to fetch config"`, 'solution', false, projectPath ); scannedEntries++; await contributeProject( result.user_id, projectId, `What should go in the 'pitfall' category?`, `Document failed approaches and things that DON'T work. Save future you from repeating mistakes. Example: "Don't use Promise.all for sequential API calls - causes race conditions"`, 'pitfall', false, projectPath ); scannedEntries++; await contributeProject( result.user_id, projectId, `What should go in the 'roadmap' category?`, `Track future features, planned improvements, and technical debt here. Example: "Add rate limiting to API endpoints" Example: "Refactor auth middleware for better error handling"`, 'roadmap', false, projectPath ); scannedEntries++; // Add starter skills (bookmarks to global hivemind skills) await contributeProject( result.user_id, projectId, `Respawn Claude - Reload MCP servers without losing context`, `Bookmark: skill_id 18419. Trigger: "respawn skill" or "run the respawn skill". Opens new Terminal window, spawns fresh Claude session with --continue flag. Preserves conversation context while reloading all MCP servers. Usage: mcp__hivemind__get_skill(18419)`, 'skills', false, projectPath ); scannedEntries++; await contributeProject( result.user_id, projectId, `Checkpoint System - Save and restore conversation state`, `Bookmark: skill_id 18418. Trigger: "create checkpoint" or "checkpoint". Saves current conversation state to KIRBY database for later restoration. Usage: mcp__hivemind__get_skill(18418)`, 'skills', false, projectPath ); scannedEntries++; } catch (error) { console.error('Scanner error:', error); // Continue even if scan fails } } const storageLocation = storageChoice === 'cloud' ? 'Supabase cloud database (ksethrexopllfhyrxlrb.supabase.co)' : 'Supabase cloud database (ksethrexopllfhyrxlrb.supabase.co)'; const nextStepsMessage = `Your hive is ready! Let's get you comfortable with 3 quick actions: **ACTION 1: Search your hive** Say: "search my hive for tech stack" (This shows you what Claude already knows about your project) **ACTION 2: Add something new** Say: "add to hive" (I'll ask what you want to store - try adding a note about something you're working on) **ACTION 3: See the full guide** Say: "search my hive for getting started" (Shows you everything your hive can do - categories, commands, tips) Ready? Try ACTION 1 now: "search my hive for tech stack" --- **Pro tip:** After any work session, say "update hive" and I'll automatically add what we learned. Your hive grows smarter every day. Want to see your hive overview? Say "show me my hive"`; const localStoragePath = storageChoice === 'local' ? `${projectPath}/.hive.json` : null; const statusMessage = storageChoice === 'cloud' ? `Hive active with 10x limits. Your project knowledge syncs wherever you go, and your solutions help improve Hivemind for everyone. User ID: ${result.user_id} (save this)${scannedEntries > 0 ? `. Scanned and added ${scannedEntries} foundational entries to Supabase cloud database.` : ''}` : `Hive active. Knowledge stays private on this machine. User ID: ${result.user_id} (save this)${scannedEntries > 0 ? `. Scanned and added ${scannedEntries} foundational entries to ${localStoragePath}.` : ''}`; return { step: 'confirm_setup', message: `${statusMessage}\n\n${nextStepsMessage}`, user_id: result.user_id, project_id: result.project_id, storage_type: storageChoice, scanned_entries: scannedEntries, _ctx: "SEARCH FIRST, CODE SECOND. HIVE = PROJECT BRAIN: Contains YOUR proven approaches, not generic answers.", scan_results: scanResult ? { tech_stack: scanResult.tech_stack, architecture: scanResult.architecture, database: scanResult.database, build_system: scanResult.build_system, git_repo: scanResult.git_repo, git_branch: scanResult.git_branch, testing_framework: scanResult.testing_framework, deployment: scanResult.deployment, roadmap: scanResult.roadmap, description: scanResult.description, version: scanResult.version } : undefined }; }
  • Helper function used by initHive to scan the project directory and detect tech stack, architecture, database, build tools, git repo, testing framework, deployment config, and roadmap files. Results are auto-contributed as initial hive entries.
    async function scanProject(projectPath: string): Promise<ProjectScanResult> { const fs = await import('fs/promises'); const path = await import('path'); const result: ProjectScanResult = { tech_stack: [], architecture: [], categories: ['tech-stack', 'architecture'] }; // Try Node.js (package.json) try { const pkgPath = path.join(projectPath, 'package.json'); const pkgContent = await fs.readFile(pkgPath, 'utf-8'); const pkg = JSON.parse(pkgContent); result.description = pkg.description; result.version = pkg.version; const allDeps = { ...pkg.dependencies, ...pkg.devDependencies }; if (allDeps['typescript']) result.tech_stack.push('TypeScript'); if (allDeps['@modelcontextprotocol/sdk']) { result.tech_stack.push('MCP Server'); result.architecture.push('MCP stdio transport'); result.categories.push('mcp-development'); } if (allDeps['react']) result.tech_stack.push('React'); if (allDeps['next']) result.tech_stack.push('Next.js'); if (allDeps['vue']) result.tech_stack.push('Vue'); if (allDeps['@supabase/supabase-js']) { result.tech_stack.push('Supabase'); result.categories.push('supabase-backend'); } if (pkg.scripts?.build?.includes('tsc')) { result.build_system = 'TypeScript compiler (tsc)'; } if (pkg.engines?.node || pkg.scripts) { result.tech_stack.push('Node.js'); } } catch { // No package.json, try other project types } // Try Go (go.mod) try { const goModPath = path.join(projectPath, 'go.mod'); const goModContent = await fs.readFile(goModPath, 'utf-8'); // Extract Go version const versionMatch = goModContent.match(/^go\s+([\d.]+)/m); if (versionMatch) { result.tech_stack.push(`Go ${versionMatch[1]}`); result.version = versionMatch[1]; } // Extract module name (first line) const moduleMatch = goModContent.match(/^module\s+(.+)/m); if (moduleMatch && !result.description) { result.description = `Go module: ${moduleMatch[1]}`; } // Detect common Go libraries if (goModContent.includes('github.com/gorilla/mux')) { result.architecture.push('HTTP server (gorilla/mux)'); } if (goModContent.includes('github.com/gin-gonic/gin')) { result.architecture.push('HTTP server (Gin)'); } if (goModContent.includes('github.com/mattn/go-sqlite3')) { result.database = 'SQLite'; result.categories.push('database'); } if (goModContent.includes('github.com/lib/pq') || goModContent.includes('gorm.io/driver/postgres')) { result.database = 'PostgreSQL'; result.categories.push('database'); } if (goModContent.includes('go-sql-driver/mysql')) { result.database = 'MySQL'; result.categories.push('database'); } result.build_system = 'go build'; } catch { // No go.mod } // Try Python (requirements.txt or pyproject.toml) try { const reqPath = path.join(projectPath, 'requirements.txt'); const reqContent = await fs.readFile(reqPath, 'utf-8'); result.tech_stack.push('Python'); if (reqContent.includes('django')) { result.architecture.push('Django framework'); } if (reqContent.includes('flask')) { result.architecture.push('Flask framework'); } if (reqContent.includes('fastapi')) { result.architecture.push('FastAPI framework'); } if (reqContent.includes('sqlalchemy')) { result.categories.push('database'); } } catch { // Try pyproject.toml try { const pyprojectPath = path.join(projectPath, 'pyproject.toml'); await fs.stat(pyprojectPath); result.tech_stack.push('Python'); result.build_system = 'pyproject.toml'; } catch { // No Python project } } // Try Rust (Cargo.toml) try { const cargoPath = path.join(projectPath, 'Cargo.toml'); const cargoContent = await fs.readFile(cargoPath, 'utf-8'); result.tech_stack.push('Rust'); result.build_system = 'cargo'; // Extract version const versionMatch = cargoContent.match(/^version\s*=\s*"([^"]+)"/m); if (versionMatch) { result.version = versionMatch[1]; } } catch { // No Cargo.toml } // Check for Supabase directory (any project type) try { const supabasePath = path.join(projectPath, 'supabase'); const supabaseStats = await fs.stat(supabasePath); if (supabaseStats.isDirectory()) { if (!result.database) result.database = 'PostgreSQL (Supabase)'; result.architecture.push('Supabase edge functions'); result.categories.push('database', 'edge-functions'); } } catch { // No supabase directory } // Check for README to extract description if not set if (!result.description) { try { const readmePath = path.join(projectPath, 'README.md'); const readmeContent = await fs.readFile(readmePath, 'utf-8'); // Extract first heading or first paragraph const headingMatch = readmeContent.match(/^#\s+(.+)$/m); if (headingMatch) { result.description = headingMatch[1]; } else { // Get first non-empty line const lines = readmeContent.split('\n').filter(l => l.trim()); if (lines.length > 0) { result.description = lines[0].substring(0, 200); } } } catch { // No README } } // Detect Git repository try { const { execSync } = await import('child_process'); const gitRemote = execSync('git remote get-url origin', { cwd: projectPath, encoding: 'utf-8' }).trim(); const gitBranch = execSync('git branch --show-current', { cwd: projectPath, encoding: 'utf-8' }).trim(); result.git_repo = gitRemote; result.git_branch = gitBranch || 'main'; result.categories.push('git'); } catch { // No git repo or git not initialized result.git_repo = 'No git repository'; } // Detect Testing framework try { const pkgPath = path.join(projectPath, 'package.json'); const pkgContent = await fs.readFile(pkgPath, 'utf-8'); const pkg = JSON.parse(pkgContent); const allDeps = { ...pkg.dependencies, ...pkg.devDependencies }; if (allDeps['jest']) result.testing_framework = 'Jest'; else if (allDeps['vitest']) result.testing_framework = 'Vitest'; else if (allDeps['mocha']) result.testing_framework = 'Mocha'; else if (allDeps['@playwright/test']) result.testing_framework = 'Playwright'; else if (pkg.scripts?.test) result.testing_framework = 'Custom (npm test)'; } catch { // Check for Go testing try { const files = await fs.readdir(projectPath); if (files.some(f => f.endsWith('_test.go'))) { result.testing_framework = 'go test'; } } catch {} // Check for Python testing try { const reqPath = path.join(projectPath, 'requirements.txt'); const reqContent = await fs.readFile(reqPath, 'utf-8'); if (reqContent.includes('pytest')) result.testing_framework = 'pytest'; else if (reqContent.includes('unittest')) result.testing_framework = 'unittest'; } catch {} // Check for Rust testing try { const cargoPath = path.join(projectPath, 'Cargo.toml'); await fs.stat(cargoPath); result.testing_framework = 'cargo test'; } catch {} } if (result.testing_framework) { result.categories.push('testing'); } else { result.testing_framework = 'No tests detected'; } // Detect Deployment try { // Check for Vercel if (await fs.stat(path.join(projectPath, 'vercel.json')).then(() => true).catch(() => false)) { result.deployment = 'Vercel'; } // Check for Netlify else if (await fs.stat(path.join(projectPath, 'netlify.toml')).then(() => true).catch(() => false)) { result.deployment = 'Netlify'; } // Check for Docker else if (await fs.stat(path.join(projectPath, 'Dockerfile')).then(() => true).catch(() => false)) { result.deployment = 'Docker'; } // Check for GitHub Actions else if (await fs.stat(path.join(projectPath, '.github/workflows')).then(() => true).catch(() => false)) { result.deployment = 'GitHub Actions (CI/CD)'; } // Check for package.json deploy script else { const pkgPath = path.join(projectPath, 'package.json'); const pkgContent = await fs.readFile(pkgPath, 'utf-8'); const pkg = JSON.parse(pkgContent); if (pkg.scripts?.deploy) result.deployment = 'Custom (npm run deploy)'; } } catch { // No deployment detected } if (result.deployment) { result.categories.push('deployment'); } else { result.deployment = 'No deployment config'; } // Detect Roadmap try { const roadmapFiles = ['ROADMAP.md', 'TODO.md', 'BACKLOG.md', 'PLANNING.md']; let foundRoadmap = false; for (const file of roadmapFiles) { try { const roadmapPath = path.join(projectPath, file); const roadmapContent = await fs.readFile(roadmapPath, 'utf-8'); const lines = roadmapContent.split('\n').filter(l => l.trim()); if (lines.length > 0) { result.roadmap = `${file} (${lines.length} lines)`; result.categories.push('planning'); foundRoadmap = true; break; } } catch { continue; } } if (!foundRoadmap) { result.roadmap = 'No roadmap file'; } } catch { result.roadmap = 'No roadmap file'; } return result; }
  • Input schema definition for the init_hive tool, specifying parameters like project_id, project_name, storage_choice, etc.
    inputSchema: { type: "object", properties: { project_id: { type: "string", description: "Project identifier (e.g., from package.json name or directory)", }, project_name: { type: "string", description: "Human-readable project name", }, is_first_time_user: { type: "boolean", description: "Answer to 'Is this your first time using Claude Code?' (only used when onboarding flag not set)", }, storage_choice: { type: "string", enum: ["cloud", "local"], description: "User's storage choice (omit on first call to get options)", }, project_path: { type: "string", description: "Optional: Absolute path to project directory (for scanning). If not provided, creates empty hive with starter categories only.", }, }, required: ["project_id", "project_name"], },

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Kevthetech143/hivemind-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server