shuiyuan-mcp-lite
Provides read-only tools for interacting with a Discourse-based community, including searching topics, reading posts and user profiles, and listing categories and tags.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@shuiyuan-mcp-litesearch for posts about MCP in category 29"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
shuiyuan-mcp-lite
面向上海交通大学水源社区的轻量级、只读 标准 MCP Server。使用 Python、官方 MCP Python SDK 和异步 httpx,通过 stdio 接入 AstrBot 或其他 MCP Host,无 AstrBot 专用依赖。
安装与启动
需要 Python 3.12+ 和 uv。在仓库目录执行:
uv sync
uv run shuiyuan-mcp首次使用先运行 uv run shuiyuan-mcp auth login 完成鉴权配置。
启动后等待 Host 通过 stdin 发送 MCP 消息,无交互提示,也不会主动请求水源。stdout 仅用于 MCP 协议;日志写入 stderr。直接在终端运行时没有输出属于正常情况。Host 关闭输入后进程退出。
依赖版本记录在 uv.lock。部署可执行 uv sync --locked --no-dev;安装后的 CLI 名称为 shuiyuan-mcp。当前锁定官方 SDK 的 1.x 维护版本(mcp>=1.26,<2),不依赖独立的 fastmcp 包。
Related MCP server: UWaterloo MCP
配置
服务配置来自环境变量;Cookie 凭据存储在登录文件中,不自动加载 .env 文件。水源帖子需要登录权限,未配置有效凭据时工具会提示先登录,不再尝试匿名读取。
环境变量 | 默认值 | 说明 |
|
| 水源部署的 HTTP(S) 地址,不可含用户名、密码、查询参数或 fragment |
| 空 | 可选 Discourse User API Key;配置后优先于 Cookie 文件 |
| 空 | 可选客户端 ID,仅配置 key 时发送 |
|
| 用户提供的水源登录文件;支持 XDG_CONFIG_HOME,Windows 使用 APPDATA |
配置 key 后通过 User-Api-Key 请求头鉴权,配置 client ID 后同时发送 User-Api-Client-Id。请使用具有所需读取权限的 key;内容可见性仍受站点权限控制。登录失效时会提示重新登录,不会自动操作 jAccount。
本项目不保存 jAccount 密码、不自动读取浏览器 Cookie、不硬编码或记录完整凭据。
首次登录(推荐,容器也可用)
uv run shuiyuan-mcp auth login
uv run shuiyuan-mcp auth status登录命令提供中文步骤:在自己的浏览器手动登录水源,按 F12 打开开发者工具,在 Application(应用)或 Storage(存储)的 Cookies 下选择水源域名,复制 _t 的 Value,粘贴到终端。还可输入 _forum_session(可选)。输入不回显,也不放入命令行参数;不要将 Cookie 发给聊天机器人。
命令通过 GET /session/current.json 验证身份,成功后才保存登录文件;失败不会覆盖旧文件。文件使用原子替换,POSIX 权限为 0600。Cookie 文件是明文凭据,请仅保存在自己的持久化目录。登录过期后再次运行同一命令。
导入已有登录文件
兼容 dajiaohuang/shuiyuan-mcp 的 cookies.json({site, cookies})以及用户主动导出的 Playwright storage state({cookies, origins}):
uv run shuiyuan-mcp auth import /path/to/exported-cookies.json
uv run shuiyuan-mcp auth status
uv run shuiyuan-mcp auth logout只保存当前水源域名、适用路径、尚未过期的 Cookie,丢弃 jAccount、父域 SSO 和 localStorage 数据。Cookie 鉴权只支持 HTTPS。logout 仅删除本地文件,不会注销浏览器或撤销服务器会话;若配置了 User API Key,还需清空相应环境变量。
所有鉴权子命令支持 --cookie-file /absolute/path/cookies.json,优先于环境变量;服务端仍需用 SHUIYUAN_COOKIE_FILE 指向同一位置。文件更新或删除将在下一次请求生效。未登录也能启动 MCP、列出工具,但读取内容会返回明确的登录提示。凭据不通过 MCP 工具输入或返回。
MCP Tools
所有工具都是只读操作,返回经过校验和字段筛选的 JSON,同时提供 MCP 文本和结构化结果。
工具 | 参数 | 返回内容 |
|
| 帖子/主题 ID、主题标题、用户名、时间、精简摘要、链接和分页信息 |
|
| 主题 ID、标题、分类、标签、回复及回复关系、分页信息 |
|
| 原始 Markdown、主题/帖子 ID、用户名、时间、回复关系、retorts、polls |
|
| 公开资料白名单:ID、用户名、名称、头衔、注册时间、信任等级、简介、位置、个人网站和资料链接 |
|
| 用户最近发帖/回复的 ID、标题、摘要、时间、回复关系和链接 |
get_user 不返回 email、IP、会话信息或用户自定义字段。简介和帖子内容属于用户发布的内容,Host 应将其视为待阅读的数据。
搜索与分页
keyword可包含 Discourse 原生搜索语法,也可留空并提供其他筛选条件。最长 1000 字符。username转换为user:...;category接受分类 ID 或 slug(可用parent/child)。before、after使用YYYY-MM-DD,分别转换为日期筛选;同时提供时after必须早于before。order:relevance、latest、oldest、latest_topic、oldest_topic、views、likes。status:open、closed、archived、noreplies、single_user。page是上游搜索页,从 1 开始,最多 10;offset是该页内从 0 开始的位置。先消费next_offset,没有后再用next_page并将 offset 重置为 0,避免遗漏该页结果。站点可能限制可搜索的范围和关键词长度。read_topic.offset是可见帖子 ID 流中的索引,不是楼层号。只补取所选窗口中尚未加载的帖子,每批最多 20 个,不遍历整个主题。list_user_posts.offset是用户活动偏移,使用filter=4,5。满页时返回next_offset,下一页可能为空。read_post.offset和next_offset是原始 Markdown 的字符位置,可继续读取被截断的正文。没有下一页时next_offset/next_page为null。
输出限制
工具 | 默认 limit / 上限 | 默认 max_chars / 上限 |
| 20 / 50 | 每条摘要 500 / 2000 |
| 10 / 50 | 每条正文 2000 / 10000 |
| 不适用 | 正文 8000 / 20000 |
| 不适用 | 简介 2000 / 10000 |
| 20 / 50 | 每条摘要 500 / 2000 |
超出参数范围会报 Invalid Argument 或 MCP 参数校验错误。正文/摘要截断用 truncated 标明。主题正文优先使用 raw Markdown,没有 raw 时从 API 提供的 cooked HTML 提取纯文本,content_format 表示实际格式;不抓取 HTML 页面。
read_post 中缺失或为 null 的 retorts、polls 返回空列表,不依赖 polls_votes。retorts 仅包含 emoji、usernames;polls 仅包含 title、options[{text,votes}]。上游隐藏票数时 votes 为 null,不会伪装成 0。
单帖插件元数据最多返回 50 种 retort、每种 100 个用户名、10 个投票、每个投票 100 个选项;emoji、投票标题和选项文本分别最多 100、300、500 字符。裁剪时设置 metadata_truncated。其他标题、个人资料短文本和资源描述也有固定长度限制。
MCP Resources
URI | API | 内容 |
|
| 可见分类 ID、名称、slug、父分类、简短描述 |
|
| 可见标签 ID、名称、主题计数;合并分组标签并去重 |
资源 MIME 类型为 application/json,保持只读。分类最多 500 条、标签最多 1000 条,返回 total 与 truncated;不返回原始站点配置。这两个固定资源不提供分页,total 指本次上游响应中可见的数量。
AstrBot 配置
先将项目放到 AstrBot 能访问的目录并运行 uv sync,再填写 stdio MCP 配置:
{
"command": "uv",
"args": [
"--directory",
"/AstrBot/data/mcp/shuiyuan-mcp",
"run",
"shuiyuan-mcp"
]
}将目录替换为实际绝对路径。AstrBot 进程需要能在 PATH 中找到 uv,否则将 command 改成 uv 的绝对路径。通过 Host 的环境变量配置向子进程传入登录文件路径,或可选的 key 和 client ID。其他支持 stdio 的 MCP Host 可复用相同 command/args。
Docker 容器内克隆
在运行 AstrBot 的容器内执行以下命令(需要 git、uv 和 Python 3.12+):
mkdir -p /AstrBot/data/mcp
git clone https://github.com/Cashrel894/shuiyuan-mcp-lite.git /AstrBot/data/mcp/shuiyuan-mcp-lite
cd /AstrBot/data/mcp/shuiyuan-mcp-lite
uv sync --locked --no-dev也可以从宿主机先用 docker exec -it <容器名> sh 进入容器,再执行上述命令。确认 /AstrBot/data 对应实际的持久化挂载目录,且 AstrBot 运行用户对项目目录有读写权限。
在容器交互终端中完成登录,保存到持久化目录:
export SHUIYUAN_COOKIE_FILE=/AstrBot/data/shuiyuan-auth/cookies.json
.venv/bin/shuiyuan-mcp auth login
.venv/bin/shuiyuan-mcp auth status没有交互终端时,可将自己导出的 Cookie 文件复制到容器,再执行 auth import /path/to/exported-cookies.json。不要把凭据提交到仓库。
安装后直接使用虚拟环境中的入口,并明确配置登录文件:
{
"command": "/AstrBot/data/mcp/shuiyuan-mcp-lite/.venv/bin/shuiyuan-mcp",
"args": [],
"env": {
"SHUIYUAN_COOKIE_FILE": "/AstrBot/data/shuiyuan-auth/cookies.json"
}
}这是 AstrBot 所在容器内的路径。虚拟环境应在该容器中创建;不要复制宿主机的 .venv。更换容器基础镜像或 Python 后应重新创建虚拟环境并安装依赖。无需新增端口映射,AstrBot 会启动 stdio 子进程。
更新代码时在仓库目录执行 git pull --ff-only 和 uv sync --locked --no-dev,然后在 AstrBot 中重新连接此 MCP Server。
错误和网络行为
区分 Not Found(404)、Authentication Required(401 / 登录重定向)、Permission Denied(403)、Rate Limited(429)、Shuiyuan Unreachable(连接故障 / 5xx)、Timeout、Unexpected API Response(意外状态码 / JSON / schema)。工具错误作为 MCP isError=true 返回;资源错误作为 MCP 错误返回。错误不附带上游响应正文或完整 Python traceback。
HTTP 客户端最多 4 个连接、4 个并发请求,连接超时 10 秒,其他 HTTP 阶段超时 20 秒;不自动重试、不跟随重定向。遇到限流应等待后再由 Host 重试。
开发与验证
uv sync --locked
uv run ruff format
uv run ruff check
uv run pytest测试使用 httpx.MockTransport,阻止测试进程中的真实 HTTP 请求。覆盖查询构造、数据精简、主题补页、插件字段缺失、鉴权头、敏感字段过滤、并发限制、错误映射、MCP 工具/资源调用,以及通过 uv run --offline shuiyuan-mcp 启动子进程后的真实 stdio 握手。CLI 测试只列出能力并提交无效参数,不访问真实水源。
src/shuiyuan_mcp/server.py:工具、资源和 CLI。src/shuiyuan_mcp/client.py:异步 HTTP、分页、结果精简和错误映射。src/shuiyuan_mcp/models.py:上游响应校验、API HTML 的纯文本转换。src/shuiyuan_mcp/config.py:环境变量配置。src/shuiyuan_mcp/auth.py、credentials.py:交互鉴权、在线检查、登录文件导入和保存。tests/:mock 和协议测试。
开发遵循 AGENTS.md 中的 YAGNI 和 Conventional Commits 约定,范围见 MVP 文档。
已知限制
自动测试没有使用真实水源账号;线上访问能力取决于站点版本、权限、限流和网络条件。
只提供 stdio 和读取能力,不实现写操作、Chat、admin API、批量爬取、Web UI 或部署编排。
不自动获取或刷新 User API Key;Cookie 失效时需要用户重新提供。
搜索摘要是上游摘要,可能已被上游截断;完整内容请用
read_post。主题读取期间若帖子被删除或可见性变化,可能返回响应不一致错误,重新读取即可。cooked HTML 的纯文本回退不保留完整排版;没有 raw 的单帖响应会报告异常,不把 HTML 冒充 Markdown。
插件元数据和资源的固定上限不支持继续翻页;输出会标明截断。
接口依据
Available Tools
5 toolsget_userBRead-only
Get allowlisted public profile fields; max_chars limits the biography.
| Name | Required | Description | Default |
|---|---|---|---|
| username | Yes | ||
| max_chars | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, and destructiveHint=false, so the safety profile is covered. The description adds that only 'allowlisted public' fields are exposed, which is real behavioral context about data filtering. It says nothing about auth requirements, rate limits, or error behavior, so it is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence with the core purpose front-loaded and the parameter note appended after a semicolon. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return shape need not be explained, and the 'allowlisted public fields' phrase usefully hints at the response scope. However, with 0% schema description coverage, the description leaves username and the interaction of max_chars with the biography only lightly addressed, which is thin for a two-parameter tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the burden. It does explain that max_chars limits the biography, adding meaning beyond the bare 'Max Chars' title and its 1–10000 bounds. username is left unexplained, though its meaning is self-evident from the name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Get') and resource ('public profile fields') and adds the meaningful qualifier 'allowlisted', which scopes what is returned. It does not differentiate from siblings like read_post or list_user_posts, but the purpose itself is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus search, read_topic, or list_user_posts. The only hint at a condition is that fields are 'public'/'allowlisted', which is a scope statement rather than usage routing. An agent must infer context entirely.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_user_postsARead-only
List recent topics/replies by a user; offset counts activities from 0.
max_chars limits each excerpt. A full page offers next_offset; the next page may be empty.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No | ||
| username | Yes | ||
| max_chars | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint=true, destructiveHint=false, openWorldHint=true), and the description adds real behavioral detail beyond them: offset counts activities from 0, max_chars truncates excerpts, a full page returns next_offset, and the next page may legitimately be empty. Auth/rate-limit behavior is not covered, keeping it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight clauses, front-loaded with the core purpose before the pagination and truncation caveats. No wasted words, though the fragmentary phrasing is slightly terse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and the mention of next_offset plus the possibility of an empty next page gives the pagination context an agent needs. The remaining gap is the undocumented limit/username semantics.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must carry parameter meaning. It explains offset (indexed from 0 over activities) and max_chars (per-excerpt character cap), but says nothing about how limit interacts with pagination or the username parameter, leaving two of four parameters undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'List recent topics/replies by a user', which is a clear read operation on user-scoped content. It implicitly separates from siblings like read_post/read_topic (single-item reads) and search (query-driven), but never names an alternative explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: an agent can infer this is the tool for enumerating one user's activity, but there is no when-to-use vs search/get_user guidance and no prerequisites (e.g. whether the user must exist).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_postARead-only
Read raw Markdown, retorts and polls for a post ID (not a topic/post number).
offset/next_offset are character positions in raw text. Missing plugins return []. Hidden poll vote counts return null. Plugin metadata has fixed size caps.
| Name | Required | Description | Default |
|---|---|---|---|
| offset | No | ||
| post_id | Yes | ||
| max_chars | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, openWorld, and destructive=false, so the safety profile is covered. The description adds useful edge-case behavior: missing plugins return [], hidden poll vote counts return null, and plugin metadata has fixed size caps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded, then offset semantics, then edge cases, with no filler. Mentioning next_offset, which is not in the input schema, introduces minor ambiguity that keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value explanation is largely unnecessary, and annotations cover safety. The description adequately covers raw content, offset semantics, and common edge cases, though max_chars remains undocumented.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate. It explains offset/next_offset as character positions and clarifies post_id must be a post ID rather than a topic/post number, but max_chars is left unexplained and next_offset is not an input parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb 'Read' and resources 'raw Markdown, retorts and polls' for a post ID. The parenthetical 'not a topic/post number' distinguishes it from sibling read_topic without needing to open either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides an input-type constraint (post ID, not topic/post number) that implies when the tool is appropriate. However, it never names alternative tools or states explicit when-to-use/when-not conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_topicARead-only
Read a topic and replies. offset is a 0-based index in the visible post stream.
max_chars limits each post. Use read_post to read the remainder of truncated posts. Returns Markdown when available, otherwise plain text extracted from API HTML.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No | ||
| topic_id | Yes | ||
| max_chars | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, non-destructive, openWorld), and the description adds genuinely useful behavior: truncated posts use read_post, and output is Markdown when available else plain text from API HTML. It doesn't mention rate limits or pagination termination, but the added context is solid.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences with no filler, leading with the core action and then pagination and truncation details. Efficient and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values needn't be spelled out, yet the description still explains the output format. Combined with offset/max_chars semantics and the read_post handoff, an agent has enough to invoke it correctly, though limit remains unexplained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the burden. It defines offset ('0-based index in the visible post stream') and max_chars ('limits each post'), but limit and topic_id are left entirely to the schema titles, leaving half the parameters semantically thin.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Read a topic and replies') and distinguishes itself from the sibling read_post by pointing to it for truncated remainder. It could be sharper about what a 'topic' means in this domain, but the scope is clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains when to use read_post (for the remainder of truncated posts) and clarifies pagination via offset, giving clear context. No explicit when-not conditions or prerequisites, so it falls just short of full guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchBRead-only
Search topics/posts. Dates: YYYY-MM-DD; category: ID or slug (parent/child).
keyword accepts Discourse search syntax. page is 1-based; offset is within that upstream page. Consume next_offset before next_page (reset offset to 0). max_chars limits each excerpt. Search availability depends on site permissions.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| after | No | ||
| limit | No | ||
| order | No | ||
| before | No | ||
| offset | No | ||
| status | No | ||
| keyword | No | ||
| category | No | ||
| username | No | ||
| max_chars | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint, openWorldHint and destructiveHint=false, so safety is covered. The description adds real value with a pagination consumption protocol ('consume next_offset before next_page, reset offset to 0') and a permission-dependent availability note, but says nothing about result shape or rate/limit behavior beyond that.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense, telegraphic and front-loaded: purpose first, then the parameter/pagination facts in short clauses. Nearly every clause earns its place, though the offset/next_offset sentence is compressed enough to require a careful read.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter search tool with an output schema (so return values need no explanation), the description covers pagination and the highest-risk parameter formats. It omits what order, status and username actually do, leaving meaningful filtering behavior undocumented.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 11 parameters, so the description carries the full burden and does most of it: date format for after/before, category as ID or slug with parent/child, Discourse syntax for keyword, 1-based page, offset-within-page, and max_chars as per-excerpt limit. limit, order, status and username remain undocumented anywhere.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Search topics/posts'), and the resource scope is plainly broader than the single-item siblings (read_topic, read_post, get_user). It never names an alternative explicitly, so the differentiation is inferable rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use search vs the sibling lookup tools, and no exclusions. 'Search availability depends on site permissions' is a caveat about feasibility, not usage guidance, so the agent is left to infer routing on its own.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
get_user - First observed
list_user_posts - First observed
read_post - First observed
read_topic - First observed
search
TDQS
Scored across 5 tools
Each tool maps to a distinct resource or action: search for content discovery, read_topic for whole threads, read_post for individual raw posts, get_user for profiles, and list_user_posts for user activity. The descriptions explicitly clarify the boundaries between read_topic and read_post as well as search and list_user_posts, so an agent can select confidently.
All tool names use snake_case and are immediately readable, but the pattern is not perfectly uniform: search is a bare verb while the others are verb_noun, and the verbs vary (read, get, list). This is a minor deviation that does not cause confusion.
Five tools is well-scoped for a lite read-only forum client. Each tool covers a distinct need—search, topic reading, post reading, user profile, and user activity—without redundancy or obvious padding.
The surface covers the core read-only lifecycle: search, view topics, view individual posts, view user profiles, and list user activity. Minor gaps exist, such as no direct category/tag listing or site metadata endpoint, but agents can work around these via search.
Maintenance
Related MCP Connectors
Lemmy MCP — public reads on any Lemmy instance.
Read public research communities, attributable agent activity and discussion threads.
Read-only MCP gateway. Paid verify is $0.01 USDC on Base.
Read-only MCP tools for AI agent discovery, structured resources, and NIULAI information.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables read-only queries of i桂航 campus data, including schedules, classes, terms, and campus information through MCP tools.-
- AlicenseNot gradedqualityBmaintenanceEnables read-only access to University of Waterloo Learn and Piazza, allowing users to view courses, assignments, grades, submissions, discussions, and more through an MCP server.MIT
- FlicenseNot gradedqualityBmaintenanceEnables read-only retrieval of public web pages through MCP, with SSRF protection, no cookies or login state, and specialized anonymous parsing for Xiaohongshu, plus an opt-in Jina Reader fallback.-
- AlicenseNot gradedqualityBmaintenanceEnables read-only monitoring of Xianyu (Goofish) listings, item details, chats, and account status through MCP tools for DeepSeek Harness.81 npmMIT