{
  "name": "CollabLists",
  "description": "Community-curated directory of best-in-class things for every topic. Public lists are readable anonymously; writes require a Better Auth session today.",
  "version": "0.1.0",
  "site": "https://collablists.globalbr.ai",
  "source_repo": "https://github.com/tmad4000/collablists",
  "api_base": "https://collablists.globalbr.ai/api",
  "openapi_url": "https://collablists.globalbr.ai/openapi.json",
  "docs": {
    "agents_md": "/AGENTS.md",
    "llms_txt": "/llms.txt",
    "robots_txt": "/robots.txt"
  },
  "auth_methods": [
    {
      "id": "anonymous_read",
      "description": "Anonymous GET of public and public-edit lists. Postgres row-level security enforces visibility — private and unlisted lists are invisible without a session.",
      "scopes": ["read:public"]
    },
    {
      "id": "better_auth_session",
      "description": "Better Auth (better-auth) cookie-based session. Required for all writes. Sign in at /login via magic link.",
      "header": "Cookie",
      "sign_in_url": "/login",
      "scopes": ["read:all-visible", "write:owned"]
    },
    {
      "id": "personal_api_key",
      "description": "Per-user bearer token minted at /settings/api-keys (Better Auth bearer plugin). Send as Authorization: Bearer cl_...",
      "header": "Authorization: Bearer <token>",
      "mint_url": "/settings/api-keys",
      "scopes": ["read:owned", "read:shared", "read:public"],
      "status": "live"
    },
    {
      "id": "public_agent_key",
      "description": "Always-published public agent key. Mirrors WIT's published-anon pattern. Read any public list; anonymously create items on public-edit lists with a required `reporter` attribution. Rate-limited by platform.",
      "header": "Authorization: Bearer cl_pub_agent_2026_v1",
      "alt_header": "apikey: cl_pub_agent_2026_v1",
      "token": "cl_pub_agent_2026_v1",
      "scopes": ["read:public", "create:public-edit-anon"],
      "constraints": {
        "anon_create_reporter_required": true,
        "anon_create_content_max_chars": 2000,
        "anon_create_reporter_max_chars": 200
      },
      "status": "live"
    }
  ],
  "mcp": {
    "transport": "stdio",
    "command": "npx",
    "args": ["tsx", "src/scripts/mcp-server.ts"],
    "npm_script": "npm run mcp",
    "tools": [
      "search_lists",
      "list_lists",
      "get_list",
      "search",
      "list_items",
      "get_item",
      "list_my_lists",
      "browse_url",
      "create_list",
      "create_item",
      "update_item",
      "update_list",
      "star_item",
      "unstar_item",
      "delete_item"
    ],
    "status": "live",
    "auth": "Per-user api_key passed as `api_key` tool arg OR `COLLABLISTS_API_KEY` env var. Token resolves against session.token; calls run inside withUserDb so Postgres RLS gates as if the user made the request. Public agent key cl_pub_agent_2026_v1 works for reads only.",
    "docs": "/docs/mcp-server.md (in repo)",
    "ticket": "collablists12-25-v4f"
  },
  "cli": {
    "entry": "src/scripts/cli.ts",
    "npm_script": "npm run cli",
    "shell_wrapper": "cli.sh"
  },
  "url_patterns": {
    "list_by_id":      "/list/{list_id}",
    "list_by_slug":    null,
    "item_permalink":  "/list/{list_id}/item/{item_id}",
    "item_anchor":     "/list/{list_id}#item-{item_id}",
    "settings_api_keys": "/settings/api-keys"
  },
  "how_do_i": {
    "zoom_on_item":        "GET /list/{list_id}#item-{item_id} — anchor scrolls and flashes a highlight ring",
    "open_list":           "GET /list/{list_id}",
    "list_public_lists":   "GET /api/lists?public=true (anonymous)",
    "list_my_lists":       "GET /api/lists?mine=true with bearer token",
    "create_list":         "POST /api/lists {title, visibility}",
    "add_item":            "POST /api/lists/{list_id}/items {content, link?, metadata?}",
    "subscribe_realtime":  "GET /api/list/{list_id}/events (SSE)",
    "search":              "GET /api/search?q=<query>&type=<lists|items|all>&limit=<n>",
    "mint_api_key":        "/settings/api-keys (requires migration 0007 applied; tracked in sli)",
    "self_register_agent": "POST /api/register-agent with {email,password,name,agent_kind?,purpose?} → returns {user_id,api_key,prefix} once; 5/hr/IP rate limit"
  },
  "endpoints": [
    {"method": "GET",  "path": "/api/lists",                  "auth": "optional",  "description": "List index. ?public=true forces anonymous public-only view; signed-in callers get RLS-scoped owner + shared + public/unlisted."},
    {"method": "POST", "path": "/api/lists",                  "auth": "session",   "description": "Create a list with optional initial items."},
    {"method": "GET",  "path": "/api/lists/{id}",             "auth": "optional",  "description": "One list, RLS-scoped."},
    {"method": "GET",  "path": "/api/lists/{id}/items",       "auth": "optional",  "description": "Items for one list."},
    {"method": "GET",  "path": "/api/search",                 "auth": "optional",  "description": "Full-text search across lists + items. Query: q (required, min 2 chars), type (lists|items|all), limit (1-100, default 20). Bearer-aware: authenticated callers get RLS-scoped results."},
    {"method": "GET",  "path": "/api/list/{id}/events",       "auth": "optional",  "description": "SSE realtime change stream for one list."},
    {"method": "GET",  "path": "/api/list/{id}/presence",     "auth": "optional",  "description": "Presence and typing indicators."},
    {"method": "GET",  "path": "/api/link-preview",           "auth": "optional",  "description": "OpenGraph preview helper. Query: url."},
    {"method": "POST", "path": "/api/frontend-log",           "auth": "none",      "description": "Forward browser errors to server logs."},
    {"method": "POST", "path": "/api/register-agent",         "auth": "none",      "description": "One-shot agent self-registration + key mint. Rate-limited 5/hr/IP. api_key returned ONCE."},
    {"method": "POST", "path": "/api/agent-chat",             "auth": "optional",  "description": "Multi-provider streaming chat with the CollabLists agent. Server-side conversation persistence."},
    {"method": "GET",  "path": "/openapi.json",               "auth": "none",      "description": "OpenAPI 3.1 spec for the routes above."},
    {"method": "*",    "path": "/api/auth/[...all]",          "auth": "varies",    "description": "Better Auth handler (sign-in, sign-out, session, callbacks)."}
  ],
  "entities": {
    "list": ["id", "title", "description", "visibility", "owner_id", "updated_at"],
    "list_item": ["id", "list_id", "content", "metadata", "position", "author_id", "source_url", "source_note"],
    "comment": ["id", "item_id", "author_id", "content", "parent_id", "created_at"],
    "star": ["id", "item_id", "user_id", "created_at"]
  },
  "enums": {
    "visibility": ["public", "public-edit", "unlisted", "private"]
  },
  "conventions": {
    "prefer_existing_lists": "Search before creating a parallel list on the same topic.",
    "provenance": "Set source_url and source_note on items that came from a URL — that is the taste signal that makes CollabLists useful.",
    "respect_visibility": "Do not try to enumerate private or unlisted lists; RLS blocks it and the design intent is that they are invisible.",
    "no_anonymous_writes": "Unlike WIT, CollabLists has no anonymous-create path. Use Better Auth or MCP read tools."
  },
  "roadmap_tickets": {
    "agent_parity_audit": "collablists12-25-j7t",
    "agents_md_llms_txt": "collablists12-25-6q5",
    "auto_filer_agent": "collablists12-25-a5j",
    "slug_routing": "collablists12-25-48g"
  }
}
