Browser features in your app
Camera, microphone, and location ask the browser for permission, and a chat host can block that prompt before it shows. A file picker asks for nothing, so it always works.
Which features work where
| Feature | Standalone app URL | Rendered inline in a chat |
|---|---|---|
| Camera | Works, once you claim the app | Blocked: the chat host denies the permission prompt |
| Location | Works, once you claim the app | Blocked: the chat host denies the permission prompt |
| Microphone | Works, once you claim the app | Blocked: the chat host denies the permission prompt |
| File picker | Works | Works |
Camera, location, and microphone. Claim the app, then use these features at its standalone URL. Chat hosts block the permission prompt. Charming shows a link to the standalone app when needed.
File picker. It needs no manifest import or claim, so it works in both hosts. See Data storage.
Camera and microphone streams are device API results, not external audio or video files. The capability import controls browser permission at the standalone URL. It does not add a CSP media-src origin or make uploaded media playable inline.
Build so it works in every host
Declare the matching capability import, call the normal Web API, and handle denial. Do not build a second permission message. For a file picker, use a normal file input and the storage API.
Technical
The table above is the host contract. The full build reference lists the exact capability imports.
Copy this prompt for your agent
Add a browser feature to my Charming app: camera, location, or
microphone. Read
https://charm.ing/docs/guides/browser-features.md first. Work out
which one I need from what I'm asking for, and build it so it falls
back cleanly when the permission is blocked. Ask me if it isn't
obvious which feature I want.
If you haven't built a Charming app before, read
https://charm.ing/docs/build-mcp.md (or build-http.md for the HTTP
API) for the app skeleton first.
How an agent performs this job
Declare charming:browser/[email protected], charming:browser/[email protected], or charming:browser/[email protected], then call the matching Web API. A file picker needs no import.
The contract
Camera, location, and microphone require a claimed app and its standalone URL. Charming’s inline viewer uses an opaque frame without the per-app capability origin, so these delegated permissions stay blocked in chat. Use an Open in web fallback.