PhotonBLOCK
Define intent once. Photon turns a single TypeScript file into CLI tools, MCP servers, and web interfaces.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](https://www.npmjs.com/package/@portel/photon) [](https://www.npmjs.com/package/@portel/photon) [](https://github.com/portel-dev/photon/blob/main/LICENSE) [](https://www.typescriptlang.org) [](https://nodejs.org) [](https://modelcontextprotocol.io) [](https://photon.portel.dev/)
One TypeScript capability becomes the whole agent stack.
Photon is the fastest way to turn a small, verified TypeScript method into something humans can operate and agents can trust. Write the capability once; Photon derives the interfaces, contracts, and runtime behavior around it:
- MCP server for Claude, ChatGPT, Cursor, and agents
- Embedded app UI for chat clients that support MCP app resources
- CLI tool for scripts, demos, and automation
- Beam web interface for humans
- Web routes, schedules, webhooks, retries, state, and audit history when the
capability grows into a production workflow
Photon is free and open source software released under the MIT license. Full documentation lives at photon.portel.dev.
Related Portel project: NCP gives agents one natural MCP interface to discover and run tools across a whole tool ecosystem. Photon builds reliable agent-facing capabilities; NCP helps agents find and use them alongside every other MCP.
Try it in two minutes:
fde76c1fe2d3OBSERVED · 2026-10-07Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add photon-vue-ui --env CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN} --env CONFIG_RUNTIME_API_KEY=${CONFIG_RUNTIME_API_KEY} --env GITHUB_TOKEN=${GITHUB_TOKEN} --env PHOTON_A2A_AUTH=${PHOTON_A2A_AUTH} -- npx -y [email protected]{
"mcpServers": {
"photon-vue-ui": {
"command": "npx",
"args": [
"-y",
"[email protected]"
],
"env": {
"CLOUDFLARE_API_TOKEN": "${CLOUDFLARE_API_TOKEN}",
"CONFIG_RUNTIME_API_KEY": "${CONFIG_RUNTIME_API_KEY}",
"GITHUB_TOKEN": "${GITHUB_TOKEN}",
"PHOTON_A2A_AUTH": "${PHOTON_A2A_AUTH}"
}
}
}
}Exposed tools (114)
100 read · 12 write · 2 destructive. Blast radius: 2 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
000-before-boundary | read | Inserted before the old offset boundary |
Basic | read | Minimal hello-world photon |
_instances | read | List all available instances. |
_redo | read | Redo the last undone mutation. Re-applies a previously undone change. |
_undo | read | Undo the last state mutation. Reverts the most recent tool call |
_use | read | Switch to a named instance. Pass empty name for default. Omit name to select interactively. |
add | write | Add a new todo item |
ag-ui | read | Supports AG-UI protocol for agent-to-agent UI |
alpha | read | Alpha method |
analyst | read | Data analysis agent |
analyze | read | Analyze a dataset |
approval | read | Wait for approval |
ask | read | Ask for a name |
autoapp.helper | read | Helper |
autoapp.main | read | Main entry |
background | read | Durable background task |
beta | read | Beta tool |
browse | read | Browse menu |
build | read | Build |
calendar | read | Calendar management |
compute | write | Run a computation |
confirm_delete | destructive | Task that requires confirmation |
createTask | write | Create task |
current | read | Get weather |
delegate | read | |
deleteTask | destructive | Delete task |
demo.echo | read | Echo input |
deploy | write | |
destructive | read | Destructive fixture |
disabled | read | Return false |
doStuff | read | |
documentedHelper | read | Helper @internal |
echo | read | Idempotent instance echo |
editTool | write | Edit something |
empty | read | |
eval | read | Evaluate expression |
events | read | List events |
exec | write | Run via tool |
execute | write | Run command |
fail | read | Return a business failure |
failing_job | read | Required failing task |
fetch | read | |
forecast | read | Get forecast |
go | read | |
greet | read | Synchronous greeting |
helper | read | |
hidden | read | |
invalid | read | Return an invalid declared result |
json_schema_2020_12_tool | read | Tool with JSON Schema 2020-12 features |
label | read | Return a string |
list | read | List all todo items |
lookup | read | Route lookup |
main | read | Open the demo app |
metrics | read | Report process memory for load verification |
mixed | read | |
multi_input | read | Task requiring multiple inputs |
mutate | read | Non-idempotent mutation |
myapp.helper | read | Helper |
myapp.main | read | Main entry |
no-namespace | read | System tool |
nothing | read | Return null |
notify | read | Broadcast a list invalidation |
open | read | Open the UI. |
photon-beam | read | Photon Beam MCP Server — interactive photon runtime |
photon.method | read | Valid |
photon_context_get | read | Read the current semantic Beam/application context for this session. |
photon_get_current_page_summary | read | Return the title, route, URL, and first visible paragraphs from the current Photon documentation page. |
photon_list_docs | read | List Photon documentation pages, optionally filtered by section such as guides, reference, internals, tutorials, or start. |
photon_navigate | read | Request navigation to a registered Photon view in the current application. |
photon_open_docs_page | read | Navigate the current browser tab to a Photon documentation page by route or URL. |
photon_search_docs | read | Search the Photon documentation site for pages about MCP, CLI, Beam, WebMCP, deployment, docblock tags, output formats, and other Photon topics. |
photon_skill_read | read | Read a declared Photon SKILL.md by name when more guidance is needed.${skillCatalog ? |
ping | write | Send a ping — the server will push a pong back via channel notification |
plain | read | |
pong | read | Reply to a channel message |
protocol_error_job | read | Protocol-error task |
report | read | Generate report |
reportRoots | read | Report current roots |
reported | read | Reports an upstream error result |
rows | read | List rows |
run | write | Run |
sample | read | Ask the client model |
save | write | Save a record |
search | read | Search |
sequence | read | Ask and then sample |
settings | write | View or update settings |
setup | write | Set up ${unresolved.name} — call this tool to begin. |
show | read | Show the UI |
slow_compute | read | Durable computation |
stateful | read | Maintains state across interactions |
status | read | Watch status |
stream | read | |
streaming | read | Supports streaming responses via SSE |
summarize | read | Summarize |
tags | read | List tags |
test | read | A test tool |
test_custom_header | read | Custom routing header fixture |
test_input_required_result_prompt | read | Prompt requiring input |
test_prompt_with_arguments | read | Prompt with arguments |
test_prompt_with_embedded_resource | read | Prompt with embedded resource |
test_prompt_with_image | read | Prompt with image |
test_simple_prompt | read | Simple prompt |
test_tool_with_task | read | MRTR then task composition |
throws | read | Throws an upstream transport failure |
todo | read | A todo list manager |
tool1 | read | Test tool |
tool_execution | read | Executes tools via MCP protocol |
unsafe | read | Unsafe route |
unsafeSchema | read | Declare a forbidden external reference |
url | read | Perform URL elicitation |
valid | read | Valid external result |
visible | read | Visible description |
weather | read | Weather service |
zero | read | Return zero |
Trust audit
BLOCKgrade F · trust 50/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | WARN |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | WARN |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (11 observation(s))
- Network
- declared (9 observation(s))
- Shell
- declared (10 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- found
Findings (25)
if (process.platform === 'darwin') exec('open "' + beamUrl + '"');else if (process.platform === 'win32') exec('start "" "' + beamUrl + '"');else exec('xdg-open "' + beamUrl + '" 2>/dev/null');exec(query: string): Promise<D1ExecResult>;
return await new Function('m', 'return import(m)')(modName);asset-encoding.ts
console.log(token);
secret: 'test-auth-secret-at-least-16',
secret: 'test-secret-at-least-32-chars-long-1234',
secret: 'test-secret-at-least-32-chars-long-1234',
<div data-method="add" data-trigger="click" style="display: none;"></div>
confirm_delete, deleteTask
asset-encoding.test.ts
.release-it.json
.vscodeignore
const bundlePath = path.join(__dirname, '../../dist/beam.bundle.js');
content = await readText(path.join(__dirname, '../../dist', bundleName));
const workerPath = path.join(__dirname, '../../dist/beam-ts-worker.js');
import type { ClientType as Client } from '../../mcp/sdk-v2-2026/client.js';import { logger } from '../../shared/logger.js';curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:35678/api/ui/main/curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:35678/api/ui/main/assets/main.jscurl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:35678/api/ui/main/assets/main.csscurl -X POST http://127.0.0.1:3000/api/v1/photon/stereogram/tools/open \
export PHOTON_MCP_JWT_AUDIENCE=http://127.0.0.1:3000/mcp
Gates applied: no_behavioural_pass.
fde76c1fe2d3full audit observations/trust-audit/mcp-server/portel-dev__photon.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-07 | fde76c1fe2d3 | BLOCK | F | 50 | first audit |
Questions
What is the Photon MCP server?
Define intent once. Photon turns a single TypeScript file into CLI tools, MCP servers, and web interfaces.
What tools does Photon expose?
114 in total: 100 read-only, 12 that write, and 2 that can delete or overwrite (confirm_delete, deleteTask). Every one is listed on this page with its risk.
Is Photon safe to connect to an agent?
No — not without reading the findings first. The audit graded it F (50/100) and found 5 critical or high issues in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 2 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does Photon need?
It reads CLOUDFLARE_API_TOKEN, CONFIG_RUNTIME_API_KEY, GITHUB_TOKEN, PHOTON_A2A_AUTH, PHOTON_MCP_AUTHORIZATION_SERVER, PHOTON_MCP_AUTH_MODE, PHOTON_MCP_OAUTH_ISSUER, PHOTON_MCP_OAUTH_KV_ID, PHOTON_OAUTH_ENCRYPTION_KEY, PHOTON_OAUTH_HOST_SUBJECTS, PHOTON_OAUTH_JWT_SECRET and PHOTON_OAUTH_KEY_ID from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does Photon run?
It speaks sse, stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as photon-vue-ui at 0.0.0.
How current is this page?
The grade is for one exact copy of the source (fde76c1fe2d3), read on 2026-10-07. The repository is watched and re-audited when it changes.