Spec generated via /spec (Claude Code). Stack + Q1–Q4 picks locked in prior /decide ultrathink turn. Source vault context: ~/Documents/Developer/knowledge-os/Projects/mcp-xee/_context.md.
Problem Statement
Scaffold is complete and the repo is public with SEO topics applied — but mcp-xee is not yet usable by real users. There is no PyPI distribution, no documented cookie-generation flow, no CI verifying smoke tests on PRs, and no v0.1.0 release tag. A curious developer who finds the repo today still has to clone + uv sync + figure out cookie format from twikit's docs. Adoption blocks here.
Solution
Ship v0.1.0 as a GitHub release + PyPI publish, with documented cookie-generation paths (both pythonic and browser-export), smoke-only CI on push/PR, copy-paste Claude Desktop / Claude Code config examples, and a debug-logging escape hatch. Skip MCP-catalog listings and CI live integration tests — both gated on traction signals, not present at v0.1.
Glossary (Ubiquitous Language)
| Term |
Definition |
Aliases to avoid |
| tool |
An MCP tool function. v0.1 = search + user_tweets. |
endpoint, method, function |
| cookie file |
JSON of twikit-format X session cookies. Path via MCP_XEE_COOKIES. |
credentials, auth file, session file |
| twikit client |
The twikit.Client singleton inside mcp-xee |
X client, twitter client |
| MCP client |
The AI app on the other end (Claude Desktop, Claude Code, ChatGPT MCP) |
"client" alone |
| listing |
Submission to an external MCP catalog (mcp.io, glama.ai, smithery.ai) |
"registry" alone |
| release |
A tagged GitHub release with PyPI artifact |
publish, launch |
| smoke CI |
Lint + unit tests on push/PR. No live X calls. |
"tests in CI" alone |
User Stories
- As an MCP-curious dev, I want
pip install mcp-xee so I don't have to clone + uv-sync.
- As a security-conscious user, I want a cookie-export-via-browser-extension path so I never type my X password into a script.
- As a power user, I want
client.login() + save_cookies() documented because I trust twikit and want one-shot setup.
- As a Claude Desktop user, I want a copy-paste
claude_desktop_config.json block to wire mcp-xee in under 2 minutes.
- As a Claude Code user, I want the same example for Claude Code's MCP config surface.
- As a contributor, I want CI to run on every PR so I know my change doesn't break smoke tests.
- As a future maintainer, I want each release tagged + GH-released + PyPI-published from the same commit so version provenance is trivial.
- As an end user, I want clear error messages when my cookie file expires or auth fails — not a stack trace.
- As a debug-mode user, I want
MCP_XEE_DEBUG=1 to surface twikit calls to stderr without polluting MCP stdio.
- As a dev evaluating mcp-xee, I want a comparison table vs other X MCPs in the README so I know if it fits. (Already shipped in scaffold.)
Implementation Decisions
Q1 → (c): document both cookie-generation paths
scripts/login_and_save.py — pythonic CLI: prompts for user/pass/email, calls client.login() + save_cookies(). Password held in memory only.
scripts/convert_cookies.py — converts Netscape cookies.txt (from "Get cookies.txt LOCALLY" Chrome extension) → twikit JSON. No password handling.
docs/cookies.md — step-by-step for both, with security tradeoffs called out.
Q2 → (b): v0.1.0 = GitHub release + PyPI publish
- No listings (mcp.io, glama, smithery) at v0.1 — gate on ≥10 GitHub stars or ≥3 user reports.
- No CI integration test against a live account at v0.1 — see Q3.
Q3 → No: skip CI live integration
- CI runs
ruff check + pytest (smoke only).
- No cookie secret stored in GitHub. Eliminates ban-risk + secret rotation burden.
- Live verification done locally pre-tag using @Aiyo91 cookies.
Q4 → PyPI now
- Publish at v0.1.0 cut, not deferred. mcp-xee is simpler than Yzel; PyPI is the dominant install path users expect.
Stack (locked, validated by /decide ultrathink)
- Python 3.11+ — twikit forces Python; no comparable TS/Node lib for cookie-auth scrape.
- uv — 10–100× pip on resolve/install; deterministic
uv.lock; already user's standard.
- mcp SDK with FastMCP —
@mcp.tool() decorator eliminates ~40 LOC boilerplate per tool.
- twikit — mature Python lib for cookie-based X scrape; D1 invalidation = swap to twscrape on bot-detection.
- hatchling — PEP 621, zero-config, PyPA-preferred for new projects.
Modules to add/modify
| Module |
Change |
Interface |
Owner |
scripts/login_and_save.py |
NEW |
CLI: python scripts/login_and_save.py --out ~/.config/mcp-xee/cookies.json |
None — utility |
scripts/convert_cookies.py |
NEW |
CLI: python scripts/convert_cookies.py cookies.txt --out cookies.json |
None — utility |
docs/cookies.md |
NEW |
Markdown doc, both paths, security tradeoffs |
Docs |
examples/claude_desktop_config.json |
NEW |
Copy-paste config |
Docs |
examples/claude_code_config.md |
NEW |
Claude Code MCP wiring |
Docs |
.github/workflows/ci.yml |
NEW |
uv sync → ruff → pytest, py 3.11/3.12/3.13, ubuntu-latest, on push + PR |
CI |
src/mcp_xee/client.py |
EDIT |
Add MCP_XEE_DEBUG env hook → stderr logger; cleaner error wrapping |
client |
src/mcp_xee/tools.py |
EDIT |
Wrap tool calls so cookie/auth errors return MCP tool error with docs/cookies.md hint |
tools |
tests/test_serialize.py |
NEW |
Mock-tweet → _serialize dict. No live X. |
tests |
docs/release.md |
NEW |
Manual release process: tag → GH release → uv publish |
Docs |
README.md |
EDIT |
Add pip install mcp-xee line once PyPI live |
Docs |
Testing Decisions
- Smoke tests already cover: package imports, server import, tools import, client import,
cookies_path raises without env. Keep.
- Add
test_serialize_minimal_tweet — mock object → _serialize produces expected dict. Tests behavior of the pure function, no live X.
- Add
test_cookies_path_resolves_tilde — env var with ~ → expanded to home.
- Skip live
search / user_tweets integration. Manual local verify pre-tag against @Aiyo91 cookies.
- Prior art: Yzel runs 138 unit tests, no live integration in CI. Same pattern.
Out of Scope (v0.1)
- Posting / DMs / likes / retweets — read-only law (vault D1).
- Multi-account cookie pool — v0.3 conditional on bot-detection signal.
- Listings on mcp.io / glama.ai / smithery.ai — wait for traction (≥10 stars or ≥3 reports).
- Live integration test in CI — recurring cookie liability without strong signal.
- RU/CIS bilingual layer — X audience is global; EN-only is correct for v0.1.
- Release-notes automation — manual for v0.1, automate at v0.2.
- Cookie health-check tool — roadmapped to v0.2.
Further Notes
- twikit deprecation risk: monitored; D1 invalidation triggers swap to twscrape with same tool surface.
- PyPI account: verify
aiyo28 is owned/verifiable before tag. Register if not.
- Test cookies: local-only, never in repo or CI. Use fresh cookies from @Aiyo91 for pre-tag verify.
- Branch strategy: master only for v0.1. Feature branches start at v0.2.
- License: MIT. Donation-only via paypal.me/aiyo28. No paid tiers ever (Path B rule).
Problem Statement
Scaffold is complete and the repo is public with SEO topics applied — but mcp-xee is not yet usable by real users. There is no PyPI distribution, no documented cookie-generation flow, no CI verifying smoke tests on PRs, and no v0.1.0 release tag. A curious developer who finds the repo today still has to clone +
uv sync+ figure out cookie format from twikit's docs. Adoption blocks here.Solution
Ship
v0.1.0as a GitHub release + PyPI publish, with documented cookie-generation paths (both pythonic and browser-export), smoke-only CI on push/PR, copy-paste Claude Desktop / Claude Code config examples, and a debug-logging escape hatch. Skip MCP-catalog listings and CI live integration tests — both gated on traction signals, not present at v0.1.Glossary (Ubiquitous Language)
search+user_tweets.MCP_XEE_COOKIES.twikit.Clientsingleton inside mcp-xeeUser Stories
pip install mcp-xeeso I don't have to clone + uv-sync.client.login()+save_cookies()documented because I trust twikit and want one-shot setup.claude_desktop_config.jsonblock to wire mcp-xee in under 2 minutes.MCP_XEE_DEBUG=1to surface twikit calls to stderr without polluting MCP stdio.Implementation Decisions
Q1 → (c): document both cookie-generation paths
scripts/login_and_save.py— pythonic CLI: prompts for user/pass/email, callsclient.login()+save_cookies(). Password held in memory only.scripts/convert_cookies.py— converts Netscapecookies.txt(from "Get cookies.txt LOCALLY" Chrome extension) → twikit JSON. No password handling.docs/cookies.md— step-by-step for both, with security tradeoffs called out.Q2 → (b): v0.1.0 = GitHub release + PyPI publish
Q3 → No: skip CI live integration
ruff check+pytest(smoke only).Q4 → PyPI now
Stack (locked, validated by
/decideultrathink)uv.lock; already user's standard.@mcp.tool()decorator eliminates ~40 LOC boilerplate per tool.Modules to add/modify
scripts/login_and_save.pypython scripts/login_and_save.py --out ~/.config/mcp-xee/cookies.jsonscripts/convert_cookies.pypython scripts/convert_cookies.py cookies.txt --out cookies.jsondocs/cookies.mdexamples/claude_desktop_config.jsonexamples/claude_code_config.md.github/workflows/ci.ymlsrc/mcp_xee/client.pyMCP_XEE_DEBUGenv hook → stderr logger; cleaner error wrappingsrc/mcp_xee/tools.pydocs/cookies.mdhinttests/test_serialize.py_serializedict. No live X.docs/release.mduv publishREADME.mdpip install mcp-xeeline once PyPI liveTesting Decisions
cookies_pathraises without env. Keep.test_serialize_minimal_tweet— mock object →_serializeproduces expected dict. Tests behavior of the pure function, no live X.test_cookies_path_resolves_tilde— env var with~→ expanded to home.search/user_tweetsintegration. Manual local verify pre-tag against @Aiyo91 cookies.Out of Scope (v0.1)
Further Notes
aiyo28is owned/verifiable before tag. Register if not.