ENDPOINT 1
https://app.wignet.app/mcp
MCP server metadata
- Name
- wignet-owner
- Version
- 2.0.0
# Wignet: agent guide You drive one Wignet: a remote screen. You publish to it; it shows the content when it next syncs. Everything below is English and stable. - REST base: https://app.wignet.app/api/owner/<device-link> - MCP server: https://mcp.wignet.app/<device-link> - OpenAPI: https://app.wignet.app/api/owner/<device-link>/openapi.json - Owner's page: https://app.wignet.app/w/<device-link> Read get_orientation first: it gives the size to draw at, the orientation and the inks. ## Show something: pick the simplest that fits 1. **Text**: `push_event {"text": "..."}`, in Markdown or plain. It shows for 3 hours (`duration_seconds`, 60 to 86400) from when the screen downloads it, then the screen returns to its slides; `"standing": true` replaces the slides instead. On a screen with nothing of its own yet (no slides, or only the Welcome page), it stays. The server lays it out in black on yellow (white on a black-and-white screen), as large as it fits: `# ` a title, `## ` a subtitle, `**bold**`, `- ` or `1. ` lists, `> ` a quote, `---` a rule, and a table whose last column is right-aligned, the way to show a schedule or a scoreboard: `{"text": "# Today\n| Gym | 18:00 |\n| Shopping | 19:30 |"}`. At most 1000 characters and 12 list items and table rows; a text that does not fit the screen at 16 px is refused, saying how much does. Emoji are left out (the font has none). `"format": "plain"` shows the characters as typed. 2. **Your own image**: `push_image`. Draw it at the size above. Send it, best first: - as a file, if you have a shell: `curl -F image=@card.png https://app.wignet.app/api/owner/<device-link>/push_image` (or raw bytes: `curl --data-binary @card.png -H 'Content-Type: image/png' https://app.wignet.app/api/owner/<device-link>/push_image`); - as a public URL: `{"image_url": "https://..."}`; - as base64, as a last resort: `{"image_base64": "...", "image_sha256": "<hex>"}`. Every character goes through the conversation and one wrong character ruins the image, so always send the sha256: a damaged copy is then refused instead of shown. A photo the owner has at hand can be dropped at https://app.wignet.app/w/<device-link>#photo instead: there they add it as a slide, show it for 10 min to 24 h, or replace the slides with it. `mode` defaults to `auto`: a flat graphic (64 colours or fewer) is printed in the nearest inks, a photo is dithered. Force `threshold` or `dither` only if auto is wrong. `fit` is `contain` (default, letterbox) or `cover` (crop). Leave `orientation` out: the publication follows the screen. Give `landscape` or `portrait` only to draw one on the other axis; which edge is up always comes from the screen. Add `"dry_run": true` (or `-F dry_run=true`) to either (a text or an image on `push_event`, not with a sound) to render without publishing: you get a `preview_url` to check, and the screen is untouched. ## Example, end to end (shell) ```sh curl -s https://app.wignet.app/api/owner/<device-link>/get_orientation # size, orientation, inks python3 draw.py # writes card.png at that size curl -s -F image=@card.png -F dry_run=true https://app.wignet.app/api/owner/<device-link>/push_image # check preview_url curl -s -F image=@card.png https://app.wignet.app/api/owner/<device-link>/push_image # publish curl -s https://app.wignet.app/api/owner/<device-link>/state # content.delivery: waiting, then fetched ``` ## What the answers mean - Every publication answers with `preview_url` (exactly what the panel will show) and `rendering` (page size, rotation, mode used, and a note when your image had to be scaled). - Published means stored on the server. The screen downloads it at its next contact: `next_contact_expected_at` says when, and `get_state` then reports `content.delivery.state` = `fetched`, with `fetched_at`. The server cannot wake a sleeping screen. - The screen's standing content is a list of slides. `push_image`, `set_custom_image`, `push_event` with `standing: true` and `set_slides` replace it (the answer gives `replaced_slides`); a `push_event` text or image without `standing` shows above it for `duration_seconds`, counted from when the screen downloads it, and the slides pause meanwhile, then resume on the same slide. A push the screen has not downloaded within 24 hours is dropped. `get_state` → `pushed` gives its status. ## Slides `set_slides {"slides": [{"text": "..."}, {"image_url": "..."}, {"publication_id": "..."}], "seconds": 600}` sets the list, in order; a `publication_id` (from `get_state` → `slides.items`) keeps a slide without sending it again. `add_slide` adds one (at the end, or at `position`), `remove_slide {"publication_id": ...}` drops one, `set_slide_interval {"seconds": ...}` sets how long each shows (`get_capabilities` → `slides`: 60 to 86400 s, 600 by default, 50 slides at most). The server's clock decides which slide shows; a new list starts again at slide 1, while adding, removing or a new interval keeps the slide showing. On battery, every change wakes the screen: the answer says so. ## Planning and refreshing Use get_events/set_events for planned text, images and sounds, update_event to change one event (alarms are events with a sound) and delete_event to remove one. A sound can be a tune or a chime picked by name: get_tunes lists them (built-in and saved on this Wignet, each with a preview_url), and sound {"tune_name": "..."} sets one. Leave a sound's volume out: it follows the Wignet's, which set_sound_volume changes for every sound at once. set_events replaces the whole list: read get_events first and send everything back. Per Wignet: 32 planned events, 16 with an image. An immediate publication supersedes event windows already open; later occurrences and sounds stay scheduled. The server never fetches or redraws anything on its own: images are copied once, when you publish or save the event. A recurring event with an image shows the same image every time. For fresh data, compose a new image and call set_events again before the window opens (planned time minus lead_seconds). If you cannot run at a set time, tell the owner the image will not update. ## When something goes wrong `get_device_log` lists the calls made to this Wignet over MCP or REST in the last 30 days, newest first: the action, when, the argument names, how it ended and, for a refusal, the error (`{"errors_only": true}` keeps only those; `since` narrows it). Read it before asking the owner what happened: an earlier refusal, a call that never arrived, another agent or the owner's page changing a setting. Combine it with `get_state` (last contact, delivery) and `get_power_history`. The text or image sent is never kept. If you still cannot explain it, offer the owner to write to contact@wignet.app with what you found: the Wignet's name, its link, the times and the errors. ## Conventions - Reads are GET, writes are POST with a JSON body: `https://app.wignet.app/api/owner/<device-link>/<action>`. Short read names work too (`/state`, `/capabilities`, `/screen`, `/events`, `/log`). An unknown action answers 404 with the list of valid ones. - Errors are JSON: `{"error": "...", "field": "..."}`. - Orientations: landscape, portrait, landscape_inverse, portrait_inverse. The `_inverse` ones are the screen's: they tell the platform its top is the other edge, for every publication. - The Wignet's name (`get_state` → `name`, null until one is given) is what the owner calls it. When they give it one, `set_name {"name": "Kitchen"}` keeps it on the platform (`null` clears it): their page shows it at once, other agents read it, and the link and identifier stay the same. - Resolution and display profile are administrator settings. The owner's page shows the current content and, under its Schedule tab, the planned events (read-only); it can also set the Wignet's name, orientation and battery sync frequency. Guides (Agent Skills) explain how to do well what these tools allow: read_skill without arguments lists them, read_skill with a uri reads one of their files. Read skill://wignet/SKILL.md before composing or sending an image (photos included). For a more polished visual than a card, the Wignet's get_capabilities gives in skills.design the files of skill://wignet-visuals/SKILL.md to read for its display profile (black and white or six colours); skills.tune, skill://wignet-tunes/SKILL.md, before writing an alarm tune for a Wignet that plays them; skills.events, skill://wignet-alarm/SKILL.md before setting an alarm and skill://wignet-notify/SKILL.md before sending a notification (a sound or a message now, or at a given time). When the owner wants a use case rather than a single action (a photo slideshow, a smart alarm clock…), read_recipe lists recipes: its outcome, what it requires, and which of these tools make it.
Known tools 37
get_stateRead durable and selected content, Wignet capabilities, power and last physical contact.
Inferred read-onlyget_capabilitiesRead the effective capabilities and their source (firmware report or admin verification): screen (display profile), speaker, microphone and alarms, and in skills the guides (skill://…) to read for this particular Wignet.
Inferred read-onlyget_orientationRead what to draw for: draw_width x draw_height (the page in the current orientation), the orientation, the display profile and its inks.
Inferred read-onlyset_orientationSet how the screen hangs and regenerate local prepared content without fetching URLs.
Inferred read-onlyget_local_timeRead the trusted UTC time, the derived local time and the IANA time zone saved for this device.
Inferred read-onlyset_battery_sync_intervalSet, in seconds, how often the screen syncs with the server when it is on battery (get_state → power).
Inferred read-onlyget_power_historyRead the Wignet's power history, newest to oldest: plugged in or on battery, level, voltage, charging.
Inferred read-onlyset_powered_sync_intervalSet, in seconds, how often the screen syncs with the server when it is plugged in (get_state → power).
Inferred read-onlyset_power_sourceState whether the Wignet is plugged in (`powered`) or on battery (`battery`), for a Wignet that does not detect it itself (get_state → power.can_state).
Inferred read-onlyreset_battery_sync_intervalRestore battery sync cadence to 3600s at the screen's next contact.
Inferred read-onlyget_eventsRead the Wignet's events: planned (weekly or one-off, alarms included) and pushed, with their sound, their text and their next occurrence in the device's time zone; sound_supported says whether the Wignet can ring; last_seen_at says when it last woke up.
Inferred read-onlyset_eventsReplace ALL planned events (alarms included): read get_events first and send back the complete list.
Potential side effectsupdate_eventChange one planned event (alarm included) by its id, giving only what changes: the rest of the event and the other events are kept.
Inferred read-onlycancel_eventCancel a pushed sound (push_event) the screen has not received yet, by its id (see get_events).
Inferred read-onlydescribe_deviceIdentify a Wignet from its page link or its identifier: returns its name and its link.
Inferred read-onlyset_custom_imageCustom: fetch a URL once per explicit call and publish its image.
Potential side effectspush_imagePublish one durable image by URL, base64 or conversation file; exactly one source.
Potential side effectsset_nameName this Wignet, as the owner calls it ("Kitchen", "Kooleur"): the owner's page, describe_device and get_state show it from now on, and a Welcome page still showing is redrawn with it.
Inferred read-onlyset_message_backgroundColour screens only: the ink text messages are drawn on, yellow by default.
Inferred read-onlyset_sound_volumeSet how loud this Wignet plays, 0 to 100 (50 by default): every alarm, chime and pushed sound without its own volume follows it, from the next sync.
Inferred read-onlydelete_eventDelete one planned event (alarm included) by its id, as get_events gives it; every other event is kept.
Potential side effectspush_eventShow a text or an image, and/or queue a supported sound for the next wake.
Inferred read-onlyset_slidesReplace the slides the screen cycles through, in order: each a text ({"text": "...", "format"?, "orientation"?}), an image ({"image_url": ...} with fit, mode, orientation), or a slide already published ({"publication_id": ...}, from get_state slides.items) to keep or reorder it without sending it again.
Inferred read-onlyadd_slideAdd one text or image to the slides, at the end or at position (0 is first), and keep the others.
Inferred read-onlyremove_slideRemove one slide by its publication_id (get_state slides.items); the last slide cannot be removed.
Potential side effectsend_pushEnd the text or image push_event is showing for a while, now; the screen returns to its slides at its next contact.
Inferred read-onlyget_device_logRead the calls made to this Wignet over MCP or REST in the last 30 days, newest first: action, when, which arguments were given, how it ended and, for a refusal, the error.
Inferred read-onlyget_tunesList the tunes and chimes that can be picked by name: built-in ones, then the ones saved on this Wignet.
Inferred read-onlysave_tuneKeep a tune or a chime on this Wignet under a name, so it can be picked later without writing it again (sound {"tune_name": "<name>"}).
Inferred read-onlyset_slide_intervalSet how long each slide shows, in seconds (get_capabilities slides gives the bounds).
Inferred read-onlyread_skillRead a guide (Agent Skill) written for you: how to use these tools well for a given task.
Inferred read-onlyread_recipeRecipes bridge these generic tools and a use case the owner wants (a photo slideshow, a smart alarm clock…): its outcome, what it requires from you, how it shares the screen, and the tools it needs.
Inferred read-onlypreview_tuneLet the owner hear an alarm tune (MML, see the tune field of set_alarm_schedule) before setting it: checks the text, then returns a link to a player that plays it in the browser exactly as the Wignet synthesizes it, on a loop (without the alarm's fade-in).
Inferred read-onlylist_productsList the frames on sale with their live price and stock: slug, name, description, price (VAT and shipping included), units remaining, sold_out, photo, and the product page to link a person to.
Inferred read-onlyget_productOne frame by its slug (from list_products), with the same fields plus its product page's text: details, characteristics and every photo.
Inferred read-onlyCONNECT WITH APPROVAL
Client installation
Review this server and its permissions before adding it. Secret placeholders must be set locally.
Codex
~/.codex/config.toml
[mcp_servers.wignet-owner]
url = "https://app.wignet.app/mcp"
enabled = true
Claude Code
.mcp.json
{
"mcpServers": {
"wignet-owner": {
"type": "http",
"url": "https://app.wignet.app/mcp"
}
}
}
Claude Desktop
Settings → Connectors → Add custom connector
Name: wignet-owner
Remote MCP URL: https://app.wignet.app/mcp
Add this remote URL as a custom connector in Claude Desktop. Availability depends on the user plan and workspace policy.
Cursor
.cursor/mcp.json
{
"mcpServers": {
"wignet-owner": {
"url": "https://app.wignet.app/mcp"
}
}
}
Visual Studio Code
.vscode/mcp.json
Add to Visual Studio Code{
"servers": {
"wignet-owner": {
"type": "http",
"url": "https://app.wignet.app/mcp"
}
}
}
Generic MCP
Client-specific MCP configuration
{
"name": "wignet-owner",
"transport": "streamable-http",
"url": "https://app.wignet.app/mcp"
}
MCP Inspector
Run the official MCP Inspector locally and enter the indexed Streamable HTTP endpoint.
ENDPOINT 2
https://wignet.app/api/shop/mcp
MCP server metadata
- Name
- wignet-shop
- Version
- 1.0.0
Live catalogue of the Wignet frames sold on this site: prices (VAT and shipping included) and remaining stock, from the same table the shop page and payment read. Call list_products before quoting a price or saying what is left; never answer from memory. Ordering is done by the person on https://wignet.app/shop.html; you cannot place an order. Anything outside this batch (sizes, custom frames, lead times): contact@wignet.app. This server does not drive a display: that is the device's own link and connector.
Known tools 2
list_productsList the frames on sale with their live price and stock: slug, name, description, price (VAT and shipping included), units remaining, sold_out, photo, and the product page to link a person to.
Inferred read-onlyget_productOne frame by its slug (from list_products), with the same fields plus its product page's text: details, characteristics and every photo.
Inferred read-onlyCONNECT WITH APPROVAL
Client installation
Review this server and its permissions before adding it. Secret placeholders must be set locally.
Codex
~/.codex/config.toml
[mcp_servers.wignet-shop]
url = "https://wignet.app/api/shop/mcp"
enabled = true
Claude Code
.mcp.json
{
"mcpServers": {
"wignet-shop": {
"type": "http",
"url": "https://wignet.app/api/shop/mcp"
}
}
}
Claude Desktop
Settings → Connectors → Add custom connector
Name: wignet-shop
Remote MCP URL: https://wignet.app/api/shop/mcp
Add this remote URL as a custom connector in Claude Desktop. Availability depends on the user plan and workspace policy.
Cursor
.cursor/mcp.json
{
"mcpServers": {
"wignet-shop": {
"url": "https://wignet.app/api/shop/mcp"
}
}
}
Visual Studio Code
.vscode/mcp.json
Add to Visual Studio Code{
"servers": {
"wignet-shop": {
"type": "http",
"url": "https://wignet.app/api/shop/mcp"
}
}
}
Generic MCP
Client-specific MCP configuration
{
"name": "wignet-shop",
"transport": "streamable-http",
"url": "https://wignet.app/api/shop/mcp"
}
MCP Inspector
Run the official MCP Inspector locally and enter the indexed Streamable HTTP endpoint.
TRUST AND VERIFICATION EVIDENCE
Loading Trust v2 evidence…
Checking the associated registrable domain. The BuiltWith key remains server-side.
Evidence is source-attributed and does not guarantee that a third-party server is safe. Risk labels are conservative metadata heuristics.