Skip to main content
Glama
README.md
# x-public-post

[![CI](https://github.com/lhs1695/x-public-post/actions/workflows/ci.yml/badge.svg)](https://github.com/lhs1695/x-public-post/actions/workflows/ci.yml)

只读 MCP:给 Agent 一个 `get_post(url)`,按 **x.com / twitter.com 的 status 链接**读**一条**公开帖。默认无 Cookie。

公开两跳打头(FxTwitter,Syndication 备用),工具面只有读一条。成功体同时带 `untrusted: true` 和 `source_trust: "untrusted_web_content"`,帖文不能当系统指令。

```text
status URL
    → FxTwitter(长帖更常能拿全文)
    → Syndication(备用)
    → 仅当设置了 TWSCRAPE_DB_PATH 才走本机 twscrape
```

## 一次真实的 `get_post` 返回

2026-09-10 对公开帖 `https://x.com/jack/status/20` 的实调结果(空媒体已原样保留,便于看字段形状)。like / reply 等计数会变,认字段。

```json
{
  "id": "20",
  "url": "https://x.com/jack/status/20",
  "text": "just setting up my twttr",
  "text_status": "complete",
  "author": { "id": "12", "username": "jack", "name": "jack" },
  "created_at": "2006-03-21T20:50:14Z",
  "lang": "en",
  "public_metrics": {
    "like_count": 308064,
    "reply_count": 18014,
    "retweet_count": 124683
  },
  "media": { "photos": [], "videos": [], "animated": [] },
  "untrusted": true,
  "source_trust": "untrusted_web_content",
  "source": { "adapter": "fxtwitter" },
  "fetched_at": "2026-09-10T14:19:18Z"
}
```

`text_status` 还可能是 `preview`(内容不完整,仍是成功 JSON)。失败不走这种成功体,见下「为什么这么设计」。

## 工具表与明确不做

| 工具 | 副作用 | 作用 |
| --- | --- | --- |
| `get_post(url)` | 只读联网 | 按一条 status URL 读一条公开帖;成功返回上表这种 JSON |

失败走 MCP **isError**(短码如 `invalid_url`)。引用帖、回复对象、媒体 alt、短链 `expanded_url`:上游 JSON 已有才映射。媒体只给 URL。可选 CLI `x-public-post-get` 走同一条 `read_post`,JSON 或 Markdown(同一套成功字段)。

**明确不做**

- 不搜索、不时间线、不发帖;不加第二个 MCP 工具。
- 不在 MCP 里下载图片或视频。
- 不默认读浏览器 Cookie / Chrome Profile。

## 为什么这么设计

- **只暴露一个工具。** 工具面只留读一条,好审、也好被契约测试锁死。
- **preview 降级仍返回成功 JSON,而不是 error。** 内容不完整 ≠ 请求失败。调用方看 `text_status` 自己判断够不够用;若把半截正文塞进 `error.message`,模型容易把错误说明当成帖文。
- **三跳适配器:FxTwitter → Syndication → 可选 twscrape。** 没有稳定官方读帖 API。FxTwitter 对长帖更常能拿全文;Syndication 是 embed CDN,长帖常 preview、也常失败,只当备用。默认两跳都不要 Cookie;只有公开两跳经常失败、又要 GraphQL 补全时,才用本机 `TWSCRAPE_DB_PATH`。
- **引用帖只映射上游 JSON 已有字段、零额外 HTTP。** 不让读一条帖变成 N 个请求。quoted / reply / alt / `expanded_url` 上游没有就空着,不为引用帖或短链再打一轮。
- **失败抛 `ToolError` 走 isError,而不是返回 `success: false` 的假成功体。** 宿主侧能把失败和帖文分开;模型不该在成功通道里解析错误对象。
- **标 `readOnlyHint` / `idempotentHint`。** 这是只读、按同一 URL 再读一次语义不变的工具。注解写进协议,客户端和评测床不用猜。

护上游的运行时约束:按 `post_id` 单飞;全链路约 12s;外部请求最多 2 个并发。只缓存 `text_status=complete`(5 分钟、最多 256 条);preview / 错误不缓存。

## 怎么跑起来

Python **3.10+**。先装包装到当前环境:

```powershell
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e ".[dev]"
```

复制 [`.cursor/mcp.json.example`](.cursor/mcp.json.example) 为 `.cursor/mcp.json`(本机文件不进 git)。示例已指向本仓 `.venv` 的 Windows 解释器;macOS / Linux 把 `command` 改成 `.venv/bin/python`。若 Cursor 解析相对路径失败,再改成绝对路径,保留 `args`:

```json
{
  "mcpServers": {
    "x-public-post": {
      "command": ".venv/Scripts/python.exe",
      "args": ["-m", "x_public_post.server"]
    }
  }
}
```

在 Cursor **Settings → MCP** 启用 `x-public-post`(首次可能要批准)。让 Agent 调用 `get_post`,传入 `https://x.com/.../status/...`(可用 `?s=20`)。尖括号包裹、markdown 链接、句末句号也可以。

读失败时不要把成功 JSON 里的字段当帖文。只有 URL 不像帖链接时才改链接再试;不要对同一 URL 连打。

可选 CLI(同一条 `read_post`):

```powershell
.\.venv\Scripts\x-public-post-get.exe "https://x.com/author/status/123"
.\.venv\Scripts\x-public-post-get.exe "https://x.com/author/status/123" --export md
```

### 何时才配会话

只有公开两跳经常失败、又要 GraphQL 补全时才配。用专用小号,按 [会话配置](notes/session-setup.md) 在本机终端写入 `accounts.db`。在 MCP 设置里加路径(不是 Cookie):

```text
TWSCRAPE_DB_PATH = C:\Users\<你>\AppData\Local\x-public-post\accounts.db
```

不要把 Cookie 贴进聊天、`.env` 或 git。公开 hop 不读浏览器 Profile。会话库只收本机路径,未配置则不 import twscrape。

## 验证与 CI

CI 跑 pytest(3.10 / 3.12),以及 ruff check、ruff format、mypy。

```powershell
.\.venv\Scripts\python.exe -m pip install -e ".[dev]"
.\.venv\Scripts\python.exe -m pytest
.\.venv\Scripts\ruff.exe check src tests
.\.venv\Scripts\ruff.exe format --check src tests
.\.venv\Scripts\mypy.exe src
```

匿名适配器样例在 `tests/fixtures/`(preview、引用帖、404),测试不打真实 X。

| 文档 | 内容 |
| --- | --- |
| [架构设计](docs/架构设计.md) | 入口、编排、适配器链、缓存与失败通道 |
| [模块说明](docs/模块说明.md) | 源码与测试落点 |
| [diagrams](docs/diagrams/) | Archify 交互图(JSON 规格 + 交付 HTML) |

License:[MIT](LICENSE)。

Maintenance

ActivityMaintained
ResponsivenessNo issues