Skip to main content

Python client + CLI for the Vivly social-data API (X / Reddit) with smart prompt-based routing.

Project description

vivly

Async Python client for the Vivly social-data API. One bearer key, two live sources: X (Twitter) and Reddit, plus a smart router that picks sources from a plain-language prompt. Comes with a CLI and an optional MCP server so AI agents (Claude Desktop, Claude Code, Cursor, …) can call it directly.

0.5.0b3 — breaking change. The Python API is now async (async with + await). The CLI is unchanged. See Usage.

Install

pip install --pre vivly==0.5.0b3                # core SDK + CLI
pip install --pre "vivly[mcp]==0.5.0b3"         # + MCP server (vivly-mcp)

The --pre flag is required while we're in beta.

Authenticate

The client needs a personal access token (looks like vk_live_...). Two ways:

# Option A: log in interactively (opens a browser, stores the token at
# ~/.config/vivly/config.json with 0600 perms)
vivly login

# Option B: set it yourself if you were handed a token
export VIVLY_API_KEY="vk_live_..."

A .env file in the working directory is auto-loaded. Resolution order: explicit api_key= argument, then VIVLY_API_KEY (or legacy VIVLY_SKILL_KEY), then .env, then ~/.config/vivly/config.json.

Usage

CLI

vivly route "what reddit thinks of claude code"          # planner picks sources
vivly route "claude code launch reactions" --x           # pin to X
vivly route "san antonio spurs" --x --reddit             # pin both
vivly route "..." --limit 50 --pretty                    # 50 items, pretty JSON
vivly route "..." --out results.json                     # to file
vivly route "..." --no-interactive                       # take planner defaults

While a query runs you'll see a per-source progress block:

  ▰▰▰▱▱▱▱▱ reddit  fetching
  ▰▰▰▱▱▱▱▱ x       fetching

…finalising to per-source counts when the response lands.

Python (async)

import asyncio
from vivly import VivlyClient

async def main():
    async with VivlyClient() as v:
        # Reddit: one-shot retrieval. Auto-discovers subreddits, searches them,
        # and LLM-filters the results for relevance.
        r = await v.reddit.search("claude code agents", max_posts=10)
        for post in r["posts"]:
            print(post["score"], post["title"], post["url"])

        # X / Twitter: async helper that starts a scrape, polls, returns items.
        # (Runs a paid third-party actor server-side; expect a few seconds to
        # minutes — pass on_progress to surface per-poll status.)
        tweets = await v.x.scrape(
            '"san antonio" arena Spurs lang:en',
            max_items=50,
            on_progress=lambda ev: print(ev["phase"], ev["status"], f"{ev['elapsed']:.1f}s"),
        )
        for t in tweets:
            print(t["metrics"]["likes"], t["text"][:80])

        # Smart router: describe what you want; it plans + runs the right sources.
        result = await v.route(
            "what are people saying about claude code on reddit",
            force_sources=["reddit"],
            max_items=20,
            ask="auto",                          # never block on MCQs in scripts
        )

asyncio.run(main())

If you'd rather drive the X scrape yourself instead of the blocking helper:

async with VivlyClient() as v:
    started = await v.x.scrape_start("query lang:en", max_items=50)
    status  = await v.x.scrape_status(started["run_id"])
    items   = await v.x.scrape_items(started["dataset_id"])

MCP — expose Vivly to AI agents

Once pip install vivly[mcp] is in place, the vivly-mcp command runs a Model Context Protocol server over stdio exposing three tools: reddit_search, x_scrape, and route. Auth is read from VIVLY_API_KEY exactly like the CLI — the model never sees the key.

Smoke-test in the inspector:

npx @modelcontextprotocol/inspector vivly-mcp

Register with Claude Code:

claude mcp add vivly vivly-mcp -e VIVLY_API_KEY=vk_live_...

Register with Claude Desktop — ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "vivly": {
      "command": "vivly-mcp",
      "env": { "VIVLY_API_KEY": "vk_live_..." }
    }
  }
}

Cursor uses the same shape at ~/.cursor/mcp.json. After restart, your agent sees reddit_search / x_scrape / route in its tool list and calls them on its own.

Errors

from vivly import VivlyError, AuthError, RateLimitError, NotFoundError

AuthError (401/403) usually means a missing, revoked, or mistyped token.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vivly-0.5.0b3.tar.gz (22.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vivly-0.5.0b3-py3-none-any.whl (28.3 kB view details)

Uploaded Python 3

File details

Details for the file vivly-0.5.0b3.tar.gz.

File metadata

  • Download URL: vivly-0.5.0b3.tar.gz
  • Upload date:
  • Size: 22.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.12

File hashes

Hashes for vivly-0.5.0b3.tar.gz
Algorithm Hash digest
SHA256 8e8b7d5a9ae23b497642f9995c87f5eea3138b4a92407a2f6f203607aafe7328
MD5 8eec931fce0adfb8a1228f934695830a
BLAKE2b-256 2653f3bc57488b072517ac5727c311218fddc16742895b36c1dfc67586160f82

See more details on using hashes here.

File details

Details for the file vivly-0.5.0b3-py3-none-any.whl.

File metadata

  • Download URL: vivly-0.5.0b3-py3-none-any.whl
  • Upload date:
  • Size: 28.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.12

File hashes

Hashes for vivly-0.5.0b3-py3-none-any.whl
Algorithm Hash digest
SHA256 6c1854703c766893cbf128ccaaf72a8bdedbaad1b07dd3b5ab604713dfe1d6b0
MD5 447b3d5a11b60e4245bd7f5c0e27cf38
BLAKE2b-256 bf31601add21d57741df7f07126afde31bbb1e78d911e4b37691f0b34c617d3a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page