Skip to content

Releases: ihuzaifashoukat/x-use

x-use 2.4.1 — repair SKILL.md frontmatter

Choose a tag to compare

@ihuzaifashoukat ihuzaifashoukat released this 25 Jul 17:19

Patch release. 2.4.0 shipped every bundled skill with invalid YAML frontmatter; this repairs them.

Fixed

Every shipped SKILL.md had invalid YAML frontmatter. 2.4.0 removed em dashes from the skills pack and replaced several of them with colons, which landed inside unquoted description values. A colon followed by a space makes YAML read the rest of the line as a nested mapping, so all eleven files failed to parse with mapping values are not allowed in this context and no skill consumer could load them.

The descriptions are rewritten to carry no colon at all.

tests/test_skills_pack.py now parses frontmatter as real YAML instead of matching line prefixes, which is exactly why the original slipped through. It also checks the Agent Skills spec limits: name charset and length, description length, no XML tags, and name matching its directory. The em-dash house rule is pinned in the same file so fixing one cannot break the other again.

Adds pyyaml as a dev dependency. 670 to 694 tests.

Upgrade

pip install --upgrade x-use-mcp

If you installed the skills from 2.4.0, reinstall them:

x-use skills install --force

No other changes. Everything in 2.4.0 applies.

x-use 2.4.0 — search_profile, MCP prompts and resources

Choose a tag to compare

@ihuzaifashoukat ihuzaifashoukat released this 25 Jul 17:06

Adds a read-only profile-timeline tool, the prompt and resource surfaces of the MCP protocol, and a root SKILL.md. Also fixes a version drift that had the package reporting 2.0.0 to external scanners since the v2.0 release.

Added

search_profile, a read-only tool for one profile's recent posts. 32 to 33 tools. The scraper could already read profile timelines, but the only tool that reached that path was run_cycle, which is the one tool with no draft gate in front of it. Watching a competitor should not require the ungated batch path.

profile accepts a handle (@nasa or nasa), a profile URL, or a tweet URL, which resolves to its author. The handle is validated against X's charset and a canonical https://x.com/<handle> is rebuilt from it, so query strings, fragments, and extra path segments are discarded rather than navigated. Foreign hosts and x.com app routes (/home, /i, /search) error before a browser starts.

It also closes a gap in performance tracking: nothing reported how a published post did, because approve_draft returns no URL. Re-reading your own timeline is the answer.

MCP prompts. Five workflow prompts: research_niche, draft_replies, review_and_publish, daily_check, setup_account. The bundled SKILL.md pack only works in clients that implement Agent Skills; prompts are the protocol-native equivalent and work anywhere, including Claude Desktop, Cursor, and Windsurf, with nothing installed. draft_replies is lane-aware, because drafts and queued items live in separate stores with no bridge between them.

MCP resources. Four read-only context surfaces: xuse://accounts, xuse://accounts/{account_id}, xuse://accounts/{account_id}/persona, and xuse://drafts/pending. None start a browser, and all run the same masking as the tools. The persona resource is the point: it is exactly the context a drafting turn needs, and attaching it costs no turn.

SKILL.md at the repository root, generated by scripts/sync_skills.py from the canonical router skill plus an install footer, with a CI drift guard so it stays a mirror rather than a hand-edited copy.

Fixed

The package reported version 2.0.0. src/xuse/__init__.py had been stale since the v2.0 release because nothing inside the package read it. External directory scanners do, and listed x-use as 2.0.0 next to a 2.3.1 release. The version now lives in exactly one place and pyproject.toml derives its own from it, so a second literal cannot reintroduce the drift.

The MCP handshake advertised the SDK's version as x-use's. FastMCP takes no version argument, so the wrapped low-level server's stayed None and every client was told x-use was "1.28.1".

Upgrade

pip install --upgrade x-use-mcp

No configuration changes and no breaking changes. 670 tests, none of which need a network or a browser.

Note for contributors: the release rule changed. Bump __version__ in src/xuse/__init__.py, not pyproject.toml, which now derives its version from that attribute.

v2.3.1 — MCP registry manifest, docs consolidation

Choose a tag to compare

@ihuzaifashoukat ihuzaifashoukat released this 25 Jul 14:16

Packaging, documentation, and release plumbing. No src/ changes, so behaviour is identical to 2.3.0.

This exists as a release rather than a docs commit for one reason: the official MCP Registry verifies PyPI ownership by reading an mcp-name marker out of the package description, PyPI descriptions are immutable once uploaded, and 2.3.0 shipped before the marker existed. Registration needs a version that carries it.

Added

  • server.json at the repo root, the manifest for the official MCP Registry.
  • An mcp-name ownership marker in the README, which flows into the PyPI description automatically since pyproject.toml sets readme = "README.md".
  • An mcp-registry job in publish.yml that publishes to the registry after PyPI on every release. It authenticates with GitHub OIDC so no secret is stored, rewrites the server.json version from the release tag so the manifest cannot drift from the release, and refuses to publish unless the released PyPI description actually carries the marker.

Changed

  • BEST_PRACTICES.md moved to docs/BEST_PRACTICES.md and rewritten for 2.3. It had drifted badly: it referenced src/main.py and pre-src-layout module paths, described the gemini/openai/azure provider stack that 2.2 replaced with a single OpenAI-compatible client, said LLM keys could not come from the environment when .env now takes precedence over settings.json, and listed draft mode and x-use doctor as planned when both had shipped. It now covers the queue gate, the proxy MCP tools, cookie expiry checks, and the percent-encoding rule for proxy credentials.
  • GitHub Actions moved off the deprecated Node 20 runtime: checkout v4 to v7, setup-python v5 to v7, upload-artifact v4 to v7, download-artifact v4 to v8.
  • Em dashes removed throughout the user-facing documentation.

Full detail in CHANGELOG.md. 599 tests passing.

v2.3.0 — agent media, personas, composite drafts, proxy pools

Choose a tag to compare

@ihuzaifashoukat ihuzaifashoukat released this 25 Jul 12:52

Agent-native media, personas, composite draft staging, and proxy pool management — followed by a hardening wave driven by live testing against a real X account. 25 → 32 MCP tools.

Full detail in CHANGELOG.md.

Added

  • get_tweet(account, tweet_url, include_images=true) — text, author, public counts, typed media and persona in one read.
  • Typed media on tweets — photos with alt text and video posters, deduped, avatars excluded. Photos return to vision-capable clients as MCP ImageContent; fetches are allowlisted to *.twimg.com, capped at 8 MB / 5 s, and re-encoded to JPEG ≤1024 px. Any failure degrades to URL-only and never errors the tool.
  • include_images on search_tweets and prepare_reply.
  • Freeform account persona, prepended to reply and post prompts.
  • Composite draft-only toolsresearch_and_stage and draft_post_variations, both persona-aware and both refusing paused accounts.
  • Proxy pool managementlist_proxies, add_proxy, remove_proxy, test_proxy, fully masked, with validated atomic settings.json writes.
  • Bundled 5-skill agent packx-use skills install|list, offered at the end of x-use init, plus a Claude plugin marketplace kept byte-identical by a CI drift guard.
  • Docsdocs/MCP_GUIDE.md (32-tool reference) and docs/SETUP_PROMPT.md (one-prompt setup).

Changed

  • Default LLM max_tokens raised to 1200 — reasoning models were spending the whole budget on reasoning and returning empty replies. An empty completion with finish_reason="length" now retries once at max(2x, 1200).
  • The cookie handshake drops its redundant post-cookie refresh, removing one full page load from every cold start.

Fixed

Highlights — the full grouped list is in the changelog.

  • A failed add_account/update_account no longer deletes the account's live cookie file. Importing a cookie_file overwrites config/<id>_cookies.json, and orphan cleanup then unlinked that path on a failed config write — so update_account(cookie_file=…, proxy="bad-url") returned ok:false and destroyed a working login that nothing backs up. The import now stashes any pre-existing file and restores it on rollback, deleting only files it created.
  • Userinfo masking now handles passwords containing /, whitespace, or a second @. The previous regex could not match those, so http://user:pa/ss@host was emitted completely unmasked — reachable via list_proxies, get_account, and proxy error text. Masking now scans the URL authority directly, and the three copies of that regex are collapsed into one shared implementation.
  • Security — whole-userinfo masking everywhere, sanitized queue last_error, *.twimg.com fetch allowlist.
  • Queue — cancel-during-sleep honored, zombie processing items recovered, paused accounts skipped on drain-all, dedup keys include media and community.
  • Sessions — cancel-safe cold start and close, unresponsive drivers force-quit, cookie shape validation, proxy pool import fix.
  • Config writes — backup failures block the write, shared proxy validation, corrupt configs surfaced rather than treated as empty.
  • Engine truthfulness — no action reports success without confirmation; navigation failures are respected instead of swallowed.

Both of the first two fixes were regressions introduced within this release cycle and never reached a published version — 2.2.0 is unaffected. Each is now pinned by regression tests.

Testing

599 tests passing, up from 551, requiring no network and no browser.

v2.2.0 — agent-native MCP, single LLM client

Choose a tag to compare

@ihuzaifashoukat ihuzaifashoukat released this 24 Jul 14:12

v2.2 makes the MCP server agent-native: interactive use needs no LLM key at all — your MCP client (Claude, Codex, ...) does the analysis and writing, and the server drives the browser. The old three-provider LLM stack collapses into a single OpenAI-compatible client for the paths that genuinely need one (background automation, "auto" text). This release was audited end to end and live-tested against a real X account: 25/25 tools exercised, real post + self-reply + like executed through the draft and queue gates.

Highlights

  • One OpenAI-compatible LLM client: llm block in settings.json (api_key, base_url, model), env fallbacks OPENAI_API_KEY / OPENAI_BASE_URL / OPENAI_MODEL. OpenAI, OpenRouter, Azure, Gemini, and local servers (Ollama, vLLM) all speak this API. Legacy api_keys.openai_api_key is honored as a last-resort key source; gemini/azure keys warn-and-ignore. service_preference routing and the langchain-google-genai dependency are gone.
  • Agent-native interactive path: every write tool takes explicit text, and the new read-only prepare_reply(account, tweet_url) tool returns a tweet's content plus account context so your agent can compose the reply itself. 25 tools total.
  • Hardening from a full audit: concurrent queue drains are refused (already_running), account-tool session closes wait for in-flight actions, browsers that cold-start past their timeout are closed instead of leaked, crash-window drafts recover to pending, get_account_health reports invalid configs instead of failing, paused accounts are refused on every write path, and the mcp pin is now >=1.6 (first release with FastMCP lifespan).
  • Fixes found by live testing: undetected-chromedriver no longer receives excludeSwitches (modern chromedriver rejected the session), UC is pinned to the installed Chrome major version, successful likes are no longer misreported as failures (verification now watches the button flip to "unlike"), cookie imports already at the convention path work, handles render without "@@", and the settings template defaults to Chrome.

Details

  • doctor: single llm check; a missing key is SKIP (keyless interactive use is valid), not FAIL. The init wizard writes OPENAI_API_KEY / OPENAI_BASE_URL / OPENAI_MODEL.
  • LLMService returns None when unconfigured, so heuristic fallbacks (e.g. the analyzer's keyword relevance) keep working keyless. Tools that strictly need generation return a clear envelope pointing at the llm block or the explicit-text path.
  • Runtime state (data/drafts.jsonl, data/engagement_queue.jsonl, data/metrics/*.json) is now gitignored.
  • Tests: 234 -> 258, all passing; the 25-tool contract is pinned so signature drift fails CI.

Upgrade notes

  • pip install -U x-use-mcp
  • If you used Gemini or Azure keys before: set the llm block (api_key + base_url + model) — both providers offer OpenAI-compatible endpoints. Legacy openai_api_key keeps working with no changes.
  • Interactive MCP use needs no key at all: prefer explicit text from your MCP client; use prepare_reply to give it the tweet context.
  • Background automation (run_cycle, pipelines, "auto" text in the queue) requires the llm block or env vars and errors clearly without them.

x-use v2.1.0 - scheduled-action queue, account management, 24 MCP tools

Choose a tag to compare

@ihuzaifashoukat ihuzaifashoukat released this 24 Jul 11:31

The MCP server grows from 9 to 24 tools: a persistent scheduled-action queue with safety pacing, full account management from your MCP client, and the operational tools that were missing. Additive only; everything from v2.0.0 keeps working unchanged.

Highlights

  • Scheduled-action queue: queue_post and queue_engagement store fully-rendered payloads (LLM text generated at enqueue time, so list_queue shows exactly what will fire). process_queue is the explicit approval gate and drains with jittered 90-240s pacing, per-action daily caps (posts 5, replies 15, likes 30, retweets 10 per day by default), and retry backoff. An opt-in auto_drain background worker (default off) trickles the queue on an interval.
  • Account management: add_account, update_account, set_account_active, remove_account (confirm-gated), get_account. Every write to config/accounts.json is validated, backed up to config/backups/, and applied atomically. Cookies import from a server-side file path only, never inline through the chat. Paused accounts are rejected at enqueue and skipped on drain-all.
  • Support tools: list_drafts, get_draft, reject_draft (drafts can now be reviewed and rejected, not just approved), get_run_status (poll run_cycle handles), get_account_health (config, cookie validity, metrics, session, queue depth, pending drafts in one read-only call).

Details

  • New standalone xuse/queue/ package (store, runner, scheduler) with no MCP imports, ready for a future x-use queue CLI
  • New xuse/core/config_writer.py: load-fresh, validate-every-account, timestamped pruned backups, atomic replace
  • The queue subsystem has its own top-level queue block in settings.json; see docs/CONFIG_REFERENCE.md
  • Legacy account-key normalization consolidated into xuse/core/config_loader.py (shared by core, MCP, and the init wizard)
  • config/backups/ added to .gitignore (backup copies may contain secrets)
  • Tests: 148 -> 234, all passing; the 24-tool contract is pinned so signature drift fails CI

Upgrade notes

  • pip install -U x-use-mcp
  • No config changes required; every new setting defaults conservatively (auto_drain off, pacing 90-240s, daily caps as above)
  • Drafts file gains one status value (rejected); older servers simply never produce it

x-use 2.0.0

Choose a tag to compare

@ihuzaifashoukat ihuzaifashoukat released this 23 Jul 22:01

The v2 relaunch of twitter-automation-ai: an installable package, a proper CLI, and a first-class MCP server. The automation engine is unchanged; everything around it is new.

Highlights

  • One-line installers for Windows, macOS, and Linux (install.ps1 / install.sh): clone, venv, install, config bootstrap, and x-use doctor in a single command
  • New CLI: x-use init (interactive setup wizard), x-use run, x-use doctor (preflight checks), x-use mcp
  • MCP server over stdio with 9 tools, so Claude Desktop, Claude Code, Cursor, and other MCP clients can post, reply, search, and engage directly
  • Draft mode on by default: write tools return reviewable drafts and nothing reaches X until approve_draft is called
  • Installable from PyPI: pip install x-use-mcp (PyPI rejected the bare x-use name as too similar to an existing project; import xuse and the x-use command are unchanged)

What changed since v1

  • Packaging: src-layout src/xuse/ package, pyproject.toml, Python 3.10+ floor, x-use console script, project-root anchoring that survives install location
  • CLI: Typer app with in-memory --account and --pipeline scoping (config files never mutated)
  • MCP: 9 tools on the official MCP Python SDK (FastMCP, pinned mcp>=1,<2), lazy per-account browser session pool with idle reaping, persistent draft store in data/drafts.jsonl, structured secret-sanitized error envelopes
  • LLM keys: env / .env overrides above config/settings.json, placeholder rejection from both sources, key values never logged
  • Engine fixes: FileHandler now honors the configured processed_tweets_file; proxy pool hash strategy pins accounts with sha256 (stable across restarts); engagement count parsing handles lowercase k/m suffixes and comma separators
  • Pipeline names shared between the CLI and MCP run_cycle via xuse/pipelines.py
  • Security: config/accounts.json untracked (ships accounts.example.json), cookie paths explicitly gitignored, get_metrics validates account ids against path traversal
  • Tests: 148 pytest tests (pure logic, MCP contract/drafts/sessions, CLI, env keys) plus CI on Python 3.10/3.11/3.12
  • Docs: README rewritten, ARCHITECTURE.md and BEST_PRACTICES.md refreshed, CONFIG_REFERENCE.md now covers the mcp settings block

Upgrade notes

  • Python 3.10 or newer is required
  • The legacy python src/main.py entry point still works via a deprecation shim (removal no earlier than v2.1)
  • Config file formats are unchanged; existing config/settings.json and config/accounts.json keep working