Local Twitter/X bookmark organizer with AI categorization and mindmap visualization
TypeScript
3,068
93 commits
updated Apr 8, 2026
Self-hosted Twitter/X bookmark manager with AI-powered organization
Import · Analyze · Categorize · Search · Explore
Siftly turns your Twitter/X bookmarks into a searchable, categorized, visual knowledge base — running entirely on your machine. No cloud, no subscriptions, no browser extensions required. Everything stays local except the AI API calls you configure.
It runs a 4-stage AI pipeline on your bookmarks:
📥 Import (built-in bookmarklet or console script — no extensions needed)
↓
🏷️ Entity Extraction — mines hashtags, URLs, mentions, and 100+ known tools from raw tweet data (free, zero API calls)
↓
👁️ Vision Analysis — reads text, objects, and context from every image/GIF/video thumbnail (30–40 visual tags per image)
↓
🧠 Semantic Tagging — generates 25–35 searchable tags per bookmark for AI-powered search
↓
📂 Categorization — assigns each bookmark to 1–3 categories with confidence scores
After the pipeline runs, you get:
That's it. If you have Claude Code CLI installed and signed in, AI features work automatically — no API key needed.
git clone https://github.com/viperrcrypto/Siftly.git
cd Siftly
./start.sh
start.sh installs dependencies, sets up the database, checks for Claude CLI auth, and opens http://localhost:3000 automatically.
If you're using Claude Code to set up the project, it will read CLAUDE.md and know exactly how to get started. Just open the project folder:
git clone https://github.com/viperrcrypto/Siftly.git
claude Siftly/
Claude Code will handle setup and start the app using your existing Claude subscription — no extra configuration needed.
git clone https://github.com/viperrcrypto/Siftly.git
cd Siftly
npm install
npx prisma generate
npx prisma migrate dev --name init
npx next dev
Siftly automatically detects the best available auth method — no configuration needed in the most common case.
| # | Method | How |
|---|---|---|
| 1 | Claude Code CLI (zero config) | Already signed in? Siftly reads your session from the macOS keychain automatically |
| 2 | API key in Settings | Open Settings in the app and paste your key |
| 3 | ANTHROPIC_API_KEY env var | Set in .env.local or your shell environment |
| 4 | Local proxy | Set ANTHROPIC_BASE_URL to any Anthropic-compatible endpoint |
If you use Claude Code, you're already signed in. Siftly detects your session from the macOS keychain and uses your Claude subscription (Free/Pro/Max) automatically.
The Settings page shows a green "Claude CLI detected — no API key needed" badge with your subscription tier when this is active.
Note: This works on macOS. On Linux/Windows, add an API key in Settings instead.
New accounts include $5 free credit — enough for thousands of bookmarks at Haiku pricing (~$0.00025/bookmark).
Siftly has built-in import tools — no browser extensions required. Go to the Import page and choose either method:
bookmarks.json downloadsF12 (Windows/Linux) or ⌘⌥J (Mac), then go to the Console tabbookmarks.json downloads automaticallyRe-import anytime — Siftly automatically skips duplicates and only adds new bookmarks.
Categorization starts automatically as soon as you import. You can also trigger it manually from:
| Stage | What it does |
|---|---|
| Entity Extraction | Mines hashtags, URLs, @mentions, and 100+ known tool/product names from stored tweet JSON — free, zero API calls |
| Vision Analysis | Analyzes every image, GIF, and video thumbnail — OCR text, objects, scene, mood, meme templates, 30–40 visual tags per image |
| Semantic Tagging | Generates 25–35 precise search tags per bookmark by combining tweet text + image context. Also extracts sentiment, people, and company names. |
| Categorization | Assigns 1–3 categories per bookmark with confidence scores using all enriched data |
The pipeline is incremental — if interrupted, it picks up where it left off. Use "Re-run everything (force all)" to re-analyze bookmarks that were already processed.
Natural language queries across all bookmark data:
Searches tweet text, image OCR, visual tags, semantic tags, and categories simultaneously using a full-text search index (FTS5) + Claude semantic reranking. Results are ranked by relevance with AI-generated explanations for each match.
Interactive force-directed graph showing all bookmarks organized by category:
8 default categories pre-seeded with AI-readable descriptions:
| Category | Color |
|---|---|
| Funny Memes | Amber |
| AI Resources | Violet |
| Dev Tools | Cyan |
| Design | Pink |
| Finance & Crypto | Green |
| Productivity | Orange |
| News | Indigo |
| General | Slate |
Create custom categories with a name, color, and optional description. The description is passed directly to the AI during categorization — the more specific, the more accurate the results.
manifest.csvPress Cmd+K (Mac) or Ctrl+K (Windows/Linux) to search across all bookmarks from anywhere in the app.
All settings are manageable in the Settings page at /settings or via environment variables:
| Setting | Env Var | Description |
|---|---|---|
| Anthropic API Key | ANTHROPIC_API_KEY | Optional if Claude CLI is signed in — otherwise required for AI features |
| API Base URL | ANTHROPIC_BASE_URL | Custom endpoint for proxies or local Anthropic-compatible models |
| AI Model | Settings page only | Haiku 4.5 (default, fastest/cheapest), Sonnet 4.6, Opus 4.6 |
| OpenAI Key | OPENAI_API_KEY | Alternative provider — GPT-4.1 Mini/Nano/Full, o4-mini, o3 |
| MiniMax Key | MINIMAX_API_KEY | Alternative provider — M2.7 (1M context), M2.5, M2.5-highspeed |
| MiniMax Base URL | MINIMAX_BASE_URL | Custom MiniMax API endpoint (default: https://api.minimax.io/v1) |
| Database | DATABASE_URL | SQLite file path (default: file:./prisma/dev.db) |
Point Siftly at any Anthropic-compatible server:
ANTHROPIC_BASE_URL=http://localhost:8080
siftly/
├── app/
│ ├── api/
│ │ ├── analyze/images/ # Batch image vision analysis (GET progress, POST run)
│ │ ├── bookmarks/ # List, filter, paginate, delete
│ │ │ └── [id]/categories/ # Per-bookmark category management
│ │ ├── categories/ # Category CRUD
│ │ │ └── [slug]/ # Individual category operations
│ │ ├── categorize/ # 4-stage AI pipeline (start, status, stop)
│ │ ├── export/ # CSV, JSON, ZIP export
│ │ ├── import/ # JSON file import with dedup + auto-pipeline trigger
│ │ │ ├── bookmarklet/ # Bookmarklet-specific import endpoint
│ │ │ └── twitter/ # Twitter-specific import endpoint
│ │ ├── link-preview/ # Server-side OG metadata scraper
│ │ ├── media/ # Media proxy/download endpoint
│ │ ├── mindmap/ # Graph nodes + edges for visualization
│ │ ├── search/ai/ # Natural language semantic search (FTS5 + Claude)
│ │ ├── settings/ # API key + model config
│ │ │ ├── cli-status/ # Claude CLI auth detection endpoint
│ │ │ └── test/ # API key validation endpoint
│ │ └── stats/ # Dashboard stats
│ ├── ai-search/ # AI search page
│ ├── bookmarks/ # Browse, filter, paginate
│ ├── categories/ # Category management
│ │ └── [slug]/ # Category detail page
│ ├── categorize/ # Pipeline monitor with live progress
│ ├── import/ # 3-step import flow (instructions → upload → categorize)
│ ├── mindmap/ # Interactive graph
│ ├── settings/ # Configuration
│ └── page.tsx # Dashboard
│
├── components/
│ ├── mindmap/ # Mindmap canvas, nodes, edges
│ │ ├── mindmap-canvas.tsx
│ │ ├── category-node.tsx
│ │ ├── tweet-node.tsx
│ │ ├── root-node.tsx
│ │ ├── chain-edge.tsx
│ │ └── mindmap-context.ts
│ ├── command-palette.tsx # Cmd+K global search
│ ├── nav.tsx # Sidebar navigation
│ └── theme-toggle.tsx # Light/dark mode
│
├── lib/
│ ├── categorizer.ts # AI categorization logic + default categories
│ ├── claude-cli-auth.ts # Claude CLI OAuth session detection (macOS keychain)
│ ├── vision-analyzer.ts # Image analysis + batch semantic tagging
│ ├── image-context.ts # Shared image context builder
│ ├── fts.ts # SQLite FTS5 full-text search index
│ ├── rawjson-extractor.ts # Entity extraction from raw tweet JSON
│ ├── parser.ts # Multi-format JSON parser
│ ├── exporter.ts # CSV, JSON, ZIP export
│ ├── types.ts # Shared TypeScript types
│ └── db.ts # Prisma client singleton
│
├── prisma/
│ └── schema.prisma # SQLite schema
│
├── start.sh # One-command launcher (install + DB setup + open browser)
└── CLAUDE.md # Instructions for Claude Code AI assistant
Bookmark — tweet text, author, date, raw JSON, semantic tags, enrichment metadata
├── MediaItem — images / videos / GIFs with AI-generated image tags
└── BookmarkCategory — category assignments with confidence scores (0–1)
Category — name, slug, hex color, AI-readable description
Setting — key-value store (API keys, model preferences)
ImportJob — tracks import file status and progress
Siftly uses Prisma migrations for relational schema changes.
In development, run npx prisma migrate dev --name <change-name> when schema changes.
For runtime/prod-style startup, apply committed migrations with npx prisma migrate deploy.
FTS5 (bookmark_fts) is managed at runtime in lib/fts.ts, not in schema.prisma.
This is intentional for now because Prisma does not model SQLite virtual table definitions directly.
For Prisma command and workflow details, see:
| Technology | Version | Role |
|---|---|---|
| Next.js | 16 | Full-stack framework (App Router) |
| TypeScript | 5 | Type safety throughout |
| Prisma | 7 | ORM + migrations |
| SQLite | — | Local database — zero setup, includes FTS5 |
| Tailwind CSS | v4 | Styling |
| Anthropic SDK | — | Vision, semantic tagging, categorization, search |
| MiniMax | — | Alternative AI provider (M2.7 1M context, M2.5) |
| @xyflow/react | 12 | Interactive mindmap graph |
| Framer Motion | 12 | Animations |
| Radix UI | — | Accessible UI primitives |
| JSZip | — | Category ZIP export |
| Lucide React | — | Icons |
# One-command start (installs, sets up DB, opens browser)
./start.sh
# Or manually:
npm install
npx prisma generate
npx prisma migrate dev --name init
npx next dev
# Type check
npx tsc --noEmit
# Open database GUI
npx prisma studio
# Build for production
npm run build && npm start
Edit DEFAULT_CATEGORIES in lib/categorizer.ts. Each entry needs:
{
name: 'My Category', // Display name
slug: 'my-category', // URL-safe identifier (must be unique)
color: '#6366f1', // Hex color shown in UI
description: '...', // Natural language description — used verbatim in AI prompts
}
The description field directly shapes how the AI classifies bookmarks. Be specific.
Add domain strings to KNOWN_TOOL_DOMAINS in lib/rawjson-extractor.ts to have the entity extractor automatically recognize links to those tools in tweet data.
If Siftly saves you time, consider leaving a tip ☕
MIT — see LICENSE
Built by @viperr · Self-hosted · No extensions · No cloud
535 followers · starred Mar 2026
153 followers · starred Mar 2026
58 followers · starred Mar 2026
197 followers · starred Mar 2026
Local Twitter/X bookmark organizer with AI categorization and mindmap visualization
TypeScript
3,068
93 commits
updated Apr 8, 2026
Self-hosted Twitter/X bookmark manager with AI-powered organization
Import · Analyze · Categorize · Search · Explore
Siftly turns your Twitter/X bookmarks into a searchable, categorized, visual knowledge base — running entirely on your machine. No cloud, no subscriptions, no browser extensions required. Everything stays local except the AI API calls you configure.
It runs a 4-stage AI pipeline on your bookmarks:
📥 Import (built-in bookmarklet or console script — no extensions needed)
↓
🏷️ Entity Extraction — mines hashtags, URLs, mentions, and 100+ known tools from raw tweet data (free, zero API calls)
↓
👁️ Vision Analysis — reads text, objects, and context from every image/GIF/video thumbnail (30–40 visual tags per image)
↓
🧠 Semantic Tagging — generates 25–35 searchable tags per bookmark for AI-powered search
↓
📂 Categorization — assigns each bookmark to 1–3 categories with confidence scores
After the pipeline runs, you get:
That's it. If you have Claude Code CLI installed and signed in, AI features work automatically — no API key needed.
git clone https://github.com/viperrcrypto/Siftly.git
cd Siftly
./start.sh
start.sh installs dependencies, sets up the database, checks for Claude CLI auth, and opens http://localhost:3000 automatically.
If you're using Claude Code to set up the project, it will read CLAUDE.md and know exactly how to get started. Just open the project folder:
git clone https://github.com/viperrcrypto/Siftly.git
claude Siftly/
Claude Code will handle setup and start the app using your existing Claude subscription — no extra configuration needed.
git clone https://github.com/viperrcrypto/Siftly.git
cd Siftly
npm install
npx prisma generate
npx prisma migrate dev --name init
npx next dev
Siftly automatically detects the best available auth method — no configuration needed in the most common case.
| # | Method | How |
|---|---|---|
| 1 | Claude Code CLI (zero config) | Already signed in? Siftly reads your session from the macOS keychain automatically |
| 2 | API key in Settings | Open Settings in the app and paste your key |
| 3 | ANTHROPIC_API_KEY env var | Set in .env.local or your shell environment |
| 4 | Local proxy | Set ANTHROPIC_BASE_URL to any Anthropic-compatible endpoint |
If you use Claude Code, you're already signed in. Siftly detects your session from the macOS keychain and uses your Claude subscription (Free/Pro/Max) automatically.
The Settings page shows a green "Claude CLI detected — no API key needed" badge with your subscription tier when this is active.
Note: This works on macOS. On Linux/Windows, add an API key in Settings instead.
New accounts include $5 free credit — enough for thousands of bookmarks at Haiku pricing (~$0.00025/bookmark).
Siftly has built-in import tools — no browser extensions required. Go to the Import page and choose either method:
bookmarks.json downloadsF12 (Windows/Linux) or ⌘⌥J (Mac), then go to the Console tabbookmarks.json downloads automaticallyRe-import anytime — Siftly automatically skips duplicates and only adds new bookmarks.
Categorization starts automatically as soon as you import. You can also trigger it manually from:
| Stage | What it does |
|---|---|
| Entity Extraction | Mines hashtags, URLs, @mentions, and 100+ known tool/product names from stored tweet JSON — free, zero API calls |
| Vision Analysis | Analyzes every image, GIF, and video thumbnail — OCR text, objects, scene, mood, meme templates, 30–40 visual tags per image |
| Semantic Tagging | Generates 25–35 precise search tags per bookmark by combining tweet text + image context. Also extracts sentiment, people, and company names. |
| Categorization | Assigns 1–3 categories per bookmark with confidence scores using all enriched data |
The pipeline is incremental — if interrupted, it picks up where it left off. Use "Re-run everything (force all)" to re-analyze bookmarks that were already processed.
Natural language queries across all bookmark data:
Searches tweet text, image OCR, visual tags, semantic tags, and categories simultaneously using a full-text search index (FTS5) + Claude semantic reranking. Results are ranked by relevance with AI-generated explanations for each match.
Interactive force-directed graph showing all bookmarks organized by category:
8 default categories pre-seeded with AI-readable descriptions:
| Category | Color |
|---|---|
| Funny Memes | Amber |
| AI Resources | Violet |
| Dev Tools | Cyan |
| Design | Pink |
| Finance & Crypto | Green |
| Productivity | Orange |
| News | Indigo |
| General | Slate |
Create custom categories with a name, color, and optional description. The description is passed directly to the AI during categorization — the more specific, the more accurate the results.
manifest.csvPress Cmd+K (Mac) or Ctrl+K (Windows/Linux) to search across all bookmarks from anywhere in the app.
All settings are manageable in the Settings page at /settings or via environment variables:
| Setting | Env Var | Description |
|---|---|---|
| Anthropic API Key | ANTHROPIC_API_KEY | Optional if Claude CLI is signed in — otherwise required for AI features |
| API Base URL | ANTHROPIC_BASE_URL | Custom endpoint for proxies or local Anthropic-compatible models |
| AI Model | Settings page only | Haiku 4.5 (default, fastest/cheapest), Sonnet 4.6, Opus 4.6 |
| OpenAI Key | OPENAI_API_KEY | Alternative provider — GPT-4.1 Mini/Nano/Full, o4-mini, o3 |
| MiniMax Key | MINIMAX_API_KEY | Alternative provider — M2.7 (1M context), M2.5, M2.5-highspeed |
| MiniMax Base URL | MINIMAX_BASE_URL | Custom MiniMax API endpoint (default: https://api.minimax.io/v1) |
| Database | DATABASE_URL | SQLite file path (default: file:./prisma/dev.db) |
Point Siftly at any Anthropic-compatible server:
ANTHROPIC_BASE_URL=http://localhost:8080
siftly/
├── app/
│ ├── api/
│ │ ├── analyze/images/ # Batch image vision analysis (GET progress, POST run)
│ │ ├── bookmarks/ # List, filter, paginate, delete
│ │ │ └── [id]/categories/ # Per-bookmark category management
│ │ ├── categories/ # Category CRUD
│ │ │ └── [slug]/ # Individual category operations
│ │ ├── categorize/ # 4-stage AI pipeline (start, status, stop)
│ │ ├── export/ # CSV, JSON, ZIP export
│ │ ├── import/ # JSON file import with dedup + auto-pipeline trigger
│ │ │ ├── bookmarklet/ # Bookmarklet-specific import endpoint
│ │ │ └── twitter/ # Twitter-specific import endpoint
│ │ ├── link-preview/ # Server-side OG metadata scraper
│ │ ├── media/ # Media proxy/download endpoint
│ │ ├── mindmap/ # Graph nodes + edges for visualization
│ │ ├── search/ai/ # Natural language semantic search (FTS5 + Claude)
│ │ ├── settings/ # API key + model config
│ │ │ ├── cli-status/ # Claude CLI auth detection endpoint
│ │ │ └── test/ # API key validation endpoint
│ │ └── stats/ # Dashboard stats
│ ├── ai-search/ # AI search page
│ ├── bookmarks/ # Browse, filter, paginate
│ ├── categories/ # Category management
│ │ └── [slug]/ # Category detail page
│ ├── categorize/ # Pipeline monitor with live progress
│ ├── import/ # 3-step import flow (instructions → upload → categorize)
│ ├── mindmap/ # Interactive graph
│ ├── settings/ # Configuration
│ └── page.tsx # Dashboard
│
├── components/
│ ├── mindmap/ # Mindmap canvas, nodes, edges
│ │ ├── mindmap-canvas.tsx
│ │ ├── category-node.tsx
│ │ ├── tweet-node.tsx
│ │ ├── root-node.tsx
│ │ ├── chain-edge.tsx
│ │ └── mindmap-context.ts
│ ├── command-palette.tsx # Cmd+K global search
│ ├── nav.tsx # Sidebar navigation
│ └── theme-toggle.tsx # Light/dark mode
│
├── lib/
│ ├── categorizer.ts # AI categorization logic + default categories
│ ├── claude-cli-auth.ts # Claude CLI OAuth session detection (macOS keychain)
│ ├── vision-analyzer.ts # Image analysis + batch semantic tagging
│ ├── image-context.ts # Shared image context builder
│ ├── fts.ts # SQLite FTS5 full-text search index
│ ├── rawjson-extractor.ts # Entity extraction from raw tweet JSON
│ ├── parser.ts # Multi-format JSON parser
│ ├── exporter.ts # CSV, JSON, ZIP export
│ ├── types.ts # Shared TypeScript types
│ └── db.ts # Prisma client singleton
│
├── prisma/
│ └── schema.prisma # SQLite schema
│
├── start.sh # One-command launcher (install + DB setup + open browser)
└── CLAUDE.md # Instructions for Claude Code AI assistant
Bookmark — tweet text, author, date, raw JSON, semantic tags, enrichment metadata
├── MediaItem — images / videos / GIFs with AI-generated image tags
└── BookmarkCategory — category assignments with confidence scores (0–1)
Category — name, slug, hex color, AI-readable description
Setting — key-value store (API keys, model preferences)
ImportJob — tracks import file status and progress
Siftly uses Prisma migrations for relational schema changes.
In development, run npx prisma migrate dev --name <change-name> when schema changes.
For runtime/prod-style startup, apply committed migrations with npx prisma migrate deploy.
FTS5 (bookmark_fts) is managed at runtime in lib/fts.ts, not in schema.prisma.
This is intentional for now because Prisma does not model SQLite virtual table definitions directly.
For Prisma command and workflow details, see:
| Technology | Version | Role |
|---|---|---|
| Next.js | 16 | Full-stack framework (App Router) |
| TypeScript | 5 | Type safety throughout |
| Prisma | 7 | ORM + migrations |
| SQLite | — | Local database — zero setup, includes FTS5 |
| Tailwind CSS | v4 | Styling |
| Anthropic SDK | — | Vision, semantic tagging, categorization, search |
| MiniMax | — | Alternative AI provider (M2.7 1M context, M2.5) |
| @xyflow/react | 12 | Interactive mindmap graph |
| Framer Motion | 12 | Animations |
| Radix UI | — | Accessible UI primitives |
| JSZip | — | Category ZIP export |
| Lucide React | — | Icons |
# One-command start (installs, sets up DB, opens browser)
./start.sh
# Or manually:
npm install
npx prisma generate
npx prisma migrate dev --name init
npx next dev
# Type check
npx tsc --noEmit
# Open database GUI
npx prisma studio
# Build for production
npm run build && npm start
Edit DEFAULT_CATEGORIES in lib/categorizer.ts. Each entry needs:
{
name: 'My Category', // Display name
slug: 'my-category', // URL-safe identifier (must be unique)
color: '#6366f1', // Hex color shown in UI
description: '...', // Natural language description — used verbatim in AI prompts
}
The description field directly shapes how the AI classifies bookmarks. Be specific.
Add domain strings to KNOWN_TOOL_DOMAINS in lib/rawjson-extractor.ts to have the entity extractor automatically recognize links to those tools in tweet data.
If Siftly saves you time, consider leaving a tip ☕
MIT — see LICENSE
Built by @viperr · Self-hosted · No extensions · No cloud
535 followers · starred Mar 2026
153 followers · starred Mar 2026
58 followers · starred Mar 2026
197 followers · starred Mar 2026