使用说明
MCP聊天
本项目基于并修改自 人类学在线学习课程原版通过Google Vertex AI使用了Anthropic的Claude;此版本已迁移为使用OpenAI API。
MCP Chat是一个用于交互式AI聊天的命令行界面应用程序,由OpenAI模型提供支持。它支持通过以下方式进行文档检索 @mentions,基于命令的提示通过 /commands,以及通过MCP(模型上下文协议)架构的可扩展工具集成。
先决条件
- Python 3.10+
- 一 OpenAI API密钥
设置
步骤1:配置环境变量
创建或编辑 .env 项目根目录中的文件:
OPENAI_API_KEY="sk-..." # Your OpenAI API key
OPENAI_MODEL="gpt-4o-mini" # Or any other OpenAI model (e.g. gpt-4o)
USE_UV=1 # Set to 0 if not using uv
步骤2:安装依赖项
选项1:使用紫外线(推荐)
紫外线 是一个快速的Python包安装程序和解析器。
- 如果尚未安装,请安装uv:
pip install uv
- 安装依赖项:
uv sync
- 运行项目:
uv run main.py
选项2:使用普通pip
- 创建并激活虚拟环境:
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
- 安装依赖项:
pip install openai python-dotenv prompt-toolkit "mcp[cli]>=1.8.0"
- 运行项目:
python main.py
用法
基本聊天
键入您的信息,然后按Enter键:
> What is the capital of France?
文献检索
使用 @ 后面是文档ID,以便在查询中包含文档的内容:
> Summarize @deposition.md
文档直接注入到提示符中,不需要额外的工具调用。
命令
使用 / 运行MCP服务器中定义的预定义提示命令:
> /summarize deposition.md
按 Tab 自动完成可用命令和文档ID。
加载其他MCP服务器
启动应用程序时,将额外的服务器脚本作为参数传递:
uv run main.py my_custom_server.py
MCP 检查员
MCP Inspector是一个基于浏览器的工具,用于检查和测试您的MCP服务器——您可以浏览可用的工具、资源和提示,并在不运行完整应用程序的情况下以交互方式调用它们。
要启动它:
uv run mcp dev mcp_server.py
然后打开终端中显示的URL(通常 http://localhost:5173)在您的浏览器中。
使用检查器的提示
- 通话时
read_doc_contents,使用包括扩展名在内的完整文件名作为doc_id例如。deposition.md. - 可用的文档ID包括:
deposition.md,report.pdf,financials.docx,outlook.pdf,plan.md,spec.txt.
为什么编辑不会出现在 mcp_server.py
你可能会注意到,打电话后 edit_document 在检查员中 docs 里面的字典 mcp_server.py 不会改变。这是意料之中的,理解为什么是一个有用的教训。
这 docs 迪克住在 存储器(RAM),不在文件中。当服务器启动时,Python读取 mcp_server.py 和负载 docs 进入记忆。 edit_document 修改内存中的副本,这就是为什么后续 read_doc_contents 调用返回更新的内容。但源文件本身从未被触及——它只是食谱书。厨师在记事本上写字,而不是回到书上。
重新启动服务器时,记事本会被丢弃 docs 从原始源文件重新加载,因此所有编辑都消失了。
这是当前设计的一个已知局限性。如果您希望编辑在重新启动后仍然有效, docs 需要由真实的存储(JSON文件、SQLite等)而不是内存中的字典来支持。
端到端测试
验证整个系统是否正常工作的最快方法是按顺序运行以下五种情况:
1.基本聊天 --确认OpenAI连接
> What is 1 + 1?
2. @ 文件注入 --确认MCP服务器正在运行,文档内容已注入提示
> What is @deposition.md about?
3.工具使用 --确认代理循环、ToolManager和MCP工具执行均正常工作
> Use the read_doc_contents tool to read report.pdf and tell me what it says.
4.工具使用+编辑 --确认多回转刀具的使用和内存编辑
> Use edit_document to change the word "condenser" to "cooling" in report.pdf, then read it back to confirm.
5. / 命令 --确认MCP提示检索和完整的命令管道
> /format financials.docx
每个案例都练习堆栈的不同层。如果所有五个都通过,则验证整个端到端流。
期间会发生什么 /format
这 /format 命令很好地说明了所有层是如何协同工作的:
_process_command()在core/cli_chat.py检测/前缀并获取format来自MCP服务器的提示- 提示指示模型使用Markdown重新格式化文档并使用
edit_document保存结果的工具 - 模型调用
edit_document--代理循环core/chat.py检测finish_reason == "tool_calls"并执行该工具 - 结果被添加回消息历史记录中,循环再次运行,模型输出最终格式化的文档
有一件事需要注意: 如果原始文档很短(如 financials.docx,这只是一句话),该模型可能会发明听起来合理的内容——预算数字、类别等。--来源中不存在。这是LLM的正常行为:当信息稀疏时,模型会填充看似合理的内容,而不是说“我不知道”
在实际应用中,通过在提示符中添加显式指令来防止这种情况: 仅使用文档中已有的信息,不要添加任何新内容。
为什么你只需要跑 main.py
你可能会想知道为什么 mcp_server.py 和 mcp_client.py 不需要单独启动。答案就在 main.py --它发射 mcp_server.py 自动作为a 子进程:
command, args = ("uv", ["run", "mcp_server.py"])
doc_client = await stack.enter_async_context(
MCPClient(command=command, args=args)
)
MCPClient.connect() 将此命令交给操作系统,操作系统将启动 mcp_server.py 作为背景过程。然后,这两个过程会相互讨论 stdin/stdout --这是MCP的stdio传输。
You run: uv run main.py
│
├── spawns subprocess ──→ mcp_server.py (background process)
│ ↑ ↓ stdin / stdout
└── MCPClient ─────────────────┘
(mcp_client.py, imported as a class)
mcp_server.py是 由...推出main.py--你从不手动启动它mcp_client.py是 作为类导入 --这不是你运行的脚本- 当
main.py退出后,子流程将通过以下方式自动清理AsyncExitStack
使用stdin/stdout作为传输的原因是,它使MCP服务器与语言无关——服务器可以用Python、Node.js或Rust编写。只要它在标准I/O上讲MCP协议,客户端就不在乎。
发展
添加新文档
编辑 docs 字典在 mcp_server.py 添加新文档。
添加新的MCP服务器
任何实现MCP协议的Python脚本都可以作为参数传递给 main.py每个服务器都作为自己的子进程运行,并将其工具自动暴露给模型。
过梁和类型检查
当前未配置棉绒或类型检查。
奖金:什么是紫外线和紫外线?
让我们从类比开始
想象一下,你是一位有很多食谱(项目)的厨师,每个食谱都需要不同的食材(包装)。
问题是:配方A要求“酱油v1.0”,配方B要求“酱油v2.0”,这两个版本不兼容,它们的API不匹配。如果你的厨房(你的电脑)只有一瓶酱油,你就卡住了。
venv和uv都是为了解决这个问题而存在的。
什么是venv?
venv 是Python内置的用于创建“虚拟环境”的工具。
虚拟环境背后的想法很简单:它在项目文件夹中创建Python运行时的独立副本,因此为此项目安装的包与其他项目完全隔离,不会相互干扰。
python -m venv .venv # Create a virtual environment (creates the .venv folder)
source .venv/bin/activate # "Enter" this environment
pip install openai # Now openai is installed only for this project
这 openai 您在此项目中安装的包不会影响计算机上的任何其他项目。这就是“隔离”的意思。
这 .venv 文件夹包含Python及其所有包的独立副本,这就是为什么它的大小通常是几百MB:它确实是一个完整的运行时环境。
紫外线是什么?
uv 是一种更现代的工具,取代了以下组合 pip 和 venv.
把它看作是 venv + pip +包版本锁定,所有这些都捆绑在一个更快、更智能的工具中。
# The old way (three steps)
python -m venv .venv
source .venv/bin/activate
pip install openai
# The uv way (one step)
uv add openai
是什么让紫外线更好?
1.快得离谱
pip 一次安装一个软件包,按顺序下载和安装。 uv 它是用Rust编写的,几乎完全并行工作,速度提高了10到100倍。
2.自动 .venv 管理
您不需要手动运行 python -m venv .venv 然后激活它。运行 uv run main.py 自动找到(或创建)正确的虚拟环境,并在其中运行脚本。
3.锁定文件(版本锁定)
这 uv.lock 项目中的文件记录了每个包的确切版本。这意味着,即使你几个月后换了电脑,或者把项目交给同事,运行 uv sync 恢复完全相同的环境,避免了经典的“在我的机器上工作”问题。
背后到底发生了什么 uv run python -c?
uv 是Astral团队开发的Python包和项目管理器,最近在Python生态系统中非常流行。Astral也是著名的Python linter背后的团队 Ruff. uv 它本身是用Rust编写的,因此它的核心特征是速度、简单性和可重复性。
核心工具: uv
uv的目标是取代像 pip, pip-tools, venv,以及 pyenv它最显著的特点是速度极快,通常比传统的Python包管理工具快10到100倍。
- 由Rust提供支持:它利用了Rust的并发性和高效的内存管理,使包解析和安装非常快。
- 一个二进制:
uv是一个独立的工具,因此在使用之前不需要预先配置Python环境。 - 全局缓存:
uv使用内容寻址存储。如果多个项目使用同一个包,则只需要在磁盘上保留一个副本;当构建环境时,uv通过硬链接将其链接到项目中,这样可以快速安装并节省磁盘空间。
分解命令: uv run
uv run 是其中之一 uv的最强大的功能,您可以将其视为“按需环境管理”。
- 自动创建虚拟环境:运行时
uv run,uv检查当前目录中是否已存在可用的虚拟环境。如果没有,它会自动创建.venv并确保依赖关系与项目配置相匹配。 - 无缝的脚本依赖集成:如果Python脚本在顶部包含PEP 723之后的元数据,
uv run可以根据该元数据自动准备脚本所需的包。一旦脚本完成,就不需要手动清理任何临时环境。
分解命令: python -c
python -c 是一个标准的Python功能,意思是“将以下字符串作为Python代码执行”。
uv run python -c "print('hello from uv')"
在这里, -c 代表命令,它通常用于快速测试、单行脚本或在shell脚本中嵌入一小段Python逻辑。
把它放在一起: uv run python -c "..."
以下是运行此命令时发生的情况:
uv run python -c "..."
它触发了现代Python执行工作流:
- 环境准备:
uv快速确认当前项目具有正确的Python虚拟环境。 - 依赖解析:如果代码或脚本元数据需要特定的包,
uv确保它们已安装。 - 代码执行:
uv在之后运行代码python -c在孤立的项目环境中。 - 一致性:只要
uv如果在计算机上可用,则同一命令更有可能在不同计算机上产生一致的结果,而无需手动运行pip install或者首先激活虚拟环境。
视觉摘要
Your computer
│
├── Project A/
│ └── .venv/ ← Project A's independent environment
│ └── openai 1.0
│
├── Project B/
│ └── .venv/ ← Project B's independent environment
│ └── openai 2.0
│
└── System Python ← Best to avoid installing anything here
每 .venv 它是一个独立的泡沫,与其他泡沫隔绝。 uv 是为您管理这些泡沫的现代工具。
你真正需要记住的命令
| 场景 | 命令 |
|---|---|
| 首次设置项目 | uv sync |
| 添加包 | uv add openai |
| 删除包 | uv remove anthropic |
| 运行程序 | uv run main.py |
无需手动激活。不要摆弄pip。紫外线处理一切。
