Skip to content

codecoradev/titen

Repository files navigation

CI Release License: AGPL-3.0-only Rust 1.85+

Titen

titen — Javanese: to watch closely, to observe with care.

Self-hosted Threads management platform. Post, schedule, analyze — on your own infrastructure.

Why Titen?

Threads has no native post scheduling. Every existing tool is a SaaS you don't control, with your API tokens living on someone else's server. Titen runs locally or on your box, talks directly to the Threads Graph API, and stores everything in a single SQLite file.

That's it. No web dashboard you didn't ask for. No subscription. No vendor lock-in.

Features

Capability Details
Multi-account Manage multiple Threads accounts in one instance
Post scheduling Cron-based scheduler — something Threads itself doesn't offer
Comment fetching Pull comments from the Threads API, store locally
Sentiment analysis Pluggable engine trait (stub default; ONNX/LLM/custom API extensible)
Analytics Time-series snapshots per post
Media storage S3-compatible via swappable storage trait
MCP server JSON-RPC 2.0 over stdio — works with Claude Desktop, Cursor, etc.
CLI Full CRUD from the terminal
Docker Single container, minimal footprint

Architecture

4 crates, one binary each:

Crate Purpose
titen-core Domain logic — models, SQLite, Threads API client, sentiment trait, scheduler, S3 storage
titen-api Axum HTTP server — REST API, API key auth, CORS, rate limiting
titen-cli Clap CLI — all operations via the HTTP API
titen-mcp MCP stdio server — 14 tools for AI agent integration

7 SQLite tables: accounts, posts, schedules, comments, analytics_snap, media_assets, rate_tracking.

3 migrations: 001_initial (schema), 002_drop_refresh_token, 003_add_app_secret.

Quick Start

Install (pre-built binary)

curl -sSL https://github.com/codecoradev/titen/releases/latest/download/install.sh | sh

Build from source

Requires Rust 1.85+ (edition 2024). SQLite is bundled via sqlx.

git clone https://github.com/codecoradev/titen.git
cd titen
cargo build --release

Run

# Start the API server (default: 0.0.0.0:7845)
titen-api

# Or via the CLI with embedded server
titen serve

# Add an account and post
export TITEN_API_KEY=your-key
titen account add myuser --access-token "THREADS_TOKEN" --expires-at "2026-12-01T00:00:00Z"
titen post create myuser --text "Hello from titen!"

The server creates a SQLite database at ~/.codecora/titen/titen.db by default (override with TITEN_DB_PATH).

Configuration

All config via environment variables:

Variable Default Description
TITEN_DB_PATH ~/.codecora/titen/titen.db SQLite database path
TITEN_API_KEY (none) API key — when unset, all endpoints are open
TITEN_HOST 0.0.0.0 Bind address
TITEN_PORT 7845 Bind port
TITEN_URL http://localhost:7845 Base URL for CLI
TITEN_SENTIMENT_ENGINE stub stub, onnx, llm, or custom_api
TITEN_SCHEDULER_INTERVAL_SECS 60 Scheduler tick interval
TITEN_S3_ENDPOINT (none) S3-compatible endpoint
TITEN_S3_BUCKET (none) S3 bucket name
TITEN_S3_REGION us-east-1 S3 region
TITEN_S3_ACCESS_KEY (none) S3 access key
TITEN_S3_SECRET_KEY (none) S3 secret key
TITEN_S3_PUBLIC_URL (none) Public URL for uploaded media

API Reference

Base URL: http://localhost:7845

All endpoints except /health require X-API-Key authentication when TITEN_API_KEY is set. Not Bearer — it's a plain header:

X-API-Key: your-key-here

Health

Method Path Auth
GET /health None

Accounts

Method Path Description
GET /api/accounts List all accounts
POST /api/accounts Create an account
PUT /api/accounts/{id} Update an account
DELETE /api/accounts/{id} Delete an account
POST /api/accounts/{id}/refresh-token Refresh OAuth token
GET /api/accounts/{id}/profile Fetch Threads profile
GET /api/accounts/{id}/publishing-limit Get remaining daily limits
GET /api/accounts/check-tokens Batch token expiry check

Posts

Method Path Description
GET /api/posts List posts (?account_id=&status=&limit=&offset=)
POST /api/posts Create and publish a post
GET /api/posts/{id} Get a single post
DELETE /api/posts/{id} Delete a post
GET /api/posts/{id}/insights Fetch and store post insights

Schedules

Method Path Description
GET /api/schedules List schedules (?account_id=&status=)
POST /api/schedules Create a schedule
PUT /api/schedules/{id} Update a schedule
DELETE /api/schedules/{id} Delete a schedule
GET /api/schedules/upcoming Next 10 pending schedules

Comments

Method Path Description
GET /api/posts/{id}/comments List stored comments
POST /api/posts/{id}/comments/fetch Fetch comments from Threads API
GET /api/posts/{id}/comments/sentiment Analyze comment sentiment

Analytics

Method Path Description
GET /api/analytics/posts Post analytics (?account_id=&from=&to=)
GET /api/analytics/posts/{id}/trend Time-series trend for a post

Media

Method Path Description
GET /api/media List uploaded media
POST /api/media Upload media (multipart)
DELETE /api/media/{id} Delete media

Threads (low-level)

Method Path Description
POST /api/threads/container Create a Threads media container
POST /api/threads/container/{id}/publish Publish a container
POST /api/threads/container/{id}/status Check container status

CLI

The CLI talks to the running HTTP server. Set TITEN_URL and TITEN_API_KEY as needed.

titen serve [--host 0.0.0.0] [--port 7845] [--mcp]

Accounts

titen account list
titen account add <username> --access-token <TOKEN> [--user-id <ID>] [--expires-at <ISO8601>]
titen account remove <id>
titen account refresh <id>
titen account status <id>
titen token-check

Posts

titen post create <account> --text <TEXT> [--media-type TEXT|IMAGE] [--image-url <URL>]
titen post delete <post_id>
titen post insights <post_id>

Schedules

titen schedule add <account> --text <TEXT> --at <ISO8601> [--media-type TEXT|IMAGE]
titen schedule list [--account <id>] [--status <status>]
titen schedule cancel <id>
titen schedule upcoming

Comments

titen comment fetch <post_id>
titen comment list <post_id>
titen comment sentiment <post_id>

Analytics

titen analytics posts <account> [--from <date>] [--to <date>]
titen analytics trend <post_id>
titen analytics sentiment-summary <post_id>

Media

titen media list
titen media upload <file_path> [--content-type <mime>]
titen media delete <id>

MCP Server

Titen ships an MCP (Model Context Protocol) server for AI agent integration. Communicates over stdio using JSON-RPC 2.0.

Setup

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "titen": {
      "command": "/path/to/titen-mcp",
      "env": {
        "TITEN_DB_PATH": "/path/to/titen.db"
      }
    }
  }
}

Cursor — add to your MCP settings:

{
  "mcp": {
    "titen": {
      "command": "/path/to/titen-mcp",
      "env": {
        "TITEN_DB_PATH": "/path/to/titen.db"
      }
    }
  }
}

Available Tools

Tool Description
list_accounts List all Threads accounts
get_account Get a single account by ID
create_post Create and publish a post
schedule_post Schedule a post for later
list_schedules List scheduled posts
cancel_schedule Cancel a scheduled post
fetch_comments Fetch and store comments from Threads
get_post_sentiment Sentiment analysis on a post's comments
get_post_analytics Analytics for a specific post
get_account_analytics Analytics summary for an account
upload_media Upload media to S3 storage
refresh_token Refresh an account's access token
check_tokens Batch check all accounts' token expiry

Threads API Limits

The platform enforces these per-account daily limits:

Limit Count
Posts 250/day
Replies 1,000/day
Deletes 100/day
Caption length 500 chars
text_attachment length 10,000 chars

Scheduler Behavior

  • Engine: tokio-cron with a 60-second tick interval
  • Flow: At scheduled time → create media container → wait for ready → publish
  • Publish delays: text posts publish immediately (0s), image posts wait 30s, video posts wait 60s for processing

Docker

docker build -t titen .
docker run -p 7845:7845 \
  -e TITEN_API_KEY=your-key \
  -e TITEN_DB_PATH=/data/titen.db \
  -e TITEN_S3_ENDPOINT=https://s3.example.com \
  -e TITEN_S3_BUCKET=titen-media \
  -v titen-data:/data \
  titen

License

AGPL-3.0-only

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/my-feature)
  3. Commit your changes
  4. Push to the branch (git push origin feature/my-feature)
  5. Open a Pull Request

About

Self-hosted Threads management platform — schedule, analyze, monitor

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors