Atlas / MCP servers / portel-dev / Photon

PhotonBLOCK

mcp/portel-dev/photon

Define intent once. Photon turns a single TypeScript file into CLI tools, MCP servers, and web interfaces.

Verdict
BLOCK
Grade
F
Trust score
50 /100
Exposed tools
114 100r · 12w · 2d
Transport
sse · stdio · streamable-http
License
MIT
Stars
100
01

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:

Read from source at commit fde76c1fe2d3OBSERVED · 2026-10-07
02

Connect

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-code
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]
claude-desktop
{
  "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}"
      }
    }
  }
}
03

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.

ToolRiskDescription
000-before-boundaryreadInserted before the old offset boundary
BasicreadMinimal hello-world photon
_instancesreadList all available instances.
_redoreadRedo the last undone mutation. Re-applies a previously undone change.
_undoreadUndo the last state mutation. Reverts the most recent tool call
_usereadSwitch to a named instance. Pass empty name for default. Omit name to select interactively.
addwriteAdd a new todo item
ag-uireadSupports AG-UI protocol for agent-to-agent UI
alphareadAlpha method
analystreadData analysis agent
analyzereadAnalyze a dataset
approvalreadWait for approval
askreadAsk for a name
autoapp.helperreadHelper
autoapp.mainreadMain entry
backgroundreadDurable background task
betareadBeta tool
browsereadBrowse menu
buildreadBuild
calendarreadCalendar management
computewriteRun a computation
confirm_deletedestructiveTask that requires confirmation
createTaskwriteCreate task
currentreadGet weather
delegateread
deleteTaskdestructiveDelete task
demo.echoreadEcho input
deploywrite
destructivereadDestructive fixture
disabledreadReturn false
doStuffread
documentedHelperreadHelper @internal
echoreadIdempotent instance echo
editToolwriteEdit something
emptyread
evalreadEvaluate expression
eventsreadList events
execwriteRun via tool
executewriteRun command
failreadReturn a business failure
failing_jobreadRequired failing task
fetchread
forecastreadGet forecast
goread
greetreadSynchronous greeting
helperread
hiddenread
invalidreadReturn an invalid declared result
json_schema_2020_12_toolreadTool with JSON Schema 2020-12 features
labelreadReturn a string
listreadList all todo items
lookupreadRoute lookup
mainreadOpen the demo app
metricsreadReport process memory for load verification
mixedread
multi_inputreadTask requiring multiple inputs
mutatereadNon-idempotent mutation
myapp.helperreadHelper
myapp.mainreadMain entry
no-namespacereadSystem tool
nothingreadReturn null
notifyreadBroadcast a list invalidation
openreadOpen the UI.
photon-beamreadPhoton Beam MCP Server — interactive photon runtime
photon.methodreadValid
photon_context_getreadRead the current semantic Beam/application context for this session.
photon_get_current_page_summaryreadReturn the title, route, URL, and first visible paragraphs from the current Photon documentation page.
photon_list_docsreadList Photon documentation pages, optionally filtered by section such as guides, reference, internals, tutorials, or start.
photon_navigatereadRequest navigation to a registered Photon view in the current application.
photon_open_docs_pagereadNavigate the current browser tab to a Photon documentation page by route or URL.
photon_search_docsreadSearch the Photon documentation site for pages about MCP, CLI, Beam, WebMCP, deployment, docblock tags, output formats, and other Photon topics.
photon_skill_readreadRead a declared Photon SKILL.md by name when more guidance is needed.${skillCatalog ?
pingwriteSend a ping — the server will push a pong back via channel notification
plainread
pongreadReply to a channel message
protocol_error_jobreadProtocol-error task
reportreadGenerate report
reportRootsreadReport current roots
reportedreadReports an upstream error result
rowsreadList rows
runwriteRun
samplereadAsk the client model
savewriteSave a record
searchreadSearch
sequencereadAsk and then sample
settingswriteView or update settings
setupwriteSet up ${unresolved.name} — call this tool to begin.
showreadShow the UI
slow_computereadDurable computation
statefulreadMaintains state across interactions
statusreadWatch status
streamread
streamingreadSupports streaming responses via SSE
summarizereadSummarize
tagsreadList tags
testreadA test tool
test_custom_headerreadCustom routing header fixture
test_input_required_result_promptreadPrompt requiring input
test_prompt_with_argumentsreadPrompt with arguments
test_prompt_with_embedded_resourcereadPrompt with embedded resource
test_prompt_with_imagereadPrompt with image
test_simple_promptreadSimple prompt
test_tool_with_taskreadMRTR then task composition
throwsreadThrows an upstream transport failure
todoreadA todo list manager
tool1readTest tool
tool_executionreadExecutes tools via MCP protocol
unsafereadUnsafe route
unsafeSchemareadDeclare a forbidden external reference
urlreadPerform URL elicitation
validreadValid external result
visiblereadVisible description
weatherreadWeather service
zeroreadReturn zero
04

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.

LayerWhat it checksResult
L0Provenance & inventoryWARN
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)WARN
L3Class-specific surfaceWARN
L4Behavioural (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)

HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/cli/commands/build.ts:1204
if (process.platform === 'darwin') exec('open "' + beamUrl + '"');
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/cli/commands/build.ts:1205
else if (process.platform === 'win32') exec('start "" "' + beamUrl + '"');
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/cli/commands/build.ts:1206
else exec('xdg-open "' + beamUrl + '" 2>/dev/null');
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/serv/db/d1-client.ts:18
exec(query: string): Promise<D1ExecResult>;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/shared/sqlite-runtime.ts:129
return await new Function('m', 'return import(m)')(modName);
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
MEDIUMInventory / provenance · inv.binary · CWE-1104
src/shared/asset-encoding.ts
asset-encoding.ts
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
src/cli/commands/auth.ts:117
console.log(token);
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
tests/auth-delivery.test.ts:14
secret: 'test-auth-secret-at-least-16',
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
tests/auth-endpoints.test.ts:75
secret: 'test-secret-at-least-32-chars-long-1234',
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
tests/auth-endpoints.test.ts:1169
secret: 'test-secret-at-least-32-chars-long-1234',
MEDIUMPrompt injection · prompt.hidden_style · CWE-94, CWE-1427
examples/todo/ui/dashboard.photon.md:17
<div data-method="add" data-trigger="click" style="display: none;"></div>
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
confirm_delete, deleteTask
Why it matters. 2 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWInventory / provenance · inv.binary · CWE-1104
tests/asset-encoding.test.ts
asset-encoding.test.ts
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
LOWInventory / provenance · inv.hidden_file · CWE-1104
.release-it.json
.release-it.json
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
packages/vscode-photon/.vscodeignore
.vscodeignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/auto-ui/beam.ts:2171
const bundlePath = path.join(__dirname, '../../dist/beam.bundle.js');
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/auto-ui/beam.ts:2195
content = await readText(path.join(__dirname, '../../dist', bundleName));
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/auto-ui/beam.ts:2216
const workerPath = path.join(__dirname, '../../dist/beam-ts-worker.js');
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/auto-ui/beam/external-mcp-manager.ts:13
import type { ClientType as Client } from '../../mcp/sdk-v2-2026/client.js';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/auto-ui/beam/external-mcp-manager.ts:14
import { logger } from '../../shared/logger.js';
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
docs/guides/CONVERT-FRONTEND-APP.md:137
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:35678/api/ui/main/
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
docs/guides/CONVERT-FRONTEND-APP.md:138
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:35678/api/ui/main/assets/main.js
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
docs/guides/CONVERT-FRONTEND-APP.md:139
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:35678/api/ui/main/assets/main.css
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
docs/guides/CONVERT-FRONTEND-APP.md:151
curl -X POST http://127.0.0.1:3000/api/v1/photon/stereogram/tools/open \
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
docs/guides/MCP-JWT-AUTH.md:183
export PHOTON_MCP_JWT_AUDIENCE=http://127.0.0.1:3000/mcp

Gates applied: no_behavioural_pass.

Audited 2026-10-07 · audit v0.4.1 · source sha fde76c1fe2d3full audit observations/trust-audit/mcp-server/portel-dev__photon.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-07fde76c1fe2d3BLOCKF50first audit
06

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.

Advertisement