bbsbot
基于FastMCP的telnet客户端,用于BBS(公告板系统)交互,具有自动学习功能。使AI代理能够通过模型上下文协议(MCP)与基于传统telnet的系统进行交互。
⚠️ AI生成代码免责声明 该项目是在人工智能的帮助下生成的。虽然功能正常,但它可能包含错误、安全漏洞或意外行为。使用风险自负。对于因使用本软件而导致的任何问题、损害或损失,作者不承担任何责任。在任何生产环境中使用之前,请彻底检查代码。
概述
bbsbot通过提供:
- 支持ANSI/CP437的全终端仿真
- 基于模式的屏幕阅读和导航
- 自动发现和记录菜单和提示
- 会话日志记录,用于分析和回放
- MCP工具曝光,实现无缝AI集成
建筑
bbsbot使用一个干净的分层架构,并适当分离关注点:
graph TB
subgraph "AI Agent"
LLM[Claude/LLM]
MCP[MCP Client]
end
subgraph "bbsbot Server"
App[FastMCP App]
SM[SessionManager]
subgraph "Core Layer"
Session[Session]
end
subgraph "Transport Layer"
Transport[TelnetTransport]
end
subgraph "Terminal Layer"
Emulator[TerminalEmulator
pyte]
end
subgraph "Learning Layer"
Engine[LearningEngine]
Discovery[Menu Discovery]
end
subgraph "Logging Layer"
Logger[SessionLogger]
end
end
subgraph "BBS System"
Telnet[Telnet Server :23]
BBS[BBS Software]
end
subgraph "Knowledge Base"
Prompts[prompt-catalog.md]
Menus[menu-map.md]
Flows[navigation-flows.md]
end
LLM --> MCP
MCP -->|MCP Tools| App
App --> SM
SM --> Session
Session --> Transport
Session --> Emulator
Session --> Engine
Session --> Logger
Transport -->|RFC 854 + IAC Escaping| Telnet
Telnet --> BBS
BBS -->|ANSI/CP437| Telnet
Telnet -->|Raw Bytes| Transport
Transport --> Emulator
Engine --> Discovery
Engine --> Prompts
Engine --> Menus
Engine --> Flows架构层
- 传输层 (
transport/):协议抽象(符合RFC 854的telnet,IAC字节转义) - 端子层 (
terminal/):使用pyte进行ANSI/CP437终端仿真 - 核心层 (
core/):具有资源限制和状态隔离的会话管理 - 学习层 (
learning/):自动发现菜单/提示,知识库管理 - 测井层 (
logging/):使用原始字节的结构化JSONL会话日志记录
特性
- 远程登录客户端:具有选项协商的完整RFC 854 telnet协议(BINARY、SGA、NAWS、TTYPE)
- 终端仿真:配备80x25(可配置)屏幕缓冲区的完整ANSI/CP437终端
- 屏幕阅读:提取文本、匹配模式、等待具有超时控制的提示
- 自动学习:发现菜单
[A] Option,提示Enter name:,以及文档导航流 - 会话日志记录:JSONL格式,带有时间戳、上下文和原始字节,用于回放/分析
- MCP集成:25多种用于连接、导航、学习和会话管理的工具
- 保持连接:可配置间隔以防止空闲断开连接
安装
先决条件
安装 紫外线 (推荐的软件包安装程序):
curl -LsSf https://astral.sh/uv/install.sh | sh或者看看 紫外线安装文档 对于其他方法。
安装bbsbot
bbsbot是必须在MCP客户端(Claude Desktop、Cline等)中配置的MCP服务器。
选项1:作为工具安装(推荐)
uv tool install bbsbot然后添加到MCP客户端配置中:
{
"mcpServers": {
"bbsbot_local_tw2002": {
"command": "bbsbot"
}
}
}本地TW2002 MCP与外部MCP连接器
bbsbot 在本地提供TW2002工具,但这些工具仅存在于MCP中 您从这个存储库/环境启动的服务器进程。在多连接器中 客户端,您也可能安装了无关的MCP连接器;那些不会 暴露 tw2002_* 工具。
有关群集运行时/ROI诊断和防崩溃控制参考,请参阅:
对TW2002操作使用显式的本地别名和工具筛选器:
{
"mcpServers": {
"bbsbot_local_tw2002": {
"command": "bbsbot",
"args": ["serve", "--tools", "tw2002"]
}
}
}如果 tw2002_* 缺少工具,首先验证配置的命令是否包括 serve --tools tw2002.
选项2:使用pip安装
pip install bbsbot然后配置MCP客户端以运行 bbsbot 作为服务器。
开发安装
git clone https://github.com/livingstaccato/bbsbot.git
cd bbsbot
uv pip install -e ".[dev]"快速入门示例
以下是一个完整的AI代理连接到BBS、导航菜单和阅读消息的示例:
from fastmcp import Client
from fastmcp.mcp_config import StdioMCPServer
# Start bbsbot server
server = StdioMCPServer(command="bbsbot", args=[])
async with Client(server.to_transport()) as client:
# Connect to BBS
await client.call_tool("bbs_connect", {
"host": "bbs.example.com",
"port": 23,
"cols": 80,
"rows": 25,
"term": "ANSI",
"send_newline": True
})
# Wait for main menu
screen = await client.call_tool("bbs_read_until_pattern", {
"pattern": r"\[M\] Main Menu",
"timeout_ms": 5000
})
# Navigate to messages
await client.call_tool("bbs_send", {"keys": "M\r"})
# Read until message list appears
screen = await client.call_tool("bbs_read_until_pattern", {
"pattern": r"Message #\d+",
"timeout_ms": 3000
})
print(screen["screen"]) # Display the screen
# Disconnect
await client.call_tool("bbs_disconnect", {})用法
作为MCP服务器
作为MCP服务器运行以公开BBS工具:
# Start the server (stdio transport)
bbsbot
# Or specify config
bbsbot --host localhost --port 2002程序化使用
在没有MCP的情况下直接使用Python API:
from bbsbot.core.session_manager import SessionManager
manager = SessionManager(max_sessions=10)
# Connect and create session
session_id = await manager.create_session(
host="bbs.example.com",
port=23,
cols=80,
rows=25,
term="ANSI",
send_newline=True,
reuse=False
)
# Get session
session = await manager.get_session(session_id)
# Read screen with timeout
snapshot = await session.read(timeout_ms=250, max_bytes=8192)
# Snapshot contains:
# - screen: formatted text (80x25)
# - screen_hash: SHA256 of screen text
# - cursor: {x, y} position
# - cols, rows, term
print(snapshot["screen"])
print(f"Cursor at: {snapshot['cursor']}")
# Send keys
await session.send("A\r\n")
# Wait for specific pattern (manual implementation)
import re
import asyncio
pattern = re.compile(r"Enter your name:")
timeout = 5.0
interval = 0.1
start_time = asyncio.get_event_loop().time()
matched = False
while asyncio.get_event_loop().time() - start_time >MCP: bbs_log_start("session.jsonl")
MCP->>Log: Create log file
LLM->>MCP: bbs_connect(host, port, ...)
MCP->>BBS: Telnet connection
BBS-->>MCP: Welcome screen (ANSI)
MCP->>Log: Log connection + raw bytes
LLM->>MCP: bbs_auto_learn_enable(true)
LLM->>MCP: bbs_auto_learn_discover(true)
LLM->>MCP: bbs_read_until_pattern("Main Menu")
MCP->>BBS: Read telnet stream
BBS-->>MCP: Raw bytes + ANSI codes
MCP->>MCP: Parse terminal, extract text
MCP->>Log: Log screen + raw bytes
MCP->>KB: Discover menu options [A], [B]
MCP-->>LLM: screen + cursor + hash
Note over LLM: LLM analyzes screen,
decides to press 'M'
LLM->>MCP: bbs_send("M\r")
MCP->>BBS: Send 'M' + Enter
MCP->>Log: Log keystroke
LLM->>MCP: bbs_read(250, 8192)
BBS-->>MCP: Message list screen
MCP->>Log: Log screen + raw bytes
MCP-->>LLM: Full snapshot
Note over LLM: If LLM is uncertain about
screen content, it can
refer to session.jsonl
for raw bytes
LLM->>MCP: bbs_disconnect()
MCP->>BBS: Close connection
MCP->>Log: Log disconnect
LLM->>MCP: bbs_log_stop()要点
- 始终启动会话日志记录 (
bbs_log_start)-使用原始字节创建完整记录 - 使用
bbs_read对于一切 -始终以JSONL格式记录原始数据的单一方法 - 启用自动学习 早期-为未来的会议建立知识库
- 如果不确定,LLM可以参考日志 -每一个
bbs_read包括raw_bytes_b64会话日志 - 没有单独的“获取屏幕”方法 -使用
bbs_read(timeout_ms=0)获取当前状态 - 知识库积累 -菜单、提示、流程记录在
.bbs-knowledge/
为什么是单读法?
以前,读取新数据和获取当前屏幕有不同的方法。这令人困惑且容易出错。现在:
- 单一真相来源:
bbs_read始终读取,始终记录原始字节 - LLM安全: 如果不确定屏幕内容,LLM可以检查
raw_bytes_b64来自session.jsonl - 一致的日志记录: 每次屏幕观察都会完整记录
- 更简单的API: 不混淆使用哪种方法
配置
知识库
默认情况下,学习到的知识按照XDG基本目录规范存储在特定于平台的用户数据目录中:
- Linux/BSD:
~/.local/share/bbsbot(或$XDG_DATA_HOME/bbsbot) - macOS:
~/Library/Application Support/bbsbot - 视窗:
%LOCALAPPDATA%\bbsbot
用以下内容覆盖默认位置:
export BBSBOT_KNOWLEDGE_ROOT=/path/to/knowledge保持每个项目的知识库(而不是整个用户):
export BBSBOT_KNOWLEDGE_ROOT=$(pwd)/.bbs-knowledge终端设置
通过MCP工具配置终端大小和保活:
# Using MCP client
await client.call_tool("bbs_set_size", {"cols": 80, "rows": 25})
await client.call_tool("bbs_keepalive", {"interval_s": 30.0, "keys": "\r"})或者以编程方式:
# Using SessionManager
session = await manager.get_session(session_id)
await session.set_size(cols=80, rows=25)
# Keepalive is configured per-session through the session manager发展
设置
uv pip install -e ".[dev]"代码质量
该项目使用现代Python 3.11+功能和严格的质量工具:
- 类型检查:
mypy src/bbsbot - 掉毛:
ruff check src/bbsbot - 格式化:
ruff format src/bbsbot - 测试:
pytest - 类型验证:
ty src/bbsbot
运行所有检查
ruff check src/bbsbot
ruff format --check src/bbsbot
mypy src/bbsbot
pytest重新生成图表
架构和工作流程图是使用Mermaid文件生成的 mermaid-py.
使用make生成SVG图:
make diagrams可用目标:
make diagrams或make diagrams-svg-生成SVG图(默认)make diagrams-png-生成PNG图表make clean-删除所有生成的图表文件make help-显示所有可用目标
或者,直接运行脚本:
python3 docs/generate_diagrams.py --format svg源文件:
docs/diagrams/architecture.mmd→architecture.svgdocs/diagrams/workflow.mmd→workflow.svgdocs/diagrams/session-flow.mmd→session-flow.svg
智能机器人与模式测试
bbsbot包括一个智能机器人系统,该系统使用提示检测来自主导航BBS游戏并测试提示模式。
TW2002交易机器人
运行TW2002交易机器人:
bbsbot tw2002 bot -c tw2002_bot_config.yaml目标可视化(人工智能策略)
当 trading.strategy: ai_strategy 处于活动状态,显示目标进度:
- 紧凑的状态线
trading.ai_strategy.visualization_interval回合 - 目标发生变化时的完整时间表
- 会议结束时的总结报告
要禁用所有目标可视化输出,请执行以下操作:
trading:
ai_strategy:
show_goal_visualization: false间谍/监视插座
您可以通过TCP广播实时终端流,并从另一个终端连接到它:
# Start bot with watch socket enabled (raw ANSI stream)
bbsbot tw2002 bot -c tw2002_bot_config.yaml --watch-socket
# Attach viewer
bbsbot spy如果你想要结构化的JSON事件(包括目标可视化事件),请使用JSON协议:
# Start bot with JSON watch protocol
bbsbot tw2002 bot -c tw2002_bot_config.yaml --watch-socket --watch-socket-protocol json
# Attach and view JSON lines (the "viz" events include compact/timeline/summary text)
bbsbot spy --encoding utf-8目标可视化观察事件如下:
{"event":"viz","data":{"kind":"compact|timeline|summary","text":"...","turn":123,"character_name":"..."}}MCP“间谍”工具(进行中)
如果你在MCP服务器进程中运行机器人,你可以按需查询目标进度:
tw2002_get_goal_visualization(呈现压缩/时间线/摘要)tw2002_get_goal_phases(原始相位数据)tw2002_capabilities(返回分组工具图+快速入口点)tw2002_list_sessions/tw2002_set_active_session(确定性会话定位)tw2002_bootstrap(一次通话连接+登录)
快速开始
# Run intelligent bot with pattern testing
bbsbot script play_tw2002_intelligent
# Run systematic pattern validation
bbsbot script test_all_patterns特性
- 反应性检测:Bot等待提示,检测它们,并做出适当的响应
- 自动分页:自动处理“更多”提示和分页
- 模式验证:测试所有13个定义的提示模式
- 流量跟踪:记录操作→提示序列
- 综合报告:生成JSON和Markdown结果
建筑
智能机器人使用 混合反应方法:
- 第一阶段:纯反应式-检测出现的提示
- 第2阶段:跟踪提示序列和流程
- 第三期:添加常见模式的预测(未来)
看 docs/guides/INTELLIGENT_BOT.md 以获取完整的文档。
机器人使用示例
from bbsbot.commands.scripts.play_tw2002_intelligent import IntelligentTW2002Bot
bot = IntelligentTW2002Bot()
await bot.connect()
# Navigate to game
await bot.navigate_twgs_to_game()
await bot.enter_game_as_player("BotName")
# Test commands with automatic prompt detection
await bot.test_command("D\r", "Display computer")
await bot.test_command("I\r", "Show inventory")
# Auto-handles pagination
snapshot = await bot.send_and_wait("L\r", "Long range scan")
snapshot = await bot.handle_pagination(snapshot)
# Generate results
await bot.generate_report()模式测试
测试了13种模式:
login_username,login_passwordtwgs_main_menu,twgs_select_gamemain_menu,command_prompt_genericsector_command,planet_commandpress_any_key,more_promptyes_no_prompt,quit_confirmenter_number
结果保存到 logs/reports/intelligent-bot-{timestamp}.json
已知警告
- 你可以看到
UserWarning: Field name "validate" ... shadows an attribute从Pydantic开始bbsbot。这目前是无害的,不会影响运行时行为。
许可证
GNU Affero通用公共许可证v3或更高版本-版权所有(c)2025-2026 provide.io llc
看 许可证 了解详情。
