@portel/photon 1.5.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +361 -339
- package/dist/auto-ui/beam.d.ts +5 -0
- package/dist/auto-ui/beam.d.ts.map +1 -1
- package/dist/auto-ui/beam.js +727 -51
- package/dist/auto-ui/beam.js.map +1 -1
- package/dist/auto-ui/bridge/index.d.ts +37 -0
- package/dist/auto-ui/bridge/index.d.ts.map +1 -0
- package/dist/auto-ui/bridge/index.js +555 -0
- package/dist/auto-ui/bridge/index.js.map +1 -0
- package/dist/auto-ui/bridge/openai-shim.d.ts +20 -0
- package/dist/auto-ui/bridge/openai-shim.d.ts.map +1 -0
- package/dist/auto-ui/bridge/openai-shim.js +231 -0
- package/dist/auto-ui/bridge/openai-shim.js.map +1 -0
- package/dist/auto-ui/bridge/photon-app.d.ts +162 -0
- package/dist/auto-ui/bridge/photon-app.d.ts.map +1 -0
- package/dist/auto-ui/bridge/photon-app.js +460 -0
- package/dist/auto-ui/bridge/photon-app.js.map +1 -0
- package/dist/auto-ui/bridge/types.d.ts +128 -0
- package/dist/auto-ui/bridge/types.d.ts.map +1 -0
- package/dist/auto-ui/bridge/types.js +7 -0
- package/dist/auto-ui/bridge/types.js.map +1 -0
- package/dist/auto-ui/design-system/tokens.d.ts +1 -1
- package/dist/auto-ui/design-system/tokens.d.ts.map +1 -1
- package/dist/auto-ui/design-system/tokens.js +1 -1
- package/dist/auto-ui/design-system/tokens.js.map +1 -1
- package/dist/auto-ui/index.d.ts +3 -1
- package/dist/auto-ui/index.d.ts.map +1 -1
- package/dist/auto-ui/index.js +5 -2
- package/dist/auto-ui/index.js.map +1 -1
- package/dist/auto-ui/platform-compat.d.ts.map +1 -1
- package/dist/auto-ui/platform-compat.js +60 -6
- package/dist/auto-ui/platform-compat.js.map +1 -1
- package/dist/auto-ui/streamable-http-transport.d.ts +25 -1
- package/dist/auto-ui/streamable-http-transport.d.ts.map +1 -1
- package/dist/auto-ui/streamable-http-transport.js +581 -20
- package/dist/auto-ui/streamable-http-transport.js.map +1 -1
- package/dist/auto-ui/types.d.ts +74 -0
- package/dist/auto-ui/types.d.ts.map +1 -1
- package/dist/auto-ui/types.js +21 -0
- package/dist/auto-ui/types.js.map +1 -1
- package/dist/beam.bundle.js +51422 -1791
- package/dist/beam.bundle.js.map +4 -4
- package/dist/cli.js +12 -2
- package/dist/cli.js.map +1 -1
- package/dist/daemon/client.d.ts +5 -3
- package/dist/daemon/client.d.ts.map +1 -1
- package/dist/daemon/client.js +30 -4
- package/dist/daemon/client.js.map +1 -1
- package/dist/daemon/manager.d.ts +5 -0
- package/dist/daemon/manager.d.ts.map +1 -1
- package/dist/daemon/manager.js +20 -0
- package/dist/daemon/manager.js.map +1 -1
- package/dist/loader.d.ts +23 -0
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +77 -12
- package/dist/loader.js.map +1 -1
- package/dist/photon-cli-runner.d.ts.map +1 -1
- package/dist/photon-cli-runner.js +2 -0
- package/dist/photon-cli-runner.js.map +1 -1
- package/dist/photon-doc-extractor.d.ts +1 -0
- package/dist/photon-doc-extractor.d.ts.map +1 -1
- package/dist/photon-doc-extractor.js +25 -6
- package/dist/photon-doc-extractor.js.map +1 -1
- package/dist/server.d.ts +12 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +386 -13
- package/dist/server.js.map +1 -1
- package/dist/template-manager.js +2 -2
- package/dist/version.d.ts +8 -0
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +16 -0
- package/dist/version.js.map +1 -1
- package/package.json +19 -9
package/README.md
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
<img src="https://raw.githubusercontent.com/portel-dev/photon/main/assets/photon-logo.png" alt="Photon" width="500">
|
|
5
5
|
|
|
6
|
-
**
|
|
6
|
+
**Simplify the creation of CLI tools, MCP servers, and web applications.**
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
A framework, runtime, and ecosystem. Batteries included.
|
|
9
9
|
|
|
10
10
|
[](https://www.npmjs.com/package/@portel/photon)
|
|
11
11
|
[](https://www.npmjs.com/package/@portel/photon)
|
|
@@ -14,484 +14,506 @@ Write business logic. Get an MCP server, CLI, and web UI — automatically.
|
|
|
14
14
|
[](https://nodejs.org)
|
|
15
15
|
[](https://modelcontextprotocol.io)
|
|
16
16
|
|
|
17
|
-
[Quick Start](#quick-start) · [
|
|
17
|
+
[Quick Start](#quick-start) · [How It Works](#how-it-works) · [Beam UI](#beam) · [Marketplace](#marketplace) · [Docs](#documentation)
|
|
18
18
|
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
23
|
-
##
|
|
23
|
+
## What Is This Thing?
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
npm install -g @portel/photon
|
|
27
|
-
photon init my-tool
|
|
28
|
-
photon # Open Beam UI in your browser
|
|
29
|
-
```
|
|
25
|
+
So, here is the situation. You write a single TypeScript file. Just one. And somehow, through some dark magic I don’t fully understand either, you get three things at once:
|
|
30
26
|
|
|
31
|
-
|
|
27
|
+
1. **An MCP server** (so Claude or Cursor can use your tools).
|
|
28
|
+
2. **A CLI tool** (so you can run it from the terminal like a normal human).
|
|
29
|
+
3. **A web application** (a visual dashboard called "Beam" that makes forms for you).
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Analytics - Query company analytics
|
|
36
|
-
* @dependencies pg@^8.11.0
|
|
37
|
-
*/
|
|
38
|
-
import { Client } from 'pg';
|
|
31
|
+
It looks like this:
|
|
39
32
|
|
|
40
|
-
export default class Analytics {
|
|
41
|
-
private db: Client;
|
|
42
|
-
|
|
43
|
-
constructor(private host: string, private database: string, private password: string) {}
|
|
44
|
-
|
|
45
|
-
async onInitialize() {
|
|
46
|
-
this.db = new Client({ host: this.host, database: this.database, password: this.password });
|
|
47
|
-
await this.db.connect();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/** Get revenue by date range */
|
|
51
|
-
async revenue(params: { startDate: string; endDate: string }) {
|
|
52
|
-
return (await this.db.query(
|
|
53
|
-
'SELECT date, SUM(amount) FROM orders WHERE date BETWEEN $1 AND $2 GROUP BY date',
|
|
54
|
-
[params.startDate, params.endDate]
|
|
55
|
-
)).rows;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
33
|
```
|
|
59
|
-
|
|
60
|
-
Same file, three interfaces:
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
photon mcp analytics # MCP server for Claude, Cursor, Zed
|
|
64
|
-
photon cli analytics revenue # CLI for humans
|
|
65
|
-
photon # Beam web UI
|
|
34
|
+
analytics.photon.ts → MCP Server | CLI Tool | Web UI
|
|
66
35
|
```
|
|
67
36
|
|
|
68
|
-
|
|
69
|
-
<img src="https://raw.githubusercontent.com/portel-dev/photon/main/assets/photon-concept.jpg" alt="Photon — One file, three interfaces" width="700">
|
|
70
|
-
</div>
|
|
37
|
+
You just write the logic. Photon deals with the protocols, schemas, and the boring stuff that usually makes you question your life choices.
|
|
71
38
|
|
|
72
|
-
|
|
39
|
+
### The Basics
|
|
73
40
|
|
|
74
|
-
|
|
41
|
+
If you are just skimming, here is what you need to know:
|
|
75
42
|
|
|
76
|
-
|
|
43
|
+
| Concept | What it is | Learn more |
|
|
44
|
+
|---------|-----------|------------|
|
|
45
|
+
| **MCP** | A way for AI to use your tools. It’s a standard. | [modelcontextprotocol.io](https://modelcontextprotocol.io/introduction) |
|
|
46
|
+
| **Photon file** | A `.photon.ts` file. You define tools as methods in a class. | [Guide](./GUIDE.md) |
|
|
47
|
+
| **Beam** | A web dashboard. It shows your tools as forms. | [Beam UI](#beam) |
|
|
48
|
+
| **Marketplace** | A way to get other people’s photons. | [Marketplace](#marketplace) |
|
|
49
|
+
| **Daemon** | A background thing that handles messages and jobs. | [Daemon Pub/Sub](./DAEMON-PUBSUB.md) |
|
|
50
|
+
| **Tags** | JSDoc comments that tell Photon what to do. | [Tag Reference](./DOCBLOCK-TAGS.md) |
|
|
51
|
+
| **Custom UI** | When the auto-generated forms aren't enough. | [Custom UI Guide](./CUSTOM-UI.md) |
|
|
77
52
|
|
|
78
|
-
|
|
79
|
-
<img src="https://raw.githubusercontent.com/portel-dev/photon/main/assets/beam-dashboard.png" alt="Beam Dashboard" width="700">
|
|
80
|
-
</div>
|
|
53
|
+
### Who Is This For?
|
|
81
54
|
|
|
82
|
-
|
|
55
|
+
* **Developers** who want to give AI access to their database but are too lazy to write a full server.
|
|
56
|
+
* **Teams** who want to share tools without emailing zip files.
|
|
57
|
+
* **Anyone** who wants a CLI and a web UI without writing the boilerplate.
|
|
83
58
|
|
|
84
|
-
|
|
85
|
-
<tr>
|
|
86
|
-
<td width="50%">
|
|
59
|
+
You don't need to know what "MCP" actually stands for. If you can write a TypeScript class, you are qualified.
|
|
87
60
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
**Auto-generated forms** — Built from your TypeScript types. Required fields marked, types validated.
|
|
91
|
-
|
|
92
|
-
</td>
|
|
93
|
-
<td width="50%">
|
|
61
|
+
---
|
|
94
62
|
|
|
95
|
-
|
|
63
|
+
## Quick Start
|
|
96
64
|
|
|
97
|
-
|
|
65
|
+
If you are the type who likes to just run commands and see what happens:
|
|
98
66
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
67
|
+
```bash
|
|
68
|
+
npm install -g @portel/photon
|
|
69
|
+
photon maker new my-tool # Makes a new photon
|
|
70
|
+
photon # Opens the Beam UI
|
|
71
|
+
```
|
|
102
72
|
|
|
103
|
-
|
|
73
|
+
Or if you don't want to install anything (I get it):
|
|
104
74
|
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
private database: string, // → ANALYTICS_DATABASE → text field
|
|
109
|
-
private password: string // → ANALYTICS_PASSWORD → password field
|
|
110
|
-
) {}
|
|
75
|
+
```bash
|
|
76
|
+
npx @portel/photon maker new my-tool
|
|
77
|
+
npx @portel/photon
|
|
111
78
|
```
|
|
112
79
|
|
|
113
|
-
|
|
80
|
+
> **Note:** You need [Node.js 18+](https://nodejs.org). Also, TypeScript helps, but Photon handles the compiling, so you don't have to fight with `tsconfig.json`.
|
|
114
81
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
### Convention Over Configuration
|
|
82
|
+
---
|
|
118
83
|
|
|
119
|
-
|
|
120
|
-
|----------------|-----------------|
|
|
121
|
-
| `analytics.photon.ts` | MCP server name: `analytics` |
|
|
122
|
-
| `async revenue()` | MCP tool: `revenue` |
|
|
123
|
-
| TypeScript types | JSON Schema (auto-generated) |
|
|
124
|
-
| JSDoc comments | Tool descriptions |
|
|
125
|
-
| Constructor params | Env vars + config UI |
|
|
126
|
-
| `@dependencies pg@^8.11.0` | Auto-install on first run |
|
|
84
|
+
## How It Works
|
|
127
85
|
|
|
128
|
-
|
|
86
|
+
A photon is just a TypeScript class. The **public methods become tools**. Photon reads your code, looks at the types, reads your comments, and then generates everything else.
|
|
129
87
|
|
|
130
|
-
|
|
131
|
-
- **Daemon Protocol** — Pub/sub channels, distributed locks, scheduled jobs, webhooks
|
|
132
|
-
- **Custom UIs** — Build rich interfaces with `window.photon` API
|
|
133
|
-
- **OAuth** — Built-in OAuth 2.1 with Google, GitHub, Microsoft providers
|
|
134
|
-
- **MCP Composition** — Call other MCP servers with `@mcp` tag
|
|
135
|
-
- **Deployment** — Docker, Cloudflare Workers, AWS Lambda, Systemd
|
|
88
|
+
I’ll show you.
|
|
136
89
|
|
|
137
|
-
###
|
|
90
|
+
### Step 1: The Bare Minimum
|
|
138
91
|
|
|
139
|
-
|
|
92
|
+
Here is a class with one method. This is a valid photon.
|
|
140
93
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
94
|
+
```typescript
|
|
95
|
+
export default class Weather {
|
|
96
|
+
async forecast(params: { city: string }) {
|
|
97
|
+
return `Weather for ${params.city}: Sunny, 72°F`;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
148
101
|
|
|
149
|
-
|
|
102
|
+
**What happens:** Beam sees this and makes a form with a text box labeled "city". You click a button, and it runs.
|
|
150
103
|
|
|
151
|
-
|
|
104
|
+
**What you get:**
|
|
105
|
+
* `photon mcp weather` (The server for Claude)
|
|
106
|
+
* `photon cli weather forecast --city Paris` (The command line tool)
|
|
107
|
+
* `photon` (The web UI)
|
|
152
108
|
|
|
153
109
|
<div align="center">
|
|
154
|
-
<img src="https://raw.githubusercontent.com/portel-dev/photon/main/assets/
|
|
110
|
+
<img src="https://raw.githubusercontent.com/portel-dev/photon/main/assets/readme-step-1.png" alt="Step 1 — Bare method in Beam" width="600">
|
|
155
111
|
</div>
|
|
156
112
|
|
|
157
|
-
|
|
113
|
+
### Step 2: Adding Descriptions
|
|
158
114
|
|
|
159
|
-
|
|
115
|
+
If you add JSDoc comments, they show up as descriptions.
|
|
160
116
|
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
117
|
+
```typescript
|
|
118
|
+
/**
|
|
119
|
+
* Weather - Check weather forecasts worldwide
|
|
120
|
+
*
|
|
121
|
+
* Provides current conditions.
|
|
122
|
+
*/
|
|
123
|
+
export default class Weather {
|
|
124
|
+
/**
|
|
125
|
+
* Get the weather forecast
|
|
126
|
+
* @param city City name (e.g., "London")
|
|
127
|
+
*/
|
|
128
|
+
async forecast(params: { city: string }) {
|
|
129
|
+
return `Weather for ${params.city}: Sunny, 72°F`;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
165
132
|
```
|
|
166
133
|
|
|
167
|
-
**
|
|
134
|
+
**What happens:** Now the UI has helpful text. Also, the AI client reads this to understand what the tool does.
|
|
168
135
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
git push origin main
|
|
173
|
-
# Team members: photon marketplace add company/photons
|
|
174
|
-
```
|
|
136
|
+
<div align="center">
|
|
137
|
+
<img src="https://raw.githubusercontent.com/portel-dev/photon/main/assets/readme-step-2.png" alt="Step 2 — JSDoc descriptions in Beam" width="600">
|
|
138
|
+
</div>
|
|
175
139
|
|
|
176
|
-
|
|
140
|
+
### Step 3: Configuration (The clever bit)
|
|
177
141
|
|
|
178
|
-
|
|
142
|
+
If you need an API key, put it in the constructor.
|
|
179
143
|
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
144
|
+
```typescript
|
|
145
|
+
export default class Weather {
|
|
146
|
+
constructor(
|
|
147
|
+
private apiKey: string,
|
|
148
|
+
private units: string = 'metric'
|
|
149
|
+
) {}
|
|
150
|
+
|
|
151
|
+
async forecast(params: { city: string }) {
|
|
152
|
+
const res = await fetch(
|
|
153
|
+
`https://api.openweathermap.org/data/2.5/weather?q=${params.city}&appid=${this.apiKey}&units=${this.units}`
|
|
154
|
+
);
|
|
155
|
+
return await res.json();
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
186
159
|
|
|
187
|
-
|
|
188
|
-
photon init <name> # Create new photon
|
|
189
|
-
photon info # List all photons
|
|
190
|
-
photon info <name> --mcp # Get MCP client config
|
|
191
|
-
photon validate <name> # Check for errors
|
|
160
|
+
**What happens:** Beam creates a settings panel. `apiKey` becomes a password field. It also maps to environment variables like `WEATHER_API_KEY`. It just works.
|
|
192
161
|
|
|
193
|
-
|
|
194
|
-
photon
|
|
195
|
-
|
|
196
|
-
photon upgrade # Upgrade all
|
|
162
|
+
<div align="center">
|
|
163
|
+
<img src="https://raw.githubusercontent.com/portel-dev/photon/main/assets/readme-step-3.png" alt="Step 3 — Configuration panel in Beam" width="600">
|
|
164
|
+
</div>
|
|
197
165
|
|
|
198
|
-
|
|
199
|
-
photon doctor # Diagnose environment
|
|
200
|
-
photon audit # Security audit
|
|
201
|
-
photon test # Run tests
|
|
202
|
-
photon deploy # Deploy to production
|
|
203
|
-
```
|
|
166
|
+
### Step 4: Validation (Stop bad inputs)
|
|
204
167
|
|
|
205
|
-
|
|
168
|
+
You can add tags to valid inputs.
|
|
206
169
|
|
|
207
|
-
|
|
170
|
+
```typescript
|
|
171
|
+
/**
|
|
172
|
+
* Weather - Check weather forecasts worldwide
|
|
173
|
+
* @dependencies node-fetch@^3.0.0
|
|
174
|
+
*/
|
|
175
|
+
export default class Weather {
|
|
176
|
+
constructor(
|
|
177
|
+
private apiKey: string,
|
|
178
|
+
private units: string = 'metric'
|
|
179
|
+
) {}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Get the weather forecast for a city
|
|
183
|
+
* @param city City name {@example London} {@pattern ^[a-zA-Z\s]+$}
|
|
184
|
+
* @param days Number of days {@min 1} {@max 7}
|
|
185
|
+
* @format table
|
|
186
|
+
*/
|
|
187
|
+
async forecast(params: { city: string; days?: number }) {
|
|
188
|
+
// fetch and return forecast data...
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
208
192
|
|
|
209
|
-
**
|
|
193
|
+
**What happens:**
|
|
194
|
+
* The `city` input validates the regex.
|
|
195
|
+
* The `days` input becomes a number spinner (1-7).
|
|
196
|
+
* The result is formatted as a table.
|
|
197
|
+
* `@dependencies` makes Photon install `node-fetch` automatically. You don't even run `npm install`.
|
|
210
198
|
|
|
211
|
-
|
|
212
|
-
|-------|-|
|
|
213
|
-
| [Getting Started](https://github.com/portel-dev/photon/blob/main/GUIDE.md) | Create your first photon, step by step |
|
|
214
|
-
| [Advanced](https://github.com/portel-dev/photon/blob/main/ADVANCED.md) | Lifecycle hooks, performance, testing |
|
|
215
|
-
| [Docblock Tags](https://github.com/portel-dev/photon/blob/main/DOCBLOCK-TAGS.md) | Complete JSDoc tag reference |
|
|
216
|
-
| [Troubleshooting](https://github.com/portel-dev/photon/blob/main/TROUBLESHOOTING.md) | Common issues and solutions |
|
|
199
|
+
#### System CLI Dependencies
|
|
217
200
|
|
|
218
|
-
|
|
201
|
+
If your photon wraps a command-line tool (e.g. `ffmpeg`, `git`, `docker`), declare it with `@cli`. Photon checks for the tool at load time and refuses to load if it's missing.
|
|
219
202
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
203
|
+
```typescript
|
|
204
|
+
/**
|
|
205
|
+
* Video processor
|
|
206
|
+
* @cli ffmpeg - https://ffmpeg.org/download.html
|
|
207
|
+
* @cli imagemagick - https://imagemagick.org/script/download.php
|
|
208
|
+
*/
|
|
209
|
+
export default class VideoProcessor {
|
|
210
|
+
async convert({ input, format }: { input: string; format: string }) {
|
|
211
|
+
// ffmpeg is guaranteed to exist if this method runs
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
229
215
|
|
|
230
|
-
|
|
216
|
+
If `ffmpeg` is not installed, the photon won't load and the user sees:
|
|
231
217
|
|
|
232
|
-
|
|
218
|
+
```
|
|
219
|
+
VideoProcessor requires the following CLI tools to be installed:
|
|
220
|
+
- ffmpeg: Install from https://ffmpeg.org/download.html
|
|
221
|
+
```
|
|
233
222
|
|
|
234
|
-
|
|
223
|
+
> See the full [Tag Reference](./DOCBLOCK-TAGS.md) for all available tags. There are 30+ covering validation, UI hints, scheduling, webhooks, and more.
|
|
235
224
|
|
|
236
|
-
|
|
225
|
+
<div align="center">
|
|
226
|
+
<img src="https://raw.githubusercontent.com/portel-dev/photon/main/assets/readme-step-4.png" alt="Step 4 — Validation and formatting in Beam" width="600">
|
|
227
|
+
</div>
|
|
237
228
|
|
|
238
|
-
|
|
229
|
+
### Step 5: Custom UI (When you want to be fancy)
|
|
239
230
|
|
|
240
|
-
|
|
231
|
+
If the auto-generated form is too boring, you can write your own HTML.
|
|
241
232
|
|
|
242
|
-
|
|
233
|
+
```typescript
|
|
234
|
+
/**
|
|
235
|
+
* Weather - Check weather forecasts worldwide
|
|
236
|
+
* @dependencies node-fetch@^3.0.0
|
|
237
|
+
* @ui dashboard ./ui/weather.html
|
|
238
|
+
*/
|
|
239
|
+
export default class Weather {
|
|
240
|
+
constructor(private apiKey: string, private units: string = 'metric') {}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Get the weather forecast for a city
|
|
244
|
+
* @ui dashboard
|
|
245
|
+
* @format table
|
|
246
|
+
*/
|
|
247
|
+
async forecast(params: { city: string; days?: number }) {
|
|
248
|
+
// returns structured weather data
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
```
|
|
243
252
|
|
|
244
|
-
|
|
253
|
+
```html
|
|
254
|
+
<!-- ui/weather.html -->
|
|
255
|
+
<div id="weather-app">
|
|
256
|
+
<div id="forecast"></div>
|
|
257
|
+
</div>
|
|
258
|
+
<script>
|
|
259
|
+
window.photon.onResult(data => {
|
|
260
|
+
document.getElementById('forecast').innerHTML = renderWeather(data);
|
|
261
|
+
});
|
|
262
|
+
</script>
|
|
263
|
+
```
|
|
245
264
|
|
|
246
|
-
|
|
265
|
+
**What changes in Beam:** Instead of the auto-generated table, results render inside your custom HTML (a weather dashboard with icons, charts, or any visualization you build). The `window.photon` API bridges your UI to the tool system.
|
|
247
266
|
|
|
248
|
-
|
|
267
|
+
> Custom UIs follow the [MCP Apps Extension (SEP-1865)](https://github.com/nicolo-ribaudo/modelcontextprotocol/blob/nicolo/sep-1865/docs/specification/draft/extensions/apps.mdx) standard and work across compatible hosts. See the [Custom UI Guide](./CUSTOM-UI.md).
|
|
249
268
|
|
|
269
|
+
<div align="center">
|
|
270
|
+
<img src="https://raw.githubusercontent.com/portel-dev/photon/main/assets/readme-step-5.png" alt="Step 5 — Custom UI result in Beam" width="600">
|
|
250
271
|
</div>
|
|
251
272
|
|
|
252
|
-
|
|
253
|
-
# photon
|
|
273
|
+
### In Summary
|
|
254
274
|
|
|
255
|
-
|
|
275
|
+
| Step | You write | Photon generates |
|
|
276
|
+
|------|---------|-----------------|
|
|
277
|
+
| **1. Methods** | A function | Tools, CLI commands, Forms |
|
|
278
|
+
| **2. JSDoc** | Comments | Descriptions for AI and Humans |
|
|
279
|
+
| **3. Constructor** | Arguments | Config UI, Env vars |
|
|
280
|
+
| **4. Tags** | `@tags` | Validation, Installers, Formatting |
|
|
281
|
+
| **5. Custom UI** | HTML | A custom app |
|
|
256
282
|
|
|
257
|
-
|
|
283
|
+
<div align="center">
|
|
284
|
+
<img src="https://raw.githubusercontent.com/portel-dev/photon/main/assets/photon-ecosystem.png" alt="Photon Ecosystem" width="600">
|
|
285
|
+
</div>
|
|
258
286
|
|
|
259
|
-
|
|
260
|
-
- 📦 **One-command install** via [Photon CLI](https://github.com/portel-dev/photon)
|
|
261
|
-
- 🎯 **Laser-focused** on singular capabilities
|
|
262
|
-
- ⚡ **Zero-config** with auto-dependency management
|
|
263
|
-
- 🔌 **Universal** - works with Claude Desktop, Claude Code, and any MCP client
|
|
287
|
+
---
|
|
264
288
|
|
|
265
|
-
##
|
|
289
|
+
## Beam
|
|
266
290
|
|
|
267
|
-
|
|
268
|
-
|--------|-------|-------|----------|
|
|
269
|
-
| [**Code Diagram**](code-diagram.md) | Generate Mermaid diagrams from TypeScript/JavaScript code | 3 | 🔌📦 |
|
|
270
|
-
| [**Truth Serum**](serum.md) | Forces unfiltered honesty, no hedging or diplomacy @description Powerful prompt serums that force specific cognitive behaviors @icon 💉 /
|
|
271
|
-
export default class Serum {
|
|
272
|
-
/ | 10 | - |
|
|
273
|
-
| [**Test Ui**](test-ui.md) | Test Custom UI | 1 | 🎨 |
|
|
291
|
+
Beam is the dashboard. It’s where you go to poke your tools and see if they work before you let an AI loose on them.
|
|
274
292
|
|
|
293
|
+
Run `photon`. That’s it.
|
|
275
294
|
|
|
276
|
-
|
|
295
|
+
<div align="center">
|
|
296
|
+
<img src="https://raw.githubusercontent.com/portel-dev/photon/main/assets/beam-dashboard.png" alt="Beam Dashboard" width="700">
|
|
297
|
+
</div>
|
|
277
298
|
|
|
278
299
|
---
|
|
279
300
|
|
|
280
|
-
##
|
|
301
|
+
## Connecting to AI
|
|
281
302
|
|
|
282
|
-
|
|
303
|
+
If you want to use this with Claude or Cursor, you need the config.
|
|
283
304
|
|
|
284
305
|
```bash
|
|
285
|
-
|
|
306
|
+
photon info weather --mcp
|
|
286
307
|
```
|
|
287
308
|
|
|
288
|
-
|
|
309
|
+
It spits out some JSON:
|
|
289
310
|
|
|
290
|
-
```bash
|
|
291
|
-
photon add filesystem
|
|
292
|
-
photon add git
|
|
293
|
-
photon add aws-s3
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
### 3. Use It
|
|
297
|
-
|
|
298
|
-
```bash
|
|
299
|
-
# Run as MCP server
|
|
300
|
-
photon mcp filesystem
|
|
301
|
-
|
|
302
|
-
# Get config for your MCP client
|
|
303
|
-
photon get filesystem --mcp
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
Output (paste directly into your MCP client config):
|
|
307
311
|
```json
|
|
308
312
|
{
|
|
309
313
|
"mcpServers": {
|
|
310
|
-
"
|
|
314
|
+
"weather": {
|
|
311
315
|
"command": "photon",
|
|
312
|
-
"args": ["mcp", "
|
|
316
|
+
"args": ["mcp", "weather"]
|
|
313
317
|
}
|
|
314
318
|
}
|
|
315
319
|
}
|
|
316
320
|
```
|
|
317
321
|
|
|
318
|
-
|
|
322
|
+
Copy that. Paste it into your AI client’s config file. Done.
|
|
319
323
|
|
|
320
|
-
|
|
324
|
+
Works with [Claude Desktop](https://claude.ai/download), [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [Cursor](https://cursor.com), and any [MCP-compatible client](https://modelcontextprotocol.io).
|
|
321
325
|
|
|
322
326
|
---
|
|
323
327
|
|
|
324
|
-
##
|
|
328
|
+
## Why did we build this?
|
|
325
329
|
|
|
326
|
-
|
|
330
|
+
Writing an MCP server usually involves 4 to 6 files and about 150 lines of code before you even start writing the thing you actually wanted to write.
|
|
327
331
|
|
|
328
|
-
|
|
332
|
+
With Photon, it’s one file.
|
|
329
333
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
+
| | Traditional MCP | Photon |
|
|
335
|
+
|---|---|---|
|
|
336
|
+
| **Files** | 4-6 (server, transport, schemas, types, config) | 1 |
|
|
337
|
+
| **Boilerplate** | 150+ lines | 0 |
|
|
338
|
+
| **Dependencies** | Manual `npm install` | Automatic |
|
|
339
|
+
| **Schema** | Hand-written JSON Schema | Generated from TS types |
|
|
340
|
+
| **Config** | Manual env var parsing | Automatic from Constructor |
|
|
334
341
|
|
|
335
|
-
|
|
342
|
+
It is unnecessarily difficult to do it the old way. So we stopped doing it.
|
|
336
343
|
|
|
337
|
-
|
|
338
|
-
# Install specific photons you need
|
|
339
|
-
/plugin install filesystem@photons-marketplace
|
|
340
|
-
/plugin install git@photons-marketplace
|
|
341
|
-
/plugin install knowledge-graph@photons-marketplace
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
### Benefits of Claude Code Plugin
|
|
344
|
+
---
|
|
345
345
|
|
|
346
|
-
|
|
347
|
-
- **🔄 Auto-Updates**: Plugin stays synced with marketplace
|
|
348
|
-
- **⚡ Zero Config**: Photon CLI auto-installs on first use
|
|
349
|
-
- **🛡️ Secure**: No credentials shared with AI (interactive setup available)
|
|
350
|
-
- **📦 Individual MCPs**: Each photon is a separate installable plugin
|
|
346
|
+
## Marketplace
|
|
351
347
|
|
|
352
|
-
|
|
348
|
+
We also have a marketplace. 31 photons and counting.
|
|
353
349
|
|
|
354
|
-
|
|
350
|
+
<div align="center">
|
|
351
|
+
<img src="https://raw.githubusercontent.com/portel-dev/photon/main/assets/beam-marketplace.png" alt="Marketplace" width="700">
|
|
352
|
+
</div>
|
|
355
353
|
|
|
356
354
|
```bash
|
|
357
|
-
|
|
358
|
-
photon
|
|
355
|
+
photon search postgres
|
|
356
|
+
photon add postgres
|
|
359
357
|
```
|
|
360
358
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
**
|
|
359
|
+
### Available Photons
|
|
360
|
+
|
|
361
|
+
**Productivity**
|
|
362
|
+
|
|
363
|
+
| Photon | What it does | Tools |
|
|
364
|
+
|--------|-------------|-------|
|
|
365
|
+
| 📌 **kanban** | Multi-tenant task boards for humans and AI | 33 |
|
|
366
|
+
| 📬 **git-box** | Mailbox-style Git interface, manage repos like an inbox | 58 |
|
|
367
|
+
| 📬 **form-inbox** | Webhook-powered form submission collector | 12 |
|
|
368
|
+
| 📅 **google-calendar** | Calendar integration via OAuth | 9 |
|
|
369
|
+
| 🎫 **jira** | Project management and issue tracking | 10 |
|
|
370
|
+
| 💬 **slack** | Send messages and manage Slack workspaces | 7 |
|
|
371
|
+
| 📧 **email** | Send and receive via SMTP/IMAP | 8 |
|
|
372
|
+
|
|
373
|
+
**Infrastructure**
|
|
374
|
+
|
|
375
|
+
| Photon | What it does | Tools |
|
|
376
|
+
|--------|-------------|-------|
|
|
377
|
+
| 📁 **filesystem** | Safe, cross-platform file operations | 13 |
|
|
378
|
+
| 🔀 **git** | Local git repository operations | 11 |
|
|
379
|
+
| 🐙 **github-issues** | Manage GitHub issues and comments | 7 |
|
|
380
|
+
| 🐳 **docker** | Container and image management | 10 |
|
|
381
|
+
| ☁️ **aws-s3** | S3 object storage operations | 11 |
|
|
382
|
+
| 🌐 **web** | DuckDuckGo search + Readability extraction | 2 |
|
|
383
|
+
|
|
384
|
+
**Databases**
|
|
385
|
+
|
|
386
|
+
| Photon | What it does | Tools |
|
|
387
|
+
|--------|-------------|-------|
|
|
388
|
+
| 🐘 **postgres** | PostgreSQL queries and schema ops | 7 |
|
|
389
|
+
| 🗄️ **sqlite** | SQLite database operations | 9 |
|
|
390
|
+
| 🍃 **mongodb** | MongoDB document CRUD and aggregation | 13 |
|
|
391
|
+
| ⚡ **redis** | Key-value store, lists, sets, pub/sub | 18 |
|
|
392
|
+
|
|
393
|
+
**Utilities and Demos**
|
|
394
|
+
|
|
395
|
+
| Photon | What it does | Tools |
|
|
396
|
+
|--------|-------------|-------|
|
|
397
|
+
| 🕐 **time** | Timezone conversion and queries | 3 |
|
|
398
|
+
| 🧮 **math** | Expression evaluator (trig, stats, etc.) | 1 |
|
|
399
|
+
| 📊 **code-diagram** | Generate Mermaid diagrams from code | 3 |
|
|
400
|
+
| 🔴 **connect-four** | Play against AI with distributed locks | 8 |
|
|
401
|
+
| 🍳 **kitchen-sink** | Every runtime feature in one file | 25 |
|
|
402
|
+
| 📋 **dashboard** | MCP Apps UI demo | 6 |
|
|
403
|
+
| 📺 **team-dashboard** | TV/monitor-optimized team display | 20 |
|
|
404
|
+
| 🎭 **mcp-orchestrator** | Combine multiple MCPs into workflows | 10 |
|
|
405
|
+
|
|
406
|
+
You can also make a private marketplace for your team, so internal tools stay off the public internet.
|
|
369
407
|
|
|
370
408
|
---
|
|
371
409
|
|
|
372
|
-
##
|
|
410
|
+
## Commands
|
|
373
411
|
|
|
374
|
-
|
|
375
|
-
- 📁 **Filesystem** - File operations
|
|
376
|
-
- 🐙 **Git** - Repository management
|
|
377
|
-
- ☁️ **AWS S3** - Cloud storage
|
|
378
|
-
- 📅 **Google Calendar** - Calendar integration
|
|
379
|
-
- 🕐 **Time** - Timezone operations
|
|
380
|
-
- ... and more
|
|
412
|
+
A few commands you might use:
|
|
381
413
|
|
|
382
|
-
|
|
414
|
+
```bash
|
|
415
|
+
# Run
|
|
416
|
+
photon # Open Beam UI
|
|
417
|
+
photon mcp <name> # Run as MCP server
|
|
418
|
+
photon mcp <name> --dev # MCP server with hot reload
|
|
419
|
+
photon cli <name> [method] # Run as CLI tool
|
|
383
420
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
- 📦 3 production-ready photons available
|
|
387
|
-
- ⚡ Auto-installs dependencies
|
|
388
|
-
- 🔧 Works out of the box
|
|
389
|
-
- 📄 Single-file design (easy to fork and customize)
|
|
421
|
+
# Create
|
|
422
|
+
photon maker new <name> # Scaffold a new photon
|
|
390
423
|
|
|
391
|
-
|
|
424
|
+
# Manage
|
|
425
|
+
photon info # List all photons
|
|
426
|
+
photon info <name> --mcp # Get MCP client config (paste into Claude/Cursor)
|
|
427
|
+
photon validate <name> # Check for errors
|
|
392
428
|
|
|
393
|
-
|
|
429
|
+
# Marketplace
|
|
430
|
+
photon add <name> # Install photon
|
|
431
|
+
photon search <query> # Search marketplace
|
|
432
|
+
photon upgrade # Upgrade all
|
|
394
433
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
5. Repeat for every server
|
|
434
|
+
# Ops
|
|
435
|
+
photon doctor # Diagnose environment
|
|
436
|
+
photon audit # Security audit
|
|
437
|
+
photon test # Run tests
|
|
438
|
+
```
|
|
401
439
|
|
|
402
|
-
|
|
440
|
+
---
|
|
403
441
|
|
|
404
|
-
|
|
405
|
-
# Install from marketplace
|
|
406
|
-
photon add filesystem
|
|
442
|
+
## Tag Reference (Quick Overview)
|
|
407
443
|
|
|
408
|
-
|
|
409
|
-
photon get filesystem --mcp
|
|
410
|
-
```
|
|
444
|
+
Tags are JSDoc annotations that control how Photon processes your code. Here are the most commonly used ones:
|
|
411
445
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
446
|
+
| Tag | Where | What it does |
|
|
447
|
+
|-----|-------|-------------|
|
|
448
|
+
| `@dependencies` | Class | Auto-install npm packages on first run |
|
|
449
|
+
| `@cli` | Class | Declare system CLI tool dependencies, checked at load time |
|
|
450
|
+
| `@format` | Method | Control result rendering (table, list, markdown, code, etc.) |
|
|
451
|
+
| `@param ... {@choice a,b,c}` | Param | Dropdown selection in Beam |
|
|
452
|
+
| `@param ... {@format email}` | Param | Input validation and field type |
|
|
453
|
+
| `@param ... {@min N} {@max N}` | Param | Numeric range constraints |
|
|
454
|
+
| `@ui` | Class/Method | Link a custom HTML template |
|
|
455
|
+
| `@webhook` | Method | Expose as HTTP endpoint |
|
|
456
|
+
| `@scheduled` | Method | Run on a cron schedule |
|
|
457
|
+
| `@locked` | Method | Distributed lock across processes |
|
|
458
|
+
| `@autorun` | Method | Auto-execute when selected in Beam |
|
|
459
|
+
| `@mcp` | Class | Inject another MCP server as a dependency |
|
|
460
|
+
| `@icon` | Class/Method | Set emoji icon |
|
|
423
461
|
|
|
424
|
-
|
|
462
|
+
> This is a subset. See the full [Tag Reference](./DOCBLOCK-TAGS.md) for all 30+ tags with examples.
|
|
425
463
|
|
|
426
|
-
|
|
427
|
-
- ✅ One CLI, one command
|
|
428
|
-
- ✅ Zero configuration
|
|
429
|
-
- ✅ Instant installation
|
|
430
|
-
- ✅ Auto-dependencies
|
|
431
|
-
- ✅ Consistent experience
|
|
464
|
+
---
|
|
432
465
|
|
|
433
|
-
##
|
|
466
|
+
## Documentation
|
|
434
467
|
|
|
435
|
-
**
|
|
436
|
-
```bash
|
|
437
|
-
photon add filesystem git github-issues
|
|
438
|
-
photon get --mcp # Get config for all three
|
|
439
|
-
```
|
|
440
|
-
Add to Claude Desktop → Now Claude can read files, manage repos, create issues
|
|
468
|
+
**Start here:**
|
|
441
469
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
photon
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
470
|
+
| Guide | |
|
|
471
|
+
|-------|-|
|
|
472
|
+
| [Getting Started](./GUIDE.md) | Create your first photon, step by step |
|
|
473
|
+
| [Tag Reference](./DOCBLOCK-TAGS.md) | Complete JSDoc tag reference with examples |
|
|
474
|
+
| [Naming Conventions](./NAMING-CONVENTIONS.md) | How to name methods so they read naturally as CLI commands |
|
|
475
|
+
| [Troubleshooting](./TROUBLESHOOTING.md) | Common issues and solutions |
|
|
448
476
|
|
|
449
|
-
**
|
|
450
|
-
```bash
|
|
451
|
-
photon add docker git slack
|
|
452
|
-
photon get --mcp
|
|
453
|
-
```
|
|
454
|
-
Automate your workflow through AI
|
|
477
|
+
**Build more:**
|
|
455
478
|
|
|
456
|
-
|
|
479
|
+
| Topic | |
|
|
480
|
+
|-------|-|
|
|
481
|
+
| [Custom UI](./CUSTOM-UI.md) | Build rich interactive interfaces with `window.photon` |
|
|
482
|
+
| [OAuth](./AUTH.md) | Built-in OAuth 2.1 with Google, GitHub, Microsoft |
|
|
483
|
+
| [Daemon Pub/Sub](./DAEMON-PUBSUB.md) | Real-time cross-process messaging |
|
|
484
|
+
| [Webhooks](./WEBHOOKS.md) | HTTP endpoints for external services |
|
|
485
|
+
| [Locks](./LOCKS.md) | Distributed locks for exclusive access |
|
|
486
|
+
| [Advanced Patterns](./ADVANCED.md) | Lifecycle hooks, dependency injection, interactive workflows |
|
|
487
|
+
| [Deployment](./DEPLOYMENT.md) | Docker, Cloudflare Workers, AWS Lambda, Systemd |
|
|
457
488
|
|
|
458
|
-
|
|
459
|
-
# List all photons
|
|
460
|
-
photon get
|
|
489
|
+
**Operate:**
|
|
461
490
|
|
|
462
|
-
|
|
463
|
-
|
|
491
|
+
| Topic | |
|
|
492
|
+
|-------|-|
|
|
493
|
+
| [Security](./SECURITY.md) | Best practices and audit checklist |
|
|
494
|
+
| [Marketplace Publishing](./MARKETPLACE-PUBLISHING.md) | Create and share team marketplaces |
|
|
495
|
+
| [Best Practices](./PHOTON_BEST_PRACTICES.md) | Patterns for production photons |
|
|
496
|
+
| [Comparison](./COMPARISON.md) | Benchmarks vs official MCP implementations |
|
|
464
497
|
|
|
465
|
-
|
|
466
|
-
photon get google-calendar
|
|
498
|
+
**Reference:** [Architecture](./ARCHITECTURE.md) · [Changelog](./CHANGELOG.md) · [Contributing](./CONTRIBUTING.md)
|
|
467
499
|
|
|
468
|
-
|
|
469
|
-
photon upgrade
|
|
470
|
-
```
|
|
500
|
+
---
|
|
471
501
|
|
|
472
|
-
##
|
|
502
|
+
## Contributing
|
|
473
503
|
|
|
474
|
-
|
|
504
|
+
If you find a bug, or if my code offends you, feel free to open an issue or a PR. See [CONTRIBUTING.md](./CONTRIBUTING.md).
|
|
475
505
|
|
|
476
|
-
|
|
477
|
-
# 1. Organize photons
|
|
478
|
-
mkdir company-photons && cd company-photons
|
|
506
|
+
## License
|
|
479
507
|
|
|
480
|
-
|
|
481
|
-
photon maker sync
|
|
508
|
+
[MIT](./LICENSE). Do what you want with it.
|
|
482
509
|
|
|
483
|
-
|
|
484
|
-
git push origin main
|
|
510
|
+
---
|
|
485
511
|
|
|
486
|
-
|
|
487
|
-
photon marketplace add company/photons
|
|
488
|
-
photon add your-internal-tool
|
|
489
|
-
```
|
|
512
|
+
<div align="center">
|
|
490
513
|
|
|
491
|
-
|
|
514
|
+
*Singular focus. Precise target.*
|
|
492
515
|
|
|
493
|
-
|
|
516
|
+
Made by [Portel](https://github.com/portel-dev)
|
|
494
517
|
|
|
495
|
-
|
|
518
|
+
</div>
|
|
496
519
|
|
|
497
|
-
<!-- PHOTON_MARKETPLACE_END -->
|