addrbookFor publishers
← The evidence ledger

Evidence row 539279

Observed , by probe.mcp/1.

Kind
mcp.tools
About
endpoint 401e6763-79cd-4193-ad5d-22c5e31cec8c
Recorded
Previous row
None: the first of its kind about this subject
Body SHA-256
df236e595db0e6304a5d09d39977e944d849680d110af9dd4771e797c82fc7ea
Leaf
0x8236025a44c09967b6af76822eee7dd8e82da3a654cac6bf3c1a67fe0e148525

What was observed

{
  "count": 19,
  "tools": [
    {
      "description": "Take a channel off the air and out of every listing. This ARCHIVES rather than destroys: the handle stays reserved and assets and schedule history are retained, so it can be restored. Refuses with 409 while transcodes are still running. Idempotent. This is the reversible way to take a channel down; delete_asset removes individual videos instead.",
      "inputSchema": {
        "properties": {
          "channel_id": {
            "type": "integer"
          }
        },
        "required": [
          "channel_id"
        ],
        "type": "object"
      },
      "name": "archive_channel"
    },
    {
      "description": "Check whether a channel handle is free before trying to create it. The handle becomes the subdomain: {handle}.my-tv-channel.com. 3-63 chars, lowercase a-z, 0-9 and hyphens.",
      "inputSchema": {
        "properties": {
          "handle": {
            "description": "Desired handle, e.g. \"retro-arcade\"",
            "type": "string"
          }
        },
        "required": [
          "handle"
        ],
        "type": "object"
      },
      "name": "check_handle_available"
    },
    {
      "description": "Create a 24/7 linear TV channel. It will NOT be live yet — a channel goes live automatically once it has at least 4 ready assets AND at least 15 minutes of total content. is_public lists it in Discover and is available on every subscription tier, including Starter.",
      "inputSchema": {
        "properties": {
          "category": {
            "type": "string"
          },
          "channel_type": {
            "description": "Use \"thematic\" unless the channel is tied to a place",
            "enum": [
              "thematic",
              "location"
            ],
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "handle": {
            "description": "3-63 chars, lowercase a-z 0-9 and hyphens. Becomes {handle}.my-tv-channel.com",
            "type": "string"
          },
          "is_public": {
            "description": "List in Discover. Available on all tiers.",
            "type": "boolean"
          },
          "location": {
            "description": "Required only when channel_type is \"location\"",
            "properties": {
              "latitude": {
                "type": "number"
              },
              "longitude": {
                "type": "number"
              },
              "name": {
                "type": "string"
              },
              "radius_km": {
                "type": "number"
              }
            },
            "type": "object"
          },
          "name": {
            "description": "Display name",
            "type": "string"
          },
          "orientation": {
            "description": "vertical = 9:16",
            "enum": [
              "horizontal",
              "vertical"
            ],
            "type": "string"
          },
          "primary_language": {
            "description": "ISO 639-1, e.g. \"en\", \"fr\"",
            "type": "string"
          },
          "tags": {
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "handle",
          "name",
          "channel_type"
        ],
        "type": "object"
      },
      "name": "create_channel"
    },
    {
      "description": "Remove a video from a channel. Soft delete — it stops being scheduled immediately and the schedule regenerates automatically. Idempotent. The asset is retained and stops being scheduled; it is not erased. Affects one video — archive_channel takes a whole channel off the air.",
      "inputSchema": {
        "properties": {
          "asset_id": {
            "type": "integer"
          }
        },
        "required": [
          "asset_id"
        ],
        "type": "object"
      },
      "name": "delete_asset"
    },
    {
      "description": "Start here. Returns who the account is, its subscription tier and limits, how much weekly upload/stream quota is used and remaining, and every channel the owner has with its ready-asset count and what it still needs to go live (launchGaps). Call this before creating anything so you know the real limits for THIS account rather than assuming.",
      "inputSchema": {
        "properties": {},
        "required": [],
        "type": "object"
      },
      "name": "get_account_status"
    },
    {
      "description": "Get one channel by id. Includes scheduleStatus (inactive | pending | active | error) — poll this to confirm a channel has gone live — plus watchUrl, launchedAt and isArchived.",
      "inputSchema": {
        "properties": {
          "channel_id": {
            "description": "Channel id",
            "type": "integer"
          }
        },
        "required": [
          "channel_id"
        ],
        "type": "object"
      },
      "name": "get_channel"
    },
    {
      "description": "Read the channel's EPG — what is playing and what is coming up. Note this one returns a plain array of entries (unlike other tools, which return an object).",
      "inputSchema": {
        "properties": {
          "channel_id": {
            "type": "integer"
          }
        },
        "required": [
          "channel_id"
        ],
        "type": "object"
      },
      "name": "get_schedule"
    },
    {
      "description": "Read the channel's declarative schedule rules (fixed time slots and dayparts), plus its scheduling mode and timezone.",
      "inputSchema": {
        "properties": {
          "channel_id": {
            "type": "integer"
          }
        },
        "required": [
          "channel_id"
        ],
        "type": "object"
      },
      "name": "get_schedule_rules"
    },
    {
      "description": "Poll transcode progress. Give either channel_id (all its videos) or asset_id (one). Each asset reports uploadStatus (downloading -> pending -> transcoding -> ready) and the summary tells you when meetsLaunchRequirements becomes true: 4+ ready assets AND 900+ seconds. Poll every 30-60s; transcoding takes roughly real-time/4.",
      "inputSchema": {
        "properties": {
          "asset_id": {
            "type": "integer"
          },
          "channel_id": {
            "type": "integer"
          }
        },
        "required": [],
        "type": "object"
      },
      "name": "get_transcode_status"
    },
    {
      "description": "Add a video to a channel from a direct media URL. THIS IS THE MAIN WAY TO ADD CONTENT over MCP — you cannot upload local file bytes through this interface, so if the owner has local files, ask them to host them somewhere reachable or upload via the app. The URL must be a direct, public, unauthenticated link to mp4/mov/m4v/mpeg/mpg/avi, or a FINITE .m3u8 (VOD, not a live stream) — not a web page, not behind a login, not a YouTube/Vimeo watch page. The server downloads it. Returns immediately; the asset then goes downloading -> pending -> transcoding -> ready. Duration counts against the weekly upload quota. Re-submitting the same URL to the same channel returns the original asset instead of importing twice.",
      "inputSchema": {
        "properties": {
          "channel_id": {
            "type": "integer"
          },
          "tags": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "title": {
            "type": "string"
          },
          "url": {
            "description": "Direct, public media URL",
            "type": "string"
          },
          "weight": {
            "description": "How often it plays, 0-10 (default 5). Set it here rather than after — see set_asset_weight.",
            "maximum": 10,
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "channel_id",
          "url"
        ],
        "type": "object"
      },
      "name": "import_video_from_url"
    },
    {
      "description": "Import a YouTube video that the OWNER UPLOADED THEMSELVES. This will not work for anyone else's video, by design — a channel built from other people's videos is a copyright problem for the owner.\n\nOwnership is proved by a tag only the uploader can add:\n  1. The owner's tag looks like 'MyTVChannelApp#<device-id>'. When the import fails for a missing tag, the 403 error message contains that account's exact tag string.\n  2. They paste that exact string into the video's description or tags on YouTube.\n  3. Retry the import.\n\nYou cannot do step 2 for them and you cannot bypass it. Public finished videos only: no live streams, no private or age-restricted videos, no playlists or channel URLs. Capped at 10 per day. Counts against the same weekly upload quota as everything else.",
      "inputSchema": {
        "properties": {
          "channel_id": {
            "type": "integer"
          },
          "tags": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "title": {
            "description": "Overrides the YouTube title",
            "type": "string"
          },
          "url": {
            "description": "A single-video YouTube URL (watch, shorts or youtu.be)",
            "type": "string"
          },
          "weight": {
            "maximum": 10,
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "channel_id",
          "url"
        ],
        "type": "object"
      },
      "name": "import_youtube_video"
    },
    {
      "description": "List the videos on a channel.",
      "inputSchema": {
        "properties": {
          "channel_id": {
            "type": "integer"
          }
        },
        "required": [
          "channel_id"
        ],
        "type": "object"
      },
      "name": "list_assets"
    },
    {
      "description": "List the channels owned by this account.",
      "inputSchema": {
        "properties": {},
        "required": [],
        "type": "object"
      },
      "name": "list_channels"
    },
    {
      "description": "Rebuild the channel's schedule now using the current weights. Call this after changing weights on a channel that is ALREADY live, otherwise the change will not air until the hourly cron. Throttled to one call per channel per 5 minutes; exceeding that returns 429 with a Retry-After header giving the seconds remaining. Requires the channel to meet launch requirements.",
      "inputSchema": {
        "properties": {
          "channel_id": {
            "type": "integer"
          }
        },
        "required": [
          "channel_id"
        ],
        "type": "object"
      },
      "name": "regenerate_schedule"
    },
    {
      "description": "Re-queue a video whose transcode failed. Only works on assets in a failed state.",
      "inputSchema": {
        "properties": {
          "asset_id": {
            "type": "integer"
          }
        },
        "required": [
          "asset_id"
        ],
        "type": "object"
      },
      "name": "retry_transcode"
    },
    {
      "description": "Change how often a video plays (weight 0-10, default 5; 0 removes it from rotation entirely), and optionally its title or tags. IMPORTANT ORDERING: weights only affect what actually airs when the schedule is (re)generated. A channel builds its schedule the instant it crosses the launch threshold, so weights set AFTER that are stored but do not air. Either set the weight when you import each video, or call regenerate_schedule afterwards. Weights are relative: identical weights across every video produce a uniform rotation, and the spread between them is what shapes airtime.",
      "inputSchema": {
        "properties": {
          "asset_id": {
            "type": "integer"
          },
          "tags": {
            "description": "Tag videos seqXX01, seqXX02 … (XX = any two letters) to force them to play in order as a mini-series.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "title": {
            "type": "string"
          },
          "weight": {
            "maximum": 10,
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "asset_id"
        ],
        "type": "object"
      },
      "name": "set_asset_weight"
    },
    {
      "description": "Give the channel a durable schedule: fixed slots (\"news at 18:00\") and dayparts (\"no kids content after 22:00\"). The scheduler re-honours these on EVERY rebuild, so you set them once instead of babysitting the grid. **Pro tier or higher.**\n\nThis REPLACES the entire ruleset — send every rule you want, not just new ones. Sending an empty array removes all rules and returns the channel to plain weighted-random. Validate first with validate_schedule_rules.\n\nRule shapes:\n  time_slot      {rule_type:'time_slot', start_time:'18:00', end_time?:'21:00',\n                  days_mask:127, selector_type:'asset'|'tag'|'playlist',\n                  selector_value:<id|tag|[ids]>, priority?:0}\n  daypart_weight {rule_type:'daypart_weight', start_time:'22:00', end_time:'06:00',\n                  days_mask:127, selector_type:'asset'|'tag', selector_value:...,\n                  weight_multiplier:0-10}\n\ndays_mask is a bitmask: bit0=Mon … bit6=Sun. 127=daily, 31=Mon-Fri, 96=weekend.\nend_time on a time_slot makes it a BLOCK that keeps drawing from the selector until that time — that is how you get 'cartoons 06:00-09:00' rather than one cartoon.\nselector_type 'playlist' with an array of asset ids plays them IN ORDER.\nweight_multiplier 0 removes matching assets from that window entirely.\n\nSet `timezone` (IANA) or the times mean UTC, which is almost never what the owner meant. Slots start ON-OR-AFTER their time: the programme running into a slot is never cut short, so an 18:00 slot may begin at 18:02. That is intended.",
      "inputSchema": {
        "properties": {
          "channel_id": {
            "type": "integer"
          },
          "rules": {
            "description": "The COMPLETE ruleset. Empty array clears all rules.",
            "items": {
              "properties": {
                "days_mask": {
                  "maximum": 127,
                  "minimum": 0,
                  "type": "integer"
                },
                "end_time": {
                  "description": "Required for daypart_weight; on a time_slot makes it a block",
                  "type": "string"
                },
                "priority": {
                  "description": "Higher wins when slots overlap",
                  "type": "integer"
                },
                "rule_type": {
                  "enum": [
                    "time_slot",
                    "daypart_weight"
                  ],
                  "type": "string"
                },
                "selector_type": {
                  "enum": [
                    "asset",
                    "tag",
                    "playlist"
                  ],
                  "type": "string"
                },
                "selector_value": {
                  "description": "Asset id, tag name, or array of asset ids"
                },
                "start_time": {
                  "description": "HH:MM or HH:MM:SS, wall clock in the channel timezone",
                  "type": "string"
                },
                "weight_multiplier": {
                  "maximum": 10,
                  "minimum": 0,
                  "type": "number"
                }
              },
              "required": [
                "rule_type",
                "start_time",
                "selector_type",
                "selector_value"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "timezone": {
            "description": "IANA name, e.g. \"Europe/Paris\". Strongly recommended.",
            "type": "string"
          }
        },
        "required": [
          "channel_id",
          "rules"
        ],
        "type": "object"
      },
      "name": "set_schedule_rules"
    },
    {
      "description": "Update an existing channel: name, description, visibility, category, language, age rating, or the community chat link. Only send the fields you are changing.",
      "inputSchema": {
        "properties": {
          "age_classification": {
            "enum": [
              "4+",
              "9+",
              "13+",
              "16+",
              "18+"
            ],
            "type": "string"
          },
          "allow_offline_download": {
            "type": "boolean"
          },
          "category": {
            "type": "string"
          },
          "channel_id": {
            "type": "integer"
          },
          "chat_channel_id": {
            "description": "Discord channel id within that server",
            "type": "string"
          },
          "chat_platform": {
            "description": "Community chat platform shown as an overlay on the player. Discord is the fully supported one; the others are accepted but only Discord has a working embed today.",
            "enum": [
              "discord",
              "guilded",
              "matrix",
              "revolt",
              "kick",
              "restream"
            ],
            "type": "string"
          },
          "chat_server_id": {
            "description": "Discord server (guild) id — the owner must supply this; you cannot discover it",
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "is_public": {
            "description": "List in Discover. Allowed on every tier.",
            "type": "boolean"
          },
          "keywords": {
            "description": "Multilingual search keywords",
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "primary_language": {
            "description": "ISO 639-1, e.g. \"en\"",
            "type": "string"
          },
          "show_schedule": {
            "type": "boolean"
          }
        },
        "required": [
          "channel_id"
        ],
        "type": "object"
      },
      "name": "update_channel"
    },
    {
      "description": "DRY-RUN a ruleset. Saves nothing. Returns {valid, errors, warnings, preview} where preview is a simulated 24h grid of what would actually air. Intended as the dry run for set_schedule_rules: rules are wall-clock, slots start on-or-after their time, and dayparts reweight the random fill, so the airing result is hard to predict from the rules alone. Unlike set_schedule_rules this is not tier-gated and works on any tier. Same payload as set_schedule_rules.",
      "inputSchema": {
        "properties": {
          "channel_id": {
            "type": "integer"
          },
          "hours": {
            "description": "How many hours to simulate (default 24, max 168)",
            "type": "integer"
          },
          "rules": {
            "description": "Same shape as set_schedule_rules",
            "items": {
              "type": "object"
            },
            "type": "array"
          },
          "timezone": {
            "description": "IANA name, e.g. \"Europe/Paris\"",
            "type": "string"
          }
        },
        "required": [
          "channel_id",
          "rules"
        ],
        "type": "object"
      },
      "name": "validate_schedule_rules"
    }
  ]
}

What the leaf hashes

{"body":"df236e595db0e6304a5d09d39977e944d849680d110af9dd4771e797c82fc7ea","id":539279,"kind":"mcp.tools","method":"probe.mcp/1","observed_us":1793129565460081,"prev":null,"subject":"401e6763-79cd-4193-ad5d-22c5e31cec8c","subject_kind":"endpoint"}

Proof

Fold these into the leaf in order, hashing each sorted pair with keccak256, to reach the root of (273461 rows).

  1. 0x8236aa16ca5ceb5a34c23d538dc17101126ea2caece34d7d8ca065458993854e
  2. 0xb60225149b1713be832c579349da4a2eb25c072cffe01c909769b0dc01335d54
  3. 0x5d7f3ada3e270b8127fee1fd439c61e8d4c972e5a0512417d9ab2edc97421ddc
  4. 0xd665041b9323bace86fb9a0f730b0a1e7d1fb70c5503ad31a753d0605942319e
  5. 0xb59da49d4779b050fbafbada542f804fc19102ca9484835e3d002606fc0a640c
  6. 0x24777884ee093f973bfde6ad9432a6af0cdb7e3b87b8e4ab675f4bf8021b9d0d
  7. 0x0e3261838d401f3e7412cbde2f021ba0de88c5eefa3055f7a27b04ac7d9f3f41
  8. 0x3820eaf91524304443952752ccaeba12f787ae46eda374da48e21feba847a6a7
  9. 0x87955502b06eabbe569bfe0dd97c1b308c4a25ac3ddeb7e54e6d43a6a9b16bb9
  10. 0xa353e91f2ffc2fba2189ca04fea8b40a85257331c62b528369e8ba2322997237
  11. 0x164039927a75bda6275a106556896901626c20428ab1c29de73c4cd508bb0969
  12. 0x4cf7b6120bfa84e107b8f1b7be613b553fa250042dc0db95890566416a94d682
  13. 0xe38e66e8bf48306ee42504c4df50c2052cc9230af02e2ae6ff66da20232bf797
  14. 0xfa0c8e8f1a1710ff197533b0a28208f2e168afe71abb7bb3416e09d1ac371d60
  15. 0x3c500ec3d3edf0c74b87a6ca8fcd77656bfbe03db3d478bd0c184d0c88839c6b
  16. 0xfecf3d4646dd4984a13dd715499e842c3fde63692336d97394c2bfd8e877ca5d
  17. 0xf30fddbf4811226c58e8f0daf36fddd79fc5f1356b592bb1d99a8061ddbabe66
  18. 0x2bf8151e5f157dd183b9de6fa00469551932a7a6e3f33a694895000ac9061197
  19. 0x9fc354c0ea3efc3f1b6548bb77ea902a50f2c9647647ea61592efce2bd795699
Day root
0xdd77e5e99da32c3f154180d63e3c3e6fe11e896a2c6896412ef6b5c4bcf7e795
Chained
0x23bb4dfd09f55c15ac3962f53578e02c6114d5bfd9bb451cf8794fb6e2817ef4
Published
On Arc Testnet, block 69414147: 0xb2ebd83aafeb765a0ce66e76aefb133ed06606c98038fd56191e2bcd1dcb77b4

How to check it · This row as JSON