](https://www.npmjs.com/package/@portel/photon) ](https://www.npmjs.com/package/@portel/photon)   ](https://nodejs.org) 
定义意图一次。到处送货。
Photon将单个TypeScript文件转换为:
- MCP服务器 对于AI代理
- CLI工具 自动化
- 网络界面 对于人类
Photon是在 MIT许可证.
*接口是可选的。意图是强制性的。*
______________________________________________________________________
一个定义。多个接口。
______________________________________________________________________
示例
// hello.photon.ts
export default class Hello {
greet(name: string) {
return `Hello, ${name}!`;
}
}这是一个完整的光子。从这个文件中,您可以得到:
$ photon cli hello greet --name Ada # CLI
$ photon # Web UI at localhost:3008
$ photon mcp hello # MCP server for Claude, Cursor, etc.没有装饰师。没有注册。没有服务器样板。 只需定义意图。Photon处理其余部分。
______________________________________________________________________
光子为何存在
大多数软件都是围绕界面构建的:web应用程序、CLI工具、API,现在还有用于AI代理的MCP服务器。但基本逻辑往往是一样的。
Photon从另一个地方开始:在TypeScript文件中捕获一次意图,并让系统通过多个界面(CLI工具、web界面和MCP服务器)公开它。
一个定义。多个表面。
______________________________________________________________________
快速开始
通过三个命令从零到连接到Claude Desktop的MCP服务器:
bun add -g @portel/photon
photon new my-tool # Scaffolds ./my-tool.photon.ts in your CWD
photon mcp install my-tool # Registers it in Claude Desktop's config
# Restart Claude Desktop. Your tool is live.更喜欢网络仪表板?跳过步骤3并运行 photon 相反,它会打开自动生成的UI Beam。
或者尝试不全局安装:
bunx @portel/photon new my-tool
bunx @portel/photon mcp install my-tool
# pnpm users can use pnpm dlx instead:
pnpm dlx @portel/photon new my-tool
pnpm dlx @portel/photon mcp install my-tool需要 TypeScript是内部编译的;不tsconfig.json需要。 光子文件存放在哪里?./(您cd到的项目目录)或~/.photon/(全球,自动发现)。用户设置在以下情况下保持不变 `~/.photon/state/
/`。参见 东西住的地方.
______________________________________________________________________
运作原理
你编写一个TypeScript类。方法就是你的能力。类型描述什么是有效的。评论解释了意图。Photon读取所有数据,并从一个文件生成三个接口。同样的逻辑。相同的验证。相同的数据。
analytics.photon.ts → Web UI (Beam) · CLI · MCP Server for AI表达得越多,Photon导出的越多:
| 你写什么 | 光子衍生什么 |
|---|---|
| 方法签名 | 工具定义:名称、输入、输出 |
| 类型注释 | 输入验证规则、UI字段类型 |
| JSDoc评论 | AI客户端和人类用户的文档 |
| 构造函数参数 | 配置UI、环境变量映射、运行时注入(Photon, Cloudflare, CloudflareEnv) |
@tags | 验证、格式化、调度、webhooks |
当你添加一个 @param city {@pattern ^[a-zA-Z\s]+$} 注释,Beam在表单中验证它,CLI在运行前验证它,MCP模式为AI.One注释强制执行它。三个消费者。
三种写作方式
extends Photon 是一种形状。你也可以注射 Photon 作为构造函数参数,当您已经扩展了其他东西,或者在没有继承的情况下组合时——无论哪种方式都是相同的API。CF资源通过单独的通道到达光子 Cloudflare 注入使便携式光子保持便携式。看 文档/指南/PHOTON-INJECTION.md.
______________________________________________________________________
梁:人类探索
Beam是web仪表板。每个光子都会自动变成一种交互形式。跑 photon这就是整个命令。
UI是 完全自动生成 从您的方法签名中:字段类型、验证、默认值、布局。你从不写前端代码。当你添加一个 {@choice a,b,c} 标记到参数后,Beam会呈现一个下拉列表。当您将字符串标记为 {@format email},该字段验证电子邮件格式。UI会随着代码的发展而演变。
当表单不是您正在构建的正确界面时,您可以用自己的HTML替换Beam的自动生成视图。以你的光子命名的全局被自动注入(例如。, analytics.onResult(data => ...))--不需要框架。 window.photon.url 也会被注入并解析为Beam基URL,这样您的HTML就可以正确地构造获取路径,无论是在本地运行还是在反向代理后面运行。
宣布的光子 @get 或 @post HTTP路由在Beam中显示为web应用程序。路线支持动态路径段(例如。 @get /items/:id)特异性匹配:文字段胜过参数。Beam将请求代理到这些路由,并注入 x-photon-base-path 这样,无论Beam托管在哪里,应用程序都可以构建正确的绝对路径。
______________________________________________________________________
AI代理:机器调用
photon info analytics --mcp{
"mcpServers": {
"analytics": {
"command": "photon",
"args": ["mcp", "analytics"]
}
}
}粘贴到AI客户端的配置中。您的光子现在是MCP服务器。克劳德可以调用你的方法。Cursor可以调用您的方法。任何兼容MCP的主机都可以调用您的方法。
人工智能在Beam中看到了与人类相同的东西:方法名称、JSDoc中的参数描述、类型中的验证规则。你为自己记录该工具而写的JSDoc评论是克劳德用来决定何时以及如何调用它的。
当您的光子具有自定义UI时,支持 MCP应用程序扩展 原生渲染,无需单独的应用程序。下面的光子在Claude Desktop中运行,与Beam的UI和数据相同。
______________________________________________________________________
光子是如何进化的
光子是如何生长的。每一步都增加了一件事,并从中获得了多种功能。
添加评论:AI理解你的意图
/**
* Weather - Check weather forecasts worldwide
*/
export default class Weather {
/**
* Get the weather forecast for a city
* @param city City name (e.g., "London")
*/
async forecast(params: { city: string }) { ... }
}类描述变成了AI客户端如何向用户介绍该工具。这 @param 描述是AI在决定传递什么值之前读取的内容。相同的评论。人工帮助文本和人工智能合同同时生效。
声明配置:出现一个设置工具
export default class Weather {
/** User-tunable knobs. Photon auto-generates a `settings` tool from this. */
protected settings = {
/** Units for forecast values */
units: 'metric',
/** Polling interval in seconds */
pollIntervalSec: 300,
};
async forecast(params: { city: string }) {
const res = await fetch(`...?units=${this.settings.units}`);
return await res.json();
}
}protected settings 是公开运行时旋钮的规范方式。Photon读取每个属性上的JSDoc,生成MCP settings 带有键入输入的工具,并将用户更改持久化到 ~/.photon/state/ /-settings.json在方法内部, this.settings 是只读代理。要更改值,用户(或AI)调用自动生成的 settings 工具。
对于 秘密 永远不应该在设置文件(API键、令牌)中持久化的,请改用构造函数参数。Photon将参数名称映射到环境变量:
export default class Weather {
constructor(private apiKey: string) {} // → WEATHER_API_KEY
}构造函数模式适用于来自以下类型的基元 .envThe protected settings 该模式适用于其他所有内容,包括用户在运行时无需重新启动即可更改的任何旋钮。 如有疑问,请联系 settings.
添加标记:行为扩展到所有曲面
/**
* @dependencies node-fetch@^3.0.0
*/
export default class Weather {
/**
* @param city City name {@example London} {@pattern ^[a-zA-Z\s]+$}
* @param days Number of days {@min 1} {@max 7}
* @format table
*/
async forecast(params: { city: string; days?: number }) { ... }
}@dependencies 安装 node-fetch 首次运行时自动执行,无需手动安装软件包。这 {@pattern} 同时验证表单、CLI和MCP模式。 days 变为带边界的数字微调器。 @format table 在Beam中将结果渲染为表格。一个注释,三个曲面。
系统CLI依赖关系
如果您的photon封装了一个命令行工具,请声明它,photon会在加载时强制执行它:
/**
* @cli ffmpeg - https://ffmpeg.org/download.html
*/
export default class VideoProcessor {
async convert({ input, format }: { input: string; format: string }) {
// ffmpeg is guaranteed to exist when this runs
}
}______________________________________________________________________
什么是免费的
您不构建的东西,因为Photon会处理它们:
| 自动用户界面 | 根据您的签名生成的表单、字段类型、验证、布局 |
| 有状态的实例 | 同一光子的多个命名实例,每个实例都具有隔离状态 |
| 持久内存 | this.memory 为每个实例提供光子键值存储,无需数据库 |
| 计划执行 | @scheduled 按cron计划运行任何方法 |
| 网络钩子 | @webhook 将任何方法公开为HTTP端点 |
| OAuth(客户端) | 内置OAuth 2.0流,适用于谷歌、GitHub、微软 |
| OAuth授权服务器 | 自行向MCP客户端发放令牌:CIMD+DCR、PKCE、OIDC id_token、RFC 8693令牌交换 |
| SQLite持久性 | 审计日志、执行历史和OAuth授权在守护进程重启后仍然有效(bun:sqlite或better-sqlite3) |
| 守护进程操作 | photon ps 列出并控制计划作业、Webhook和实时会话 |
| 分布式锁 | @locked 序列化访问:一次一个调用者,跨进程 |
| 交叉光子呼叫 | this.call() 调用另一个光子的方法 |
| Cloudflare运行时 | this.cf.r2('blobs'), this.cf.d1('app'), this.cf.kv('cache') --局部(微耀斑)和部署(真实绑定)的形状相同。看 CF-BINDINGS.md |
| 实时事件 | this.emit() 以零连接向浏览器UI发送命名事件 |
| 实时渲染 | this.render() 实时将格式化输出推送到CLI和Beam |
| 委托法学硕士 | this.sample() 要求驾驶代理的模型生成文本-没有API密钥,代理付费 |
| 在线确认/输入 | this.confirm() 和 this.elicit() 通过客户端的原生UI进行路由(Beam对话框,Claude提示) |
| 远程访问范围 | photon claim 生成一个短期代码,将远程MCP会话限定在一个目录中 |
| 独立二进制文件 | photon build 通过Bun将任何光子编译为单个可执行文件 |
| 依赖管理 | @dependencies 首次运行时自动安装npm包 |
______________________________________________________________________
协调:锁+活动
两个基元。他们一起解锁了一类今天出乎意料地难以构建的东西。
锁 序列化访问。标记方法时 @locked,一次只能执行一个调用者,无论该调用者是Beam中的人类、CLI脚本还是AI代理。其他人都在等着轮到他们。
事件 实时将状态更改推送到任何浏览器UI。 this.emit({ event: 'boardUpdated', data: board }) 在服务器上变成 chess.onBoardUpdated(handler) 在您的自定义UI中——以您的光子文件命名。没有要配置的WebSockets。没有投票。事件通过MCP流式HTTP传输通过SSE传递。
一起: 基于回合制的实时状态协调.
export default class Chess {
/** Make a move. Locks ensure human and AI alternate turns. */
/** @locked */
async move(params: { from: string; to: string }) {
const result = await this.applyMove(params.from, params.to);
// Browser UI updates instantly, no polling needed
this.emit({ event: 'boardUpdated', data: result.board });
this.emit({ event: 'turnChanged', data: { next: result.nextPlayer } });
return result;
}
}// In your custom UI (ui/chess.html)
// The global `chess` is auto-injected, named after your photon file
chess.onBoardUpdated(board => renderBoard(board));
chess.onTurnChanged(({ next }) => showTurn(next));
// Call server methods directly
chess.move({ from: 'e2', to: 'e4' });一个人穿过梁。Claude已配置MCP服务器。锁确保它们真正交替。事件使双方董事会都保持活跃。这是一个功能齐全的回合制国际象棋游戏,人类与人工智能,大约有50行应用程序逻辑。
同样的模式也适用于游戏之外:在人工智能继续之前由人类进行审查的审批工作流程,来自任何来源的编辑立即出现的协作工具,步骤必须严格按顺序执行的模拟,任何系统 谁做下一件事很重要.
______________________________________________________________________
MCP图元打开 this
MCP协议的面向用户的原语以普通方法的形式出现 在每个光子实例上——没有装饰器、没有功能标志、没有SDK 进口。运行时将每个调用路由到 请求已于(Beam、Claude Desktop、Cursor、CLI)到达。
export default class Editor {
async summarize(params: { text: string }) {
// Ask the driving agent's LLM. No API key. Agent pays.
return await this.sample({
prompt: `Summarize in one sentence:\n\n${params.text}`,
maxTokens: 128,
});
}
async deploy() {
if (!(await this.confirm('Ship to production?'))) return;
const env = await this.elicit({
ask: 'select',
message: 'Which environment?',
options: ['staging', 'prod'],
});
await this.run(env);
}
}| 原始 | 它做什么 |
|---|---|
await this.sample({ prompt }) | 通过MCP采样将LLM生成委托给调用者的模型 |
await this.confirm(question) | 是/否提示--返回 boolean |
await this.elicit(params) | 任意输入(文本、选择、表单、文件等) |
this.status(msg) / this.progress(v) | 长时间工作期间的实时反馈;Beam中通往SSE流的路线 |
this.roots | 连接的客户端声明的MCP工作区根(roots/list) |
this.notifyResourceUpdated(uri) | 推 notifications/resources/updated 订阅客户 |
完整参考: docs/reference/MCP-PRIMITIVES.md.
______________________________________________________________________
远程访问:索赔代码
默认情况下,每个安装的光子对每个连接的MCP都是可见的 客户。当你想配对时 *远程* 代理与a *子集* 你的 光子——你的手机驱动Beam,一个队友在审查一个项目, 一个作用域为单个目录的CI代理--生成声明代码:
$ photon claim --scope /workspace/proj --ttl 4h --label "phone"
✓ Claim code: R3K-9QZ
Scope: /workspace/proj
Expires in: 4h远程客户端将代码表示为 Mcp-Claim-Code 页眉打开 其MCP会话。 tools/list 然后只暴露其来源的光子 位于该目录下。没有代码的会话保持完全访问权限-- 该功能是严格选择加入的。
完整参考: docs/reference/CLAIM-CODES.md.
______________________________________________________________________
市场
准备安装32个光子:数据库、API、开发人员工具等。
photon search postgres
photon add postgres您还可以使用限定引用直接从任何GitHub存储库安装:
photon add owner/repo/photon-name在中浏览完整目录 官方光子库。您还可以为您的团队托管一个私人市场:远离公共互联网的内部工具。
______________________________________________________________________
命令
# Run
photon # Open Beam UI
photon mcp # Run as MCP server
photon mcp --dev # MCP server with hot reload
photon cli [method] # Run as CLI tool
# Install from GitHub
photon beam owner/repo/name # Install & open in Beam
photon cli owner/repo/name method # Install & run via CLI
# Create
photon maker new # Scaffold a new photon
# Build
photon build # Compile to standalone binary
photon build --with-app # Include Beam UI in binary
# Manage
photon info # List all photons
photon info --mcp # Get MCP client config
photon maker validate # Check for errors
# Marketplace
photon add # Install photon
photon search # Search marketplace
photon upgrade # Upgrade all
# Ops
photon doctor # Diagnose environment
photon test # Run tests
photon ps # Observe & control scheduled jobs, webhooks, sessionsphoton ps:计划作业、webhooks和会话
photon ps 是守护进程的操作界面。没有参数 它打印一个四段快照——活动计划,已声明,但- 未注册、网络链接和活动会话。
photon ps # full snapshot
photon ps --json # structured output for scripts
photon ps --type active # one section only
photon ps --base ~/Projects/kith # filter to one PHOTON_DIR两步模型。 A. @scheduled 源代码中的注释是 公开宣布的 直到注册。注册是每台机器、持久和明确的:
photon ps enable newsletter:sendDigest # DECLARED → ACTIVE
photon ps disable newsletter:sendDigest # ACTIVE → suppressed (survives restart)
photon ps pause newsletter:sendDigest # stop firing without removing enrollment
photon ps resume newsletter:sendDigest # undo pause
photon ps history newsletter:sendDigest # last 20 firings: timestamp, status, error对于没有 @scheduled 标签,使用光束脉冲 面板(“添加日程表”)或呼叫 this.schedule.create() 来自光子编码。
this.schedule.create() (程序化时间表)跳过申报和 直接进入ACTIVE。看 docs/GUIDE.md#scheduling 如需完整参考,请查看守护进程状态布局,以及 .photon-no-host 用于多主机设置。
从GitHub安装
使用合格的引用直接从任何GitHub存储库安装和运行photons:
photon beam Arul-/photons/claw # Install from GitHub, open in Beam
photon cli Arul-/photons/todo add # Install from GitHub, run method格式为 owner/repo/photon-name.过渡性 @photon 来自同一仓库的依赖关系会自动解析。
编译为二进制
从任何光子构建独立的可执行文件——目标机器上不需要Node.js:
photon build my-tool # Binary for current platform
photon build my-tool -t bun-linux-x64 # Cross-compile for Linux
photon build my-tool --with-app # Embed Beam UI as a desktop app在引擎盖下使用Bun的编译器。二进制将光子捆绑在一起 @dependencies,并且可传递 @photon 保存到单个文件中。
______________________________________________________________________
标记参考
| 标签 | 位置 | 功能 |
|---|---|---|
@dependencies | 类 | 首次运行时自动安装npm包 |
@cli | 类 | 声明系统CLI依赖关系,在加载时检查 |
@format | 方法 | 结果呈现(表、列表、标记、代码等) |
@param ... {@choice a,b,c} | 参数 | 梁中的下拉选择 |
@param ... {@choice-from method} | Param | 从另一个方法的返回值填充的动态下拉列表 |
@param ... {@format email} | 参数 | 输入验证和字段类型 |
@param ... {@min N} {@max N} | 参数 | 数值范围约束 |
@ui | 类/方法 | 链接自定义HTML模板 |
@expose | 方法 | 自动绑定到 POST /api/ 获取SPA(public 跳过SameSite门) |
@get /path | 方法 | 仅HTTP GET路由;在Beam中显示为web应用程序,而不是MCP工具。支持 :param 细分市场 |
@post /path | 方法 | 仅HTTP POST路由;在Beam中显示为web应用程序,而不是MCP工具。支持 :param 细分市场 |
@resource | 方法 | 动态MCP资源解析器(规范形式;替换 @Static) |
@prompt | 方法 | MCP提示模板(规范形式;替换 @Template) |
@webhook | 方法 | 作为HTTP端点公开 |
@scheduled | 方法 | 按cron计划运行 |
@locked | 方法 | 跨进程的分布式锁 |
@autorun | 方法 | 在Beam中选择时自动执行 |
@mcp | 类 | 注入另一个MCP服务器作为依赖项 |
@icon | 类/方法 | 设置表情符号图标 |
查看完整 标记参考 所有30+个标签都有示例。
______________________________________________________________________
文档
从这里开始:
| 指南 | |
|---|---|
| 入门指南 | 在5分钟内安装、构建并运行第一个光子 |
| 核心概念 | Photon背后的6个想法 |
| 输出格式 | 每个人的视觉画廊 @format 类型 |
| 意图元数据 | 注释、模式、注释和格式如何映射到原生曲面 |
| 设置 | 使用声明运行时旋钮 protected settings (规范配置模式) |
| 故障排除 | 常见问题和解决方案 |
深入了解:
| 主题 | |
|---|---|
| 自定义用户界面 | 利用光子桥API构建丰富的交互界面 |
| OAuth | 内置OAuth 2.0与谷歌、GitHub、微软 |
| MCP客户端注册 | 通过CIMD或DCR向Photon的AS注册MCP客户端 |
| 可观测性 | OpenTetry跟踪、指标、日志和结构化错误 |
| 协议特性 | 能力握手、结构化错误、跟踪相关性 |
| Daemon Pub/Sub | 实时跨进程消息传递 |
| 网络钩子 | 外部服务的HTTP端点 |
| 锁 | 用于独占访问的分布式锁 |
| 高级模式 | 生命周期挂钩、依赖注入、交互式工作流 |
| 市场配置 | 在一个市场中跨相关光子共享设置 |
| 部署 | Docker、Cloudflare Workers、AWS Lambda、Systemd |
操作:
参考: 完整的开发人员指南 · 标记参考 · 命名约定 · 建筑 · OAuth授权服务器 · 生命周期和入口 · PHOTON_DIR和命名空间 · 更新日志 · 贡献
______________________________________________________________________
开源
Photon是免费开源的 MIT许可证.
该项目仍在发展中,欢迎捐款。
