内容
# streamlit-mcp
**将任何 Streamlit 应用作为 MCP 服务器提供服务。** 代理检查您的应用的小部件,
设置值,单击按钮,并读取渲染的输出和 `session_state` — 原生,
通过 MCP,**无需浏览器自动化**。
📖 **文档:** <https://dkedar7.github.io/streamlit-mcp/>
```bash
pip install streamlit-mcp # 或通过运行以下命令无需安装:uvx streamlit-mcp ...
# 通过 MCP 提供应用服务(用于本地客户端的 stdio)
streamlit-mcp serve app.py
# ... 或用于本地网络代理的 HTTP/SSE,循环监听
streamlit-mcp serve app.py --transport http --port 8000
# 直接从终端驱动(使用与代理相同的引擎)
streamlit-mcp inspect app.py
streamlit-mcp call app.py --set "Name=agent" --click "Save" --read
```
Streamlit 没有回调图 — 它在每次交互时重新运行整个脚本 —
因此 streamlit-mcp 通过 Streamlit 自身的测试运行时
(`streamlit.testing.v1.AppTest`)无头驱动应用,并返回 **语义元素树**,
而不是像素。Gradio 和 Dash 已经提供了原生应用即 MCP 服务;这填补了 Streamlit 的空白。
## 演示
一个正常的 Streamlit 应用(人类在浏览器中打开的应用)和代理通过 MCP 对同一应用执行的操作 —
`inspect` 小部件,`call` 设置值 / 点击 / 读取结果。无需浏览器:
<table>
<tr>
<td width="50%"><img src="docs/assets/demo-app.png" alt="浏览器中的 Streamlit 注册表单"></td>
<td width="50%"><img src="docs/assets/agent-view.png" alt="streamlit-mcp CLI 检查和驱动应用"></td>
</tr>
<tr>
<td align="center"><em>人类运行的应用</em></td>
<td align="center"><em>代理通过 MCP 看到的内容</em></td>
</tr>
</table>
人类也可以通过一个 `with` 块(`from streamlit_mcp.live import live`)实时观察代理的工作 —
无需刷新,无需浏览器自动化。参见
[实时/人机协作指南](https://dkedar7.github.io/streamlit-mcp/live/)。
## 与 MCP 客户端一起使用
**Claude Desktop / Cursor** — 添加到您的 MCP 配置(`claude_desktop_config.json` 或
`.cursor/mcp.json`):
```json
{
"mcpServers": {
"streamlit-mcp": {
"command": "uvx",
"args": ["streamlit-mcp", "serve", "/绝对路径/到/您的/app.py"]
}
}
}
```
**Claude Code:**
```bash
claude mcp add streamlit-mcp -- uvx streamlit-mcp serve /绝对路径/到/您的/app.py
```
`uvx` 运行已发布的软件包,无需事先安装。stdio(默认)是本地客户端的正确传输方式。
## 向代理公开的工具
| 工具 | 功能 |
|---|---|
| `list_widgets` / `get_layout` | 检查小部件(类型,标签,值,约束) |
| `set_widget(identifier, value)` | 设置小部件并重新运行 |
| `click(identifier)` | 点击按钮并重新运行 |
| `read_output()` | 渲染的元素树,代理可读 |
| `get_state()` | 应用的 `session_state` |
支持的小部件:text_input, number_input, text_area, slider, select_slider, selectbox,
multiselect, checkbox, toggle, radio, button, date_input, time_input, color_picker, pills,
segmented_control, feedback — 包括它们的双手柄 **范围** 形式(`st.slider("价格", 0, 100, (20, 80))`,
`st.date_input("日期", (start, end))`),它们提供一个 2 元素数组模式并接受
`[low, high]`。`st.form` 由人类驱动的方式驱动:设置字段,然后单击表单的提交按钮。
streamlit-mcp 无法驱动的输入小部件(file_uploader, camera_input, audio_input, chat_input,
data_editor, …)在所有界面上明确报告(文本 `--layout`,
`--json`,MCP `get_layout`),从不静默丢弃 — 无论它们放置在哪里,包括
`st.sidebar.file_uploader(...)` 和在列,选项卡和容器内。
## 自定义语义工具
除了每个小部件的工具外,还可以通过在应用文件中用
`@mcp_tool` 装饰函数来公开更高级别的命名操作:
```python
import streamlit as st
from streamlit_mcp import mcp_tool
@mcp_tool
def reset_all():
"""将所有内容重置为默认值。"""
return {"ok": True}
st.text_input("名称")
```
`streamlit-mcp serve app.py` 加载应用并通过 MCP 公开 `reset_all` 以及小部件工具。
被装饰的函数直接调用(它不是小部件),因此请保持其自包含。
它也可以从 CLI 访问(人类 ↔ 代理对等):`streamlit-mcp inspect app.py` 列出它,
`streamlit-mcp call app.py --tool reset_all` 调用它。
## 人类 ↔ 代理对等
代理通过 MCP 可以做的所有事情,人类都可以通过 CLI 完成 — 两者调用相同的引擎。
只读模式和小部件允许列表防护措施在两个界面上相同。如果提供的应用引发异常,
则在所有界面上报告异常 — `--json`,
MCP `read_output`/`get_layout` 和文本 CLI — 并且 `call`/`inspect --strict` 在应用异常时退出
非零(用于 CI/脚本)。
## 安全/信任模型
- **`app_path` 在服务器进程中作为受信任的代码执行** (这是 AppTest
运行它的方式)。仅提供您信任的应用。
- **`get_state` / `read_output` 公开应用的 `session_state`** 给调用者 — 不要
将秘密放在那里。
- **强制执行 HTTP/SSE 持有者身份验证。** 传递 `--bearer-token <T>` 并且每个 HTTP/SSE 请求
必须发送 `Authorization: Bearer <T>` — 缺失或错误的令牌会得到 `401` 然后任何工具
运行前。对于非循环监听的主机,仅允许设置令牌;如果没有设置令牌,`serve` 绑定
到 `127.0.0.1` 并且拒绝非循环监听主机(失败关闭)。stdio 是本地且
无身份验证的。
## 已知限制
- **会话不会被释放。** 每个客户端的隔离有效,但没有会话关闭
钩子,因此长时间运行的 HTTP 服务器累积每个客户端一个运行时。stdio 和
单客户端使用不受影响。
- **没有并发锁定。** 共享一个会话的并发请求不会序列化,并且
`AppTest` 不被认为是可重入的 — 目前使用每个会话一个请求。
- **输出捕获** 涵盖标题/降价/标题/文本;`st.write`,`st.error` 和
相似的正在计划覆盖范围。
## 许可证
MIT