内容
# 夜间浏览器




[](https://github.com/franzenzenhofer/nightmare/actions/workflows/ci.yml)
[](https://www.typescriptlang.org/)
[](https://nodejs.org/)
[](https://nwjs.io/)
[](https://github.com/franzenzenhofer/nightmare/actions)
[](https://github.com/franzenzenhofer/nightmare/actions)
[](https://opensource.org/licenses/MIT)
[](https://modelcontextprotocol.io/)
**没有安全防护的 Chrome。** 一个 AI-first 的网页浏览器,每个标签页都有完整的 Node.js,零 CORS,以及内置的 REST API。从头到尾设计用于被 AI 代理控制。
---
## 这是什么?
每个浏览器都将网站放在一个沙盒中。夜间浏览器没有。
每个标签页——本地文件、localhost 服务器、**和外部网站**——都具有完整的 Node.js 访问权限。`require('fs')` 在 google.com 上有效。`require('http')` 在任何地方都有效。没有沙盒。没有进程隔离。红色安全警告是一个警告,而不是限制。
夜间浏览器在 `localhost:6660` 上附带一个**内置 REST API**。每个浏览器操作——创建标签页、导航、执行 JavaScript、读取控制台输出、截图——都是一个 `curl` 命令。连接一个 AI 代理,编写浏览器脚本,或在此基础上构建自己的开发工具。
它还包括一个**内置 MCP 服务器**,因此像 Claude Code 这样的 AI 代理可以直接连接并通过模型上下文协议控制浏览器。
**这不是生产浏览器。** 这是开发人员和 AI 代理需要无限制浏览器访问的强大工具。
---
## 快速入门
```bash
git clone https://github.com/franzenzenhofer/nightmare.git
cd nightmare
npm install
npm run dev
```
API 在 `http://localhost:6660` 上自动启动。
---
## 看看它的实际效果
### 1. 创建一个标签页并导航
```bash
curl -X POST http://localhost:6660/api/tabs \
-H "Content-Type: application/json" \
-d '{"url": "https://news.ycombinator.com"}'
```
```json
{
"id": "a2295073-0d6b-4413-ad3e-21dd6eff5458",
"displayUrl": "https://news.ycombinator.com",
"title": "Hacker News",
"zone": "WEB"
}
```
### 2. 在该标签页中执行 JavaScript(使用 Node.js!)
```bash
curl -X POST http://localhost:6660/api/tabs/TAB_ID/execute \
-H "Content-Type: application/json" \
-d '{"code": "document.title + \" — Node \" + process.version"}'
```
```json
{
"tabId": "a2295073-...",
"result": "Hacker News — Node v25.2.1"
}
```
### 3. 读取任何标签页的控制台输出
```bash
curl http://localhost:6660/api/tabs/TAB_ID/console
```
### 4. 截图
```bash
curl http://localhost:6660/api/screenshot > browser.json
# 返回整个浏览器窗口的 base64 编码 PNG
```
### 5. 获取完整的浏览器状态
```bash
curl http://localhost:6660/api/state
```
```json
{
"tabs": [{"id": "...", "title": "Hacker News", "zone": "WEB"}, ...],
"activeTabId": "a2295073-...",
"tabCount": 3,
"nodeVersion": "v25.2.1",
"apiPort": 6660,
"platform": "darwin"
}
```
---
## 为什么不使用 Puppeteer / Playwright / Selenium?
这些工具从外部自动化浏览器。夜间浏览器为您提供一个内部无限制的浏览器。
| 功能 | Puppeteer | Playwright | Nightmare |
|---------|-----------|------------|-----------|
| 每个页面都有 Node.js | 否 | 否 | **是** |
| 任何网站上的 `require('fs')` | 否 | 否 | **是** |
| 零 CORS | 否 | 否 | **是** |
| 剥离 CSP 头 | 否 | 否 | **是** |
| GUI 模式 + 无头 | 无头优先 | 无头优先 | **两者皆有** |
| 内置 REST API | 否 | 否 | **是(25+ 端点)** |
| 内置 MCP 服务器 | 否 | 否 | **是** |
| 控制台日志流媒体 | 有限 | 有限 | **完整的环形缓冲区 + WebSocket** |
| 加载任意网站到 iframe | 否(CSP 阻止) | 否 | **是** |
| 内置书签/历史记录 | 否 | 否 | **是** |
| 为 AI 代理设计 | 改编 | 改编 | **为此而建** |
> **注意:** 这是一个与已废弃的 [Segment/Nightmare](https://github.com/segmentio/nightmare) Electron 自动化库不同的项目。
---
## 用例
**AI 代理浏览器自动化** — 通过 MCP 或 REST API 连接 Claude Code 或任何 AI。编程导航页面、点击元素、输入文本、读取控制台输出、截图 — 所有这些都是编程的。浏览器是 AI 工具包中的一流工具。
**无需 CORS 的网页抓取** — 加载任何页面。没有 CORS 错误,没有 CSP 阻止,没有 X-Frame-Options 限制。读取 DOM。使用 `require('fs').writeFileSync()` 保存结果。完成。
**全栈调试** — 在一个标签页中运行您的 Web 应用程序。在同一个标签页中,`require('fs')` 读取服务器日志。来自每个标签页的控制台输出通过 `tabId`、`level` 和 `timestamp` 以实时方式流式传输到 API。
**安全研究** — 将脚本注入任何页面。分析 cookie、localStorage、网络请求。剥离 CSP 头。每个页面都可以使用完整的 Node.js 进行全面检查。
**自定义浏览器开发工具** — 编写一个 HTML 文件。它具有完整的 Node.js 访问权限。它可以读取文件系统、生成子进程、发出 HTTP 请求。作为您的应用程序旁边的一个标签页加载它。构建您需要的任何工具。
**CI/CD 集成** — 运行 `npm run dev:headless` 以进入无头模式。REST API 在启动时启动。使用 `curl` 或任何 HTTP 客户端进行脚本编写。截图、验证页面、运行集成测试。
**教学** — 向学生展示浏览器中实际发生的事情。没有抽象层。`require('http').createServer()` 有效。文件系统可访问。浏览器是透明的。
**快速原型设计** — 在单个 HTML 文件中构建全栈应用程序。前端渲染 + 后端逻辑在一个页面中。`fs`、`http`、`child_process`、`crypto` — 所有这些都在浏览器标签页中可用。
---
## 架构
```
┌──────────────────────────────────────────────────┐
│ AI 代理 / Claude Code / curl / MCP 客户端 │
│ (REST API / MCP 协议 / WebSocket) │
├──────────────────────────────────────────────────┤
│ API 服务器(localhost:6660) │
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │ REST │ │ MCP │ │ WebSocket │ │
│ │ 处理程序 │ │ 工具 │ │ 事件 │ │
│ └────┬─────┘ └────┬─────┘ └──────┬────────┘ │
│ └──────────┬───┘───────────────┘ │
│ 路由注册表 │
│ (自动同步 REST ↔ MCP) │
├──────────────────────────────────────────────────┤
│ 服务(纯 TypeScript,无 DOM) │
│ TabManager │ SecurityZones │ Navigation │
│ 历史记录 │ 书签 │ ConsoleCapture │ 存储 │
├──────────────────────────────────────────────────┤
│ NW.js 运行时 │
│ (Chromium + Node.js,零沙盒) │
└──────────────────────────────────────────────────┘
```
每个 REST 端点都**自动公开为 MCP 工具**,通过路由注册表。添加新端点,获取新 MCP 工具 — 零手动映射。
---
## 三个安全区域
| 区域 | URL 模式 | Node.js | 警告 |
|------|-------------|---------|---------|
| **本地** | `file://`,`nightmare://` | 完全访问 | 信息 |
| **本地主机** | `localhost`,`127.0.0.1` | 完全访问 | 信息 |
| **网页** | 其他所有 | 完全访问 | 永久红色警告 |
所有区域都具有相同的功能。这些区域是**警告,而不是限制**。WEB 区域警告无法关闭 — 它是一个永久提醒,您正在使用具有完全系统访问权限的未受信任代码。
---
<details>
<summary><strong>完整的 API 参考(25+ 端点)</strong></summary>
### 标签页管理
| 方法 | 路径 | 描述 |
|--------|------|-------------|
| GET | `/api/tabs` | 列出所有标签页 |
| POST | `/api/tabs` | 创建新标签页 |
| GET | `/api/tabs/:id` | 获取标签页详情 |
| DELETE | `/api/tabs/:id` | 关闭标签页 |
| POST | `/api/tabs/:id/activate` | 激活标签页 |
| POST | `/api/tabs/:id/duplicate` | 复制标签页 |
| POST | `/api/tabs/:id/pin` | 切换固定 |
| POST | `/api/tabs/:id/mute` | 切换静音 |
### 导航
| 方法 | 路径 | 描述 |
|--------|------|-------------|
| POST | `/api/tabs/:id/navigate` | 导航到 URL |
| POST | `/api/tabs/:id/back` | 后退 |
| POST | `/api/tabs/:id/forward` | 前进 |
| POST | `/api/tabs/:id/reload` | 重新加载页面 |
### 页面交互
| 方法 | 路径 | 描述 |
|--------|------|-------------|
| POST | `/api/tabs/:id/execute` | 执行 JavaScript |
| POST | `/api/tabs/:id/click` | 点击元素选择器 |
| POST | `/api/tabs/:id/type` | 输入到元素 |
| POST | `/api/tabs/:id/find` | 在页面中查找文本 |
| POST | `/api/tabs/:id/wait-for` | 等待选择器 |
| GET | `/api/tabs/:id/query` | 查询 DOM 元素 |
### 捕获
| 方法 | 路径 | 描述 |
|--------|------|-------------|
| GET | `/api/screenshot` | 完整窗口截图 |
| GET | `/api/tabs/:id/screenshot` | 标签页截图 |
| GET | `/api/tabs/:id/html` | 获取页面 HTML |
| GET | `/api/tabs/:id/console` | 获取控制台日志 |
### 浏览器控制
| 方法 | 路径 | 描述 |
|--------|------|-------------|
| GET | `/api/state` | 完整的浏览器状态 |
| POST | `/api/tabs/:id/zoom` | 设置缩放级别 |
| POST | `/api/shutdown` | 关闭浏览器 |
| POST | `/api/relaunch` | 重新启动浏览器 |
</details>
---
## MCP 集成
在 AI 代理配置中将 Nightmare 连接为 MCP 服务器:
```json
{
"mcpServers": {
"nightmare": {
"url": "http://localhost:6660/mcp"
}
}
}
```
所有 REST 端点都自动作为 MCP 工具可用:`nightmare_create_tab`、`nightmare_navigate`、`nightmare_execute_js`、`nightmare_screenshot`、`nightmare_get_console` 等。
---
## 无头模式
```bash
npm run dev:headless
```
没有窗口。API 立即启动。相同的功能,相同的端点。用于 CI/CD、自动化或 AI 代理工作流。
启动时输出:
```json
{"ready": true, "api": "http://localhost:6660"}
```
---
## 内置演示应用程序
`samples/` 目录包含 7 个演示应用程序,展示 Node.js 集成:
| 应用程序 | 描述 |
|-----|-------------|
| **Dreamwalker** | 浏览器控制面板 — 管理标签页,触发混乱模式 |
| **Nightmare Watcher** | 实时遥测仪表盘,带有事件流媒体 |
| **Shadow Notes** | 带有文件系统持久性的笔记应用程序 |
| **Zombie Port Hunter** | 使用 Node.js `net` 模块的网络端口扫描器 |
| **文件浏览器** | 使用 `fs` 和 `path` 的文件系统资源管理器 |
| **HN Shadow** | 带有本地存储的 Hacker News 存档器 |
| **首页** | 带有系统侦察的登陆页面 |
---
## 开发
```bash
npm run dev # 启动并启用 DevTools
npm run dev:headless # 启动无头模式(仅 API)
npm run typecheck # TypeScript 严格检查
npm run lint # ESLint(零警告允许)
npm run test # 1,635 个测试,覆盖率 95%+
npm run check # 所有质量门控一次性检查
```
### 技术栈
- **运行时:** NW.js 0.109.0(Chromium + Node.js)
- **语言:** TypeScript 5.x(严格模式,零 `any`)
- **测试:** Vitest with V8 覆盖率(1,635 个测试)
- **校验:** ESLint + @typescript-eslint(严格 + 样式)
- **构建:** esbuild IIFE 包
- **CI:** GitHub Actions
### 代码质量
1,635 个单元测试。 98.6% 语句覆盖率。 TypeScript 严格模式,零 `any` 类型。 ESLint 严格,零警告。 每个公共函数都有测试。 每个 REST 端点都有对应的 MCP 工具。
```
src/browser/
services/ 纯业务逻辑(49 个文件,100% 可测试)
components/ UI 组件(11 个文件)
api/ REST + MCP 服务器(14 个文件,自动同步)
runtime/ NW.js 连接层
__tests__/ 单元测试(75 个文件)
```
---
## 贡献
参见 [CONTRIBUTING.md](CONTRIBUTING.md) 以获取设置、代码样式和 TDD 工作流程。
## 安全
参见 [SECURITY.md](SECURITY.md)。 **TL;DR:** Nightmare 故意禁用 Web 安全。它是一个开发者工具,而不是生产浏览器。
## 许可证
[MIT](LICENSE)