{"name":"agentView MCP","version":"2.0.315","protocolVersion":"2025-11-25","transport":{"streamableHttp":"https://agentview.de/mcp","protocol":"streamable-http","preferred":"streamableHttp"},"auth":{"type":"oauth2","protectedResourceMetadata":"https://agentview.de/.well-known/oauth-protected-resource/mcp","authorizationServerMetadata":"https://agentview.de/.well-known/oauth-authorization-server","publicTools":["create_auth_session","get_auth_session","authenticate","logout","get_public_status","search","fetch","get_pricing","search_public_apis","search_store_templates","list_store_categories","get_store_template_details"],"secureFlow":["Preferred: Use OAuth 2.1 Authorization Code with PKCE against /authorize and /token.","Modern /mcp transport requires a valid Bearer token on every protected HTTP request.","Compatibility auth tools are optional and mainly for clients that cannot complete OAuth or cannot reliably resend headers.","Open the returned loginUrl in a browser and let the user approve access.","Poll get_auth_session until status is active.","Use the returned token as Authorization: Bearer on every protected modern /mcp request."]},"tools":[{"name":"create_auth_session","title":"Create Auth Session","description":"Creates a browser-based login session and returns a loginUrl the user must open to authenticate. Use this as the first step when your client cannot complete OAuth 2.1 with PKCE itself. Do not use this if you already have a valid Bearer token. Returns sessionRequestId (needed for get_auth_session), loginUrl, pollUrl and expiresIn (seconds until the login window closes, default 600). After calling this, instruct the user to open the loginUrl, then poll get_auth_session until status becomes active.","inputSchema":{"type":"object","properties":{"agent_identifier":{"type":"string","description":"Optional display name of the MCP client or agent, shown to the user in the browser consent screen. Example: 'ChatGPT' or 'my-home-automation'."},"scope":{"type":"string","enum":["content_only","admin"],"description":"Requested access scope. Must be either 'content_only' (read and send content to displays) or 'admin' (content_only plus create/delete/rename displays). Defaults to 'content_only'."}}},"annotations":{"readOnlyHint":true,"idempotentHint":false,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"noauth"}],"_meta":{"securitySchemes":[{"type":"noauth"}]},"outputSchema":{"type":"object","properties":{"sessionRequestId":{"type":"string"},"requestedScope":{"type":"string"},"loginUrl":{"type":"string"},"expiresIn":{"type":"integer"},"pollUrl":{"type":"string"},"hint":{"type":"string"}}},"category":"auth"},{"name":"get_auth_session","title":"Get Auth Session","description":"Polls the status of a login session created by create_auth_session and returns the agent token once the user completes the browser login. Use this after create_auth_session; poll every 2-3 seconds until the status is no longer 'pending'. Do not use this for any other purpose. Returns one of three states: 'pending' (user has not logged in yet — keep polling), 'active' (login succeeded — response includes token as a raw JWT string and tokenExpiresAt as ISO 8601 timestamp), or 'expired' (login window or token timed out — call create_auth_session again). When status is active the current MCP session is automatically authenticated; you can call protected tools immediately.","inputSchema":{"type":"object","required":["session_request_id"],"properties":{"session_request_id":{"type":"string","description":"The sessionRequestId string returned by create_auth_session. Must be passed exactly as received."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"noauth"}],"_meta":{"securitySchemes":[{"type":"noauth"}]},"outputSchema":{"type":"object","properties":{"status":{"type":"string","enum":["pending","active","expired"]},"requestedScope":{"type":"string"},"expiresIn":{"type":"integer"},"scope":{"type":"string"},"token":{"type":"string"},"tokenExpiresAt":{"type":"string","format":"date-time"}}},"category":"auth"},{"name":"authenticate","title":"Authenticate Session","description":"Validates a JWT agent token and caches the resulting identity on the current MCP session so that subsequent protected tool calls succeed without resending the token. Use this only if your client cannot reliably send an Authorization: Bearer header on every request; modern streamable HTTP clients should send the header instead. Do not call this if the session was already auto-authenticated by get_auth_session. Returns authenticated (boolean), sessionBound (whether the identity was cached on this session), userId, name, email, scope and expiresAt (ISO 8601).","inputSchema":{"type":"object","properties":{"token":{"type":"string","description":"The raw JWT token string returned by get_auth_session or an OAuth access token. Pass the opaque token exactly as received — do not add a 'Bearer ' prefix and do not expand or decode the JWT claims."},"jwt":{"type":"string","description":"Alias for token. Use this if your wrapper cannot send the 'token' field reliably."},"access_token":{"type":"string","description":"Alias for token. Use this if your wrapper follows OAuth naming conventions."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"noauth"}],"_meta":{"securitySchemes":[{"type":"noauth"}]},"outputSchema":{"type":"object","properties":{"authenticated":{"type":"boolean"},"sessionBound":{"type":"boolean"},"transportAuthRequired":{"type":"boolean"},"userId":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"isAgent":{"type":"boolean"},"scope":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}}},"category":"auth"},{"name":"logout","title":"Logout","description":"Clears the cached authentication identity from the current MCP session. Use this when the user wants to end the session or switch accounts. This does not revoke the underlying JWT token — it only removes the session-local cache. After logout, protected tools will require re-authentication. Returns loggedOut (boolean) and sessionBound (boolean).","inputSchema":{"type":"object","properties":{}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"noauth"}],"_meta":{"securitySchemes":[{"type":"noauth"}]},"outputSchema":{"type":"object","properties":{"loggedOut":{"type":"boolean"},"sessionBound":{"type":"boolean"},"transportAuthRequired":{"type":"boolean"}}},"category":"auth"},{"name":"get_public_status","title":"Get Public Status","description":"Returns the server's public readiness status, version string and discovery URLs. Use this before authenticating to verify the server is reachable and to obtain entry-point URLs. No authentication required. Returns status ('ready'), server name, version, statusUrl and instructionsUrl.","inputSchema":{"type":"object","properties":{}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":true},"securitySchemes":[{"type":"noauth"}],"_meta":{"securitySchemes":[{"type":"noauth"}]},"outputSchema":{"type":"object","properties":{"status":{"type":"string"},"server":{"type":"string"},"version":{"type":"string"},"statusUrl":{"type":"string"},"instructionsUrl":{"type":"string"}}},"category":"discovery"},{"name":"search","title":"Search Resources","description":"Searches agentView resources by keyword and returns a ranked list of matching resource URIs with titles and snippets. Use this to discover resources before calling fetch for full details. Do not use this if you already know the exact resource URI — call fetch directly instead. Without authentication only public documentation resources are searched; with authentication your account and accessible displays are included. Returns query, resourceType, count and a results array where each entry has uri, type, title, snippet and requiresAuthentication.","inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"Free-text search terms. Examples: a display name, 'account', 'OAuth', 'status'. At least one of query or resource_type should be provided."},"resource_type":{"type":"string","enum":["all","documentation","status","account","display","api"],"description":"Restricts results to a specific resource category. Must be one of: 'all', 'documentation', 'status', 'account', 'display', 'api'. Defaults to 'all' when omitted."},"limit":{"type":"integer","minimum":1,"maximum":20,"description":"Maximum number of results to return. Integer between 1 and 20 inclusive. Defaults to 5."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":true},"securitySchemes":[{"type":"noauth"},{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"noauth"},{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"query":{"type":"string"},"resourceType":{"type":"string"},"count":{"type":"integer"},"results":{"type":"array","items":{"type":"object","properties":{"uri":{"type":"string"},"type":{"type":"string"},"title":{"type":"string"},"snippet":{"type":"string"},"requiresAuthentication":{"type":"boolean"}}}}}},"category":"discovery"},{"name":"fetch","title":"Fetch Resource","description":"Retrieves the full details of a single agentView resource identified by its URI. Use this after search to read the complete content of a discovered resource, or directly when you already know the URI. Public URIs (e.g. agentview://public/status, agentview://public/instructions) require no authentication; private URIs (e.g. agentview://account/me, agentview://display/{id}) require a valid session. Returns uri, type, title, text (human-readable content) and data (structured details).","inputSchema":{"type":"object","required":["uri"],"properties":{"uri":{"type":"string","description":"The resource URI to fetch. Must use the agentview:// scheme. Examples: 'agentview://public/status', 'agentview://account/me', 'agentview://display/ABCD1234'."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":true},"securitySchemes":[{"type":"noauth"},{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"noauth"},{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"uri":{"type":"string"},"type":{"type":"string"},"title":{"type":"string"},"text":{"type":"string"},"data":{"type":"object"}}},"category":"discovery"},{"name":"get_pricing","title":"Get Pricing","description":"Returns agentView plan pricing, features and upgrade options. Use this when the user asks about pricing, costs, plan differences or what an additional display costs. No authentication required. Returns an array of plans with name, price, included displays and features, plus the per-display add-on price and a link to the pricing page.","inputSchema":{"type":"object","properties":{}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":true},"securitySchemes":[{"type":"noauth"}],"_meta":{"securitySchemes":[{"type":"noauth"}]},"outputSchema":{"type":"object","properties":{"plans":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"price":{"type":"string"},"monthlyPrice":{"type":"number"},"displays":{"type":"integer"},"features":{"type":"array","items":{"type":"string"}}}}},"extraDisplayPrice":{"type":"string"},"extraDisplayMonthlyPrice":{"type":"number"},"pricingUrl":{"type":"string"},"currency":{"type":"string"}}},"category":"discovery"},{"name":"search_store_templates","title":"Search Store Templates","description":"Searches the agentView public template store for ready-made display designs (e.g. 'Zahnarzt-Wartezimmer', 'Bistro warm', 'Empfang'). Each template is a polished HTML design a user can push to one of their Türschild / digital-signage displays. Use this when the user describes a use case and wants to pick a pre-built design instead of having you generate raw HTML. Returns total, offset, limit, language and a templates array with slug, title, description, category, optional suite (design family), tags, theme, designStyle, placement, previewImageUrl, detailPath, previewPath, featured and publishedAt. No authentication required.","inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"Free-text search over template title, description and tags. Examples: 'Zahnarzt', 'italienisches Bistro', 'conference room'."},"category":{"type":"string","description":"Optional category slug to restrict the search (English kebab-case, e.g. 'gastronomie', 'waiting-room')."},"suite":{"type":"string","description":"Optional design-family suite slug (e.g. 'bistro-warm', 'sushi-minimal')."},"language":{"type":"string","enum":["de","en"],"description":"Preferred content language. Defaults to 'en'."},"limit":{"type":"integer","minimum":1,"maximum":50,"description":"Maximum number of templates to return. Defaults to 10."},"offset":{"type":"integer","minimum":0,"description":"Offset into the filtered result set for pagination. Defaults to 0."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"noauth"}],"_meta":{"securitySchemes":[{"type":"noauth"}],"openai/outputTemplate":"ui://widget/agentview-store-gallery","openai/toolInvocation/invoking":"Searching the agentView template store…","openai/toolInvocation/invoked":"agentView Templates"},"outputSchema":{"type":"object","properties":{"total":{"type":"integer"},"offset":{"type":"integer"},"limit":{"type":"integer"},"language":{"type":"string"},"templates":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"category":{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"}}},"suite":{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"}}},"tags":{"type":"array","items":{"type":"string"}},"theme":{"type":"string"},"designStyle":{"type":"string"},"placement":{"type":"string"},"previewImageUrl":{"type":"string"},"detailPath":{"type":"string"},"previewPath":{"type":"string"},"featured":{"type":"boolean"},"publishedAt":{"type":"string","format":"date-time"}}}}}},"category":"store"},{"name":"list_store_categories","title":"List Store Categories","description":"Lists all published agentView store categories (e.g. Gastronomie, Wartezimmer, Empfang, Smart Home) with localized titles, descriptions and template counts. Use this to narrow a subsequent search_store_templates call when the user asks for 'templates for a waiting room' or similar. No authentication required. Returns count, language and a categories array where each entry has slug, title, description, templateCount, heroIconKey and detailPath.","inputSchema":{"type":"object","properties":{"language":{"type":"string","enum":["de","en"],"description":"Preferred content language. Defaults to 'en'."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"noauth"}],"_meta":{"securitySchemes":[{"type":"noauth"}]},"outputSchema":{"type":"object","properties":{"count":{"type":"integer"},"language":{"type":"string"},"categories":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"templateCount":{"type":"integer"},"heroIconKey":{"type":"string"},"detailPath":{"type":"string"}}}}}},"category":"store"},{"name":"get_store_template_details","title":"Get Store Template Details","description":"Returns the full public details of a single store template: localized title, short description, long-form markdown (intro, use cases, audience, setup), category, optional suite (design family), tags, theme, designStyle, placement, features list, preview image URL and store detail path. Use this after search_store_templates picks a candidate so you can explain the template to the user before offering to send it to one of their displays. No authentication required.","inputSchema":{"type":"object","required":["slug"],"properties":{"slug":{"type":"string","description":"The template slug (English kebab-case) returned by search_store_templates, e.g. 'bistro-warm-door'."},"language":{"type":"string","enum":["de","en"],"description":"Preferred content language. Defaults to 'en'."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"noauth"}],"_meta":{"securitySchemes":[{"type":"noauth"}],"openai/outputTemplate":"ui://widget/agentview-store-detail","openai/toolInvocation/invoking":"Loading template details…","openai/toolInvocation/invoked":"agentView Template"},"outputSchema":{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"introMarkdown":{"type":"string"},"useCasesMarkdown":{"type":"string"},"audienceMarkdown":{"type":"string"},"setupMarkdown":{"type":"string"},"category":{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"}}},"categoryDescription":{"type":"string"},"suite":{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"}}},"suiteDescription":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"theme":{"type":"string"},"designStyle":{"type":"string"},"features":{"type":"array","items":{"type":"string"}},"placement":{"type":"string"},"previewImageUrl":{"type":"string"},"detailPath":{"type":"string"},"previewPath":{"type":"string"},"featured":{"type":"boolean"},"publishedAt":{"type":"string","format":"date-time"},"fileName":{"type":"string"},"sourceKind":{"type":"string"}}},"category":"store"},{"name":"get_store_template_install_options","title":"Get Store Template Install Options","description":"Returns the displays the authenticated user can send a given store template to, plus the data slots the template needs. Call this before send_store_template_to_display so you can show the user which Türschild they can target and know which per-slot JSON the template consumes. Requires authentication with at least content_only scope. API-key callers scoped to a display whitelist only see their scoped displays. When no displays come back, tell the user they first need to create/claim a display (create_display / pair_by_code) before installing store content.","inputSchema":{"type":"object","required":["slug"],"properties":{"slug":{"type":"string","description":"Template slug returned by search_store_templates, e.g. 'bistro-warm-door'."},"language":{"type":"string","enum":["de","en"],"description":"Preferred UI language for labels. Defaults to 'en'."},"access_token":{"type":"string","description":"Optional JWT access token."},"session_request_id":{"type":"string","description":"Optional session request ID from create_auth_session. Preferred over access_token."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"templateSlug":{"type":"string"},"language":{"type":"string"},"displays":{"type":"array","items":{"type":"object","properties":{"displayId":{"type":"string"},"name":{"type":"string"},"scope":{"type":"string","enum":["personal","group"]},"groupId":{"type":"string"},"isLocked":{"type":"boolean"}}}},"requiredDataSlots":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"type":{"type":"string","enum":["value","aggregate"]},"placeholderName":{"type":"string"},"required":{"type":"boolean"}}}}}},"category":"store"},{"name":"send_store_template_to_display","title":"Send Store Template to Display","description":"Installs a published store template onto one of the authenticated user's displays. The server materializes the template HTML, auto-creates any required data slots (reusing existing slots from a prior install when possible) and publishes the result so the Türschild updates within seconds. Optional data_slot_overrides bake per-slot JSON directly into the install so a 'show my daily menu' flow does not need a second set_data_slot call. Requires authentication with at least content_only scope, control access to the target display, and (for API-key callers) the display.send capability. Errors: 'template_not_found', 'display_not_found', 'access_denied', 'slot_install_failed', 'storage_quota_exceeded', 'invalid_slot_override', 'publish_failed'. Always call get_store_template_install_options first to know which slots the template needs.","inputSchema":{"type":"object","required":["slug","display_id"],"properties":{"slug":{"type":"string","description":"Template slug to install, e.g. 'bistro-warm-door'. Must be a currently published template."},"display_id":{"type":"string","description":"Display profile ID (8-char alphanumeric) from list_displays or get_store_template_install_options."},"data_slot_overrides":{"type":"object","description":"Optional { key: value } map keyed by data-slot key (see requiredDataSlots). Each value is JSON payload to install into that slot — either a string of raw JSON or an inline object/array. Unknown keys are silently dropped; malformed JSON fails with invalid_slot_override. Per-slot payload capped at 64 KiB, max 64 overrides per call.","additionalProperties":true},"idempotency_key":{"type":"string","maxLength":128,"description":"Optional opaque key (max 128 chars) to make this install retry-safe. If a previous successful install for the same (user, display, idempotency_key) tuple exists within 24 hours, the cached result is returned without re-publishing. Use this when an MCP client may retry the call after a network timeout (e.g. ChatGPT and other LLM hosts retry tool calls automatically) so the user doesn't see the display flicker through two near-identical installs. Recommended format: a UUID generated client-side per user request."},"access_token":{"type":"string","description":"Optional JWT access token."},"session_request_id":{"type":"string","description":"Optional session request ID from create_auth_session. Preferred over access_token."}}},"annotations":{"readOnlyHint":false,"idempotentHint":true,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"openai/outputTemplate":"ui://widget/agentview-store-install-result","openai/toolInvocation/invoking":"Sending template to display…","openai/toolInvocation/invoked":"Template installed"},"outputSchema":{"type":"object","properties":{"templateSlug":{"type":"string"},"versionId":{"type":"string"},"displayId":{"type":"string"},"fileName":{"type":"string"},"contentVersionId":{"type":"string"},"overrideCount":{"type":"integer"},"installedSlots":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"placeholderName":{"type":"string"},"slug":{"type":"string"},"readUrl":{"type":"string"},"groupId":{"type":"string"},"type":{"type":"string"}}}}}},"category":"store"},{"name":"search_public_apis","title":"Search Public APIs","description":"Searches a curated catalog of 600+ free, public APIs that require no authentication and work over HTTPS — ideal for embedding live data in display HTML pages via fetch(). Covers 47 categories including weather, news, finance, sports, images, food, entertainment, science, geocoding and more. Use this when generating HTML that needs live data from the internet. Returns matching APIs with documentation links, CORS support info and ready-to-use fetch() code hints. No authentication required.","inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"Free-text search terms. Examples: 'weather forecast', 'random quotes', 'cat pictures', 'bitcoin price', 'jokes'."},"category":{"type":"string","description":"Filter by category ID. Examples: 'weather', 'finance', 'animals', 'food-drink', 'sports-fitness', 'news', 'entertainment'. Use 'all' or omit for all categories."},"cors_only":{"type":"boolean","description":"When true, only return APIs with confirmed CORS support (safe for browser-side fetch in HTML). Defaults to false."},"limit":{"type":"integer","minimum":1,"maximum":20,"description":"Maximum results to return, 1-20. Defaults to 10."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":true},"securitySchemes":[{"type":"noauth"}],"_meta":{"securitySchemes":[{"type":"noauth"}]},"outputSchema":{"type":"object","properties":{"query":{"type":"string"},"category":{"type":"string"},"corsOnly":{"type":"boolean"},"totalCatalogApis":{"type":"integer"},"count":{"type":"integer"},"results":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"category":{"type":"string"},"cors":{"type":"string"},"link":{"type":"string"},"htmlEmbeddingHint":{"type":"string"},"fetchUri":{"type":"string"}}}}}},"category":"discovery"},{"name":"get_account","title":"Get Account","description":"Returns the authenticated user's account profile including userId, name, email, plan with feature details, personal display limits (maxPersonalDisplays, currentPersonalDisplays, remainingPersonalDisplays), total accessible displays across all organizations, organization memberships summary and points balance. Use this to answer questions about the user's subscription, display quota, organization memberships or plan capabilities. Requires authentication with at least content_only scope. Do not use this to list displays — use list_displays instead.","inputSchema":{"type":"object","properties":{"access_token":{"type":"string","description":"Optional JWT access token for authentication. Pass the token returned by get_auth_session when your MCP client does not send it as an Authorization: Bearer HTTP header automatically."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"plan":{"type":"string"},"planFeatures":{"type":"array","items":{"type":"string"}},"maxPersonalDisplays":{"type":"integer"},"currentPersonalDisplays":{"type":"integer"},"remainingPersonalDisplays":{"type":"integer"},"totalAccessibleDisplays":{"type":"integer"},"organizations":{"type":"array","items":{"type":"object","properties":{"orgId":{"type":"string"},"name":{"type":"string"},"role":{"type":"string"},"displayCount":{"type":"integer"}}}},"organizationCount":{"type":"integer"},"maxDisplays":{"type":"integer"},"currentDisplays":{"type":"integer"},"remainingDisplays":{"type":"integer"},"points":{"type":"integer"},"authenticatedVia":{"type":"string"},"hint":{"type":"string"}}},"category":"account"},{"name":"list_displays","title":"List Displays","description":"Returns all displays accessible to the authenticated user as an array with count and display details. Use this to discover available display IDs before reading or modifying a specific display with get_display or send_html. Requires authentication with at least content_only scope; admin is not required. Each display entry includes id (8-character alphanumeric profile ID), name, status, locked, displayUrl, setupUrl, pairingUrl and other management links plus a compact runtime summary such as screen resolution, touch support, deviceClass and deviceFamily when known. Do not use this to get full details of one display — use get_display with the display_id instead.","inputSchema":{"type":"object","properties":{"access_token":{"type":"string","description":"Optional JWT access token for authentication. Pass the token returned by get_auth_session when your MCP client does not send it as an Authorization: Bearer HTTP header automatically."},"session_request_id":{"type":"string","description":"Optional session request ID returned by create_auth_session. Pass this instead of access_token for simpler, more reliable authentication — the server resolves the identity server-side."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"count":{"type":"integer"},"displays":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"locked":{"type":"boolean"},"displayUrl":{"type":"string"},"approvalUrl":{"type":"string"},"setupUrl":{"type":"string"},"managedUrl":{"type":"string"},"pairingUrl":{"type":"string"},"pairingExpiresAt":{"type":"string"},"hasDefaultContent":{"type":"boolean"},"orgId":{"type":"string"},"preferredLanguage":{"type":"string"},"effectiveLanguage":{"type":"string"},"resolution":{"type":"string"},"screen":{"type":"object"},"viewport":{"type":"object"},"classification":{"type":"object"},"hasTouch":{"type":"boolean"},"deviceClass":{"type":"string"},"deviceFamily":{"type":"string"}}}}}},"category":"displays"},{"name":"list_organizations","title":"List Organizations","description":"Returns all organizations the authenticated user belongs to with their role, display count, member count and allocated slots. Use this to answer questions about the user's organizations, how many displays an organization has, or team membership. Requires authentication with at least content_only scope.","inputSchema":{"type":"object","properties":{"access_token":{"type":"string","description":"Optional JWT access token for authentication. Pass the token returned by get_auth_session when your MCP client does not send it as an Authorization: Bearer HTTP header automatically."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"count":{"type":"integer"},"organizations":{"type":"array","items":{"type":"object","properties":{"orgId":{"type":"string"},"name":{"type":"string"},"role":{"type":"string"},"displayCount":{"type":"integer"},"memberCount":{"type":"integer"},"allocatedSlots":{"type":"integer"},"plan":{"type":"string"},"isActive":{"type":"boolean"}}}}}},"category":"orgs"},{"name":"get_organization","title":"Get Organization","description":"Returns full details of a specific organization including its displays, members with roles, allocated slots and remaining capacity. Use this after list_organizations to inspect a specific organization's state. Requires authentication with at least content_only scope and the user must be a member of the organization.","inputSchema":{"type":"object","required":["org_id"],"properties":{"org_id":{"type":"string","description":"The organization ID. Obtain this from list_organizations or from get_account."},"access_token":{"type":"string","description":"Optional JWT access token for authentication. Pass the token returned by get_auth_session when your MCP client does not send it as an Authorization: Bearer HTTP header automatically."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"orgId":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"contactEmail":{"type":"string"},"plan":{"type":"string"},"isActive":{"type":"boolean"},"yourRole":{"type":"string"},"displayCount":{"type":"integer"},"allocatedSlots":{"type":"integer"},"remainingSlots":{"type":"integer"},"memberCount":{"type":"integer"},"members":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"role":{"type":"string"},"allocatedDisplays":{"type":"integer"}}}},"displays":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"locked":{"type":"boolean"}}}},"createdAt":{"type":"string"}}},"category":"orgs"},{"name":"invite_member","title":"Invite Member","description":"Creates an invite link to add a new member to an organization. The invite is valid for 7 days. Optionally bind it to a specific email address so only that person can accept it. Requires admin scope and the user must be an admin or owner of the organization. Returns the inviteUrl to share with the invitee.","inputSchema":{"type":"object","required":["org_id","role"],"properties":{"org_id":{"type":"string","description":"The organization ID to invite a member to. Obtain this from list_organizations."},"role":{"type":"string","enum":["admin","manager","viewer"],"description":"The role for the invited member. Must be one of: 'admin' (manage members and displays), 'manager' (manage displays and content), 'viewer' (read-only dashboard access)."},"email":{"type":"string","description":"Optional email address to bind the invite to. If set, only this email address can accept the invite."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"inviteToken":{"type":"string"},"inviteUrl":{"type":"string"},"orgId":{"type":"string"},"orgName":{"type":"string"},"role":{"type":"string"},"inviteeEmail":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}}},"category":"orgs"},{"name":"get_billing_url","title":"Get Billing URL","description":"Returns a URL to the user's billing and subscription page where they can purchase or manage premium display licenses. Use this when the user wants to buy more licenses, upgrade their plan, or manage their subscription. The agent should present the URL to the user and offer to allocate and assign the new licenses once the purchase is complete. Requires content_only scope.","inputSchema":{"type":"object","properties":{"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"billingUrl":{"type":"string"},"currentPremiumLicenses":{"type":"integer"},"freeLicenses":{"type":"integer"},"plan":{"type":"string"}}},"category":"account"},{"name":"allocate_licenses","title":"Allocate Licenses","description":"Allocates premium display licenses from the authenticated user's Premium plan to an organization. Premium users have a pool of allocatable licenses (base + purchased extras) that can be distributed across organizations. Requires admin scope and a Premium plan.","inputSchema":{"type":"object","required":["org_id","licenses"],"properties":{"org_id":{"type":"string","description":"The organization ID to allocate licenses to. Obtain this from list_organizations."},"licenses":{"type":"integer","minimum":0,"description":"Number of premium display licenses to allocate to this organization. Set to 0 to deallocate all licenses from this org."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"orgId":{"type":"string"},"allocatedToOrg":{"type":"integer"},"freeAllocatableLicenses":{"type":"integer"},"totalAllocatableLicenses":{"type":"integer"},"personalDisplayLimit":{"type":"integer"}}},"category":"orgs"},{"name":"create_organization","title":"Create Organization","description":"Creates a new organization and makes the authenticated user the owner. Use this when the user wants to set up a shared display fleet. Returns orgId, name, slug, type and yourRole. Requires admin scope.","inputSchema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Friendly name for the organization. Example: 'Marketing Team'."},"type":{"type":"string","enum":["organization","family"],"description":"Organization type. Defaults to 'organization' if omitted."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"orgId":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"type":{"type":"string"},"yourRole":{"type":"string"}}},"category":"orgs"},{"name":"rename_organization","title":"Rename Organization","description":"Renames an existing organization. Requires admin scope and admin or owner role in the organization.","inputSchema":{"type":"object","required":["org_id","name"],"properties":{"org_id":{"type":"string","description":"The organization ID to rename."},"name":{"type":"string","description":"The new name for the organization."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"orgId":{"type":"string"},"name":{"type":"string"}}},"category":"orgs"},{"name":"delete_organization","title":"Delete Organization","description":"Permanently deletes an organization, releasing all its displays and removing all members. Only the owner can delete. This cannot be undone. Requires admin scope.","inputSchema":{"type":"object","required":["org_id"],"properties":{"org_id":{"type":"string","description":"The organization ID to delete."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"orgId":{"type":"string"},"name":{"type":"string"},"deleted":{"type":"boolean"},"displaysReleased":{"type":"integer"},"membersRemoved":{"type":"integer"}}},"category":"orgs"},{"name":"update_member_role","title":"Update Member Role","description":"Changes a member's role within an organization. Cannot change your own role or the owner's role. Requires admin scope and admin or owner role.","inputSchema":{"type":"object","required":["org_id","target_user_id","role"],"properties":{"org_id":{"type":"string","description":"The organization ID."},"target_user_id":{"type":"string","description":"The user ID of the member whose role to change."},"role":{"type":"string","description":"The new role. Valid roles depend on organization type (e.g. 'admin', 'manager', 'viewer')."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"orgId":{"type":"string"},"targetUserId":{"type":"string"},"previousRole":{"type":"string"},"newRole":{"type":"string"}}},"category":"orgs"},{"name":"remove_member","title":"Remove Member","description":"Removes a member from an organization. Transfers their owned displays to a successor, unassigns their license allocations, and removes their display grants. Cannot remove the last owner. Requires admin scope and admin or owner role.","inputSchema":{"type":"object","required":["org_id","target_user_id"],"properties":{"org_id":{"type":"string","description":"The organization ID."},"target_user_id":{"type":"string","description":"The user ID of the member to remove."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"orgId":{"type":"string"},"targetUserId":{"type":"string"},"removed":{"type":"boolean"},"displaysTransferred":{"type":"integer"}}},"category":"orgs"},{"name":"list_org_displays","title":"List Organization Displays","description":"Returns all displays in an organization with their real-time connection status, online/offline state, and license info. Use this for fleet monitoring. Requires content_only scope and organization membership.","inputSchema":{"type":"object","required":["org_id"],"properties":{"org_id":{"type":"string","description":"The organization ID."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"orgId":{"type":"string"},"orgName":{"type":"string"},"totalDisplays":{"type":"integer"},"onlineDisplays":{"type":"integer"},"displays":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"isOnline":{"type":"boolean"},"isPremiumAssigned":{"type":"boolean"},"isLocked":{"type":"boolean"}}}}}},"category":"orgs"},{"name":"get_license_info","title":"Get License Info","description":"Returns the authenticated user's complete license allocation overview: total premium licenses, personal usage, allocatable licenses, per-organization allocations, and free licenses. Use this to understand available capacity before allocating licenses. Requires content_only scope.","inputSchema":{"type":"object","properties":{"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"totalPremiumLicenses":{"type":"integer"},"personalDisplays":{"type":"integer"},"personalPremiumDisplays":{"type":"integer"},"allocatableLicenses":{"type":"integer"},"totalAllocatedToOrgs":{"type":"integer"},"freeAllocatableLicenses":{"type":"integer"},"canAllocate":{"type":"boolean"},"orgAllocations":{"type":"array","items":{"type":"object","properties":{"orgId":{"type":"string"},"name":{"type":"string"},"allocatedLicenses":{"type":"integer"},"usedDisplays":{"type":"integer"},"premiumDisplays":{"type":"integer"}}}}}},"category":"account"},{"name":"remove_display_from_org","title":"Remove Display from Organization","description":"Removes a display from an organization, clearing its group assignment and all display grants. The display becomes unassigned. Requires admin scope and admin or owner role.","inputSchema":{"type":"object","required":["org_id","display_id"],"properties":{"org_id":{"type":"string","description":"The organization ID."},"display_id":{"type":"string","description":"The display profile ID to remove."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"displayId":{"type":"string"},"previousOrgId":{"type":"string"},"removed":{"type":"boolean"}}},"category":"orgs"},{"name":"set_display_grant","title":"Set Display Grant","description":"Grants a specific user access to a specific display within an organization. Creates or updates the grant. The target user must be a member of the organization. Access levels: 'view' (see status) or 'control' (send content). Requires admin scope.","inputSchema":{"type":"object","required":["org_id","display_id","target_user_id","access_level"],"properties":{"org_id":{"type":"string","description":"The organization ID."},"display_id":{"type":"string","description":"The display profile ID."},"target_user_id":{"type":"string","description":"The user ID to grant access to."},"access_level":{"type":"string","enum":["view","control"],"description":"Access level: 'view' or 'control'."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"displayId":{"type":"string"},"targetUserId":{"type":"string"},"accessLevel":{"type":"string"},"granted":{"type":"boolean"}}},"category":"orgs"},{"name":"remove_display_grant","title":"Remove Display Grant","description":"Removes a user's access grant from a display within an organization. Requires admin scope and admin or owner role.","inputSchema":{"type":"object","required":["org_id","display_id","target_user_id"],"properties":{"org_id":{"type":"string","description":"The organization ID."},"display_id":{"type":"string","description":"The display profile ID."},"target_user_id":{"type":"string","description":"The user ID whose grant to remove."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"displayId":{"type":"string"},"targetUserId":{"type":"string"},"removed":{"type":"boolean"}}},"category":"orgs"},{"name":"broadcast_content","title":"Broadcast Content","description":"Sends HTML content to multiple displays at once. Provide display_ids to target specific displays or set all to true to target all accessible displays. Locked displays are skipped. Returns sent and skipped lists with reasons. Requires content_only scope.","inputSchema":{"type":"object","required":["description"],"properties":{"description":{"type":"string","description":"Short description of the content being sent."},"html":{"type":"string","description":"Complete HTML document to render. Mutually exclusive with base64_html."},"base64_html":{"type":"string","description":"Base64-encoded HTML string. Mutually exclusive with html."},"display_ids":{"type":"array","items":{"type":"string"},"description":"Array of display profile IDs to target. Provide this or set all to true."},"all":{"type":"boolean","description":"Set to true to target all accessible displays."},"duration":{"type":"integer","description":"How long content stays in seconds. 0 = indefinite."},"content_description":{"type":"string","description":"Optional semantic description of the content."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."},"session_request_id":{"type":"string","description":"Optional session request ID."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"fileName":{"type":"string"},"duration":{"type":"integer"},"sentCount":{"type":"integer"},"sent":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}}},"skippedCount":{"type":"integer"},"skipped":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"reason":{"type":"string"}}}}}},"category":"content"},{"name":"create_org_display","title":"Create Organization Display","description":"Creates a new display directly within an organization WITHOUT pairing it to physical hardware. The display starts offline and uncoupled. For physical screens, ALWAYS prefer pair_by_code instead — it creates and pairs in one step. Use create_org_display only for administrative pre-provisioning when the screen is not yet available. The display is owned by the organization, not by a personal user. Requires admin scope and manager or higher role in the organization. The organization must have available licenses (use allocate_licenses first if needed).","inputSchema":{"type":"object","required":["org_id","name"],"properties":{"org_id":{"type":"string","description":"The organization ID to create the display in. Obtain this from list_organizations."},"name":{"type":"string","description":"Friendly name for the new display. Example: 'Lobby Screen'."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"orgId":{"type":"string"},"orgName":{"type":"string"},"displayUrl":{"type":"string"},"setupUrl":{"type":"string"},"pairingUrl":{"type":"string"},"pairingExpiresAt":{"type":"string"},"status":{"type":"string"}}},"category":"orgs"},{"name":"get_display","title":"Get Display","description":"Returns the full details of a single display including its live state, current content, pairing links, screen and viewport facts, touch capability, runtime classification, hardware/UI settings, and the latest reported browser/runtime facts. Use this when you already know the display ID and need its complete state before sending content or managing it. Do not use this to discover displays — use list_displays first. Requires authentication with at least content_only scope.","inputSchema":{"type":"object","required":["display_id"],"properties":{"display_id":{"type":"string","description":"The 8-character alphanumeric display profile ID, e.g. 'ABCD1234'. Obtain this from list_displays or from a previous create_display call."},"access_token":{"type":"string","description":"Optional JWT access token for authentication. Pass the token returned by get_auth_session when your MCP client does not send it as an Authorization: Bearer HTTP header automatically."},"session_request_id":{"type":"string","description":"Optional session request ID returned by create_auth_session. Pass this instead of access_token for simpler, more reliable authentication — the server resolves the identity server-side."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"locked":{"type":"boolean"},"displayUrl":{"type":"string"},"approvalUrl":{"type":"string"},"setupUrl":{"type":"string"},"managedUrl":{"type":"string"},"pairingUrl":{"type":"string"},"pairingExpiresAt":{"type":"string"},"hasDefaultContent":{"type":"boolean"},"lastSeen":{"type":"string"},"resolution":{"type":"object"},"screen":{"type":"object"},"viewport":{"type":"object"},"classification":{"type":"object"},"hasTouch":{"type":"boolean"},"browser":{"type":"string"},"engine":{"type":"string"},"platform":{"type":"string"},"deviceClass":{"type":"string"},"deviceFamily":{"type":"string"},"screenSource":{"type":"string"},"viewportSource":{"type":"string"},"touchSource":{"type":"string"},"currentContent":{"type":"string"},"effectiveLanguage":{"type":"string"},"runtime":{"type":"object"},"settings":{"type":"object","properties":{"allowCamera":{"type":"boolean"},"allowMicrophone":{"type":"boolean"},"allowGeolocation":{"type":"boolean"},"preferredLanguage":{"type":"string"},"effectiveLanguage":{"type":"string"},"showMouseCursor":{"type":"boolean"},"showBadgeOverlay":{"type":"boolean"},"watermarkPosition":{"type":"string"}}}}},"category":"displays"},{"name":"get_display_capabilities","title":"Get Display Capabilities","description":"Returns resolved display capabilities for a display, including effective network mode plus concrete browser/runtime facts such as screen, viewport, touch/input hints, browser and engine version, platform classification, feature support, known limitations, graphics hints, and a recommended delivery mode. Call this before generating or sending HTML so your agent can match the content to the real display browser. Requires authentication with at least content_only scope.","inputSchema":{"type":"object","required":["display_id"],"properties":{"display_id":{"type":"string","description":"The 8-character alphanumeric display profile ID, e.g. 'ABCD1234'."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."},"session_request_id":{"type":"string","description":"Optional session request ID returned by create_auth_session. Pass this instead of access_token for simpler, more reliable authentication — the server resolves the identity server-side."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"displayId":{"type":"string"},"capabilities":{"type":"object","properties":{"resolvedMode":{"type":"string"},"effectiveWhitelist":{"type":"array","items":{"type":"string"}},"supportsEmbeddedContent":{"type":"boolean"}}},"connectivity":{"type":"object","properties":{"resolvedMode":{"type":"string"},"effectiveWhitelist":{"type":"array","items":{"type":"string"}},"supportsEmbeddedContent":{"type":"boolean"}}},"screen":{"type":"object"},"viewport":{"type":"object"},"classification":{"type":"object"},"runtime":{"type":"object"},"metadata":{"type":"object","properties":{"inheritedFrom":{"type":"string"}}}}},"category":"displays"},{"name":"create_display","title":"Create Display","description":"Creates a personal display WITHOUT pairing it to physical hardware. The display starts offline and uncoupled. For physical screens, ALWAYS prefer pair_by_code instead — it creates and pairs in one step. Use create_display only when: (a) the user explicitly wants to pre-provision a display before the screen is available, or (b) the user needs a virtual/headless display for API-only content delivery. Do not call this just to check capacity — use get_account to inspect remainingDisplays first. Requires admin scope; list_displays and send_html only need content_only. Returns id, name, displayUrl, setupUrl, managedUrl, pairingUrl, pairingExpiresAt, approvalUrl and status.","inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Optional friendly name for the new display. If omitted, a default name is assigned. Example: 'Lobby Screen'."},"access_token":{"type":"string","description":"Optional JWT access token for authentication. Pass the token returned by get_auth_session when your MCP client does not send it as an Authorization: Bearer HTTP header automatically."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"displayUrl":{"type":"string"},"setupUrl":{"type":"string"},"managedUrl":{"type":"string"},"pairingUrl":{"type":"string"},"pairingExpiresAt":{"type":"string"},"approvalUrl":{"type":"string"},"status":{"type":"string"}}},"category":"displays"},{"name":"rename_display","title":"Rename Display","description":"Changes the friendly name of an existing display. Use this when the user wants to update only the display name without affecting its content or state. Requires admin scope. Returns id and the updated name.","inputSchema":{"type":"object","required":["display_id","name"],"properties":{"display_id":{"type":"string","description":"The 8-character alphanumeric display profile ID to rename, e.g. 'ABCD1234'."},"name":{"type":"string","description":"The new friendly display name. Non-empty string."},"access_token":{"type":"string","description":"Optional JWT access token for authentication. Pass the token returned by get_auth_session when your MCP client does not send it as an Authorization: Bearer HTTP header automatically."}}},"annotations":{"readOnlyHint":false,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}},"category":"displays"},{"name":"delete_display","title":"Delete Display","description":"Permanently deletes a display and all its associated content. This action cannot be undone. Use this only when the user explicitly confirms they want to remove the display. Requires admin scope. Returns id, name and deleted (boolean true).","inputSchema":{"type":"object","required":["display_id"],"properties":{"display_id":{"type":"string","description":"The 8-character alphanumeric display profile ID to delete, e.g. 'ABCD1234'."},"access_token":{"type":"string","description":"Optional JWT access token for authentication. Pass the token returned by get_auth_session when your MCP client does not send it as an Authorization: Bearer HTTP header automatically."}}},"annotations":{"destructiveHint":true,"readOnlyHint":false,"idempotentHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"id":{"type":"string"},"deleted":{"type":"boolean"}}},"category":"displays"},{"name":"send_html","title":"Send HTML","description":"Pushes raw HTML content to a display, immediately replacing whatever is currently shown to viewers. Prefer this over send_url unless the user explicitly wants an external page rendered as-is. Include a human-readable description whenever possible so later get_display_content calls can summarize intent without immediately reading raw HTML. Before generating complex HTML, inspect get_display_capabilities for the target display so you know the real browser/runtime limits. When the user does not supply a detailed design system, default to premium digital-signage quality: full-screen layout, strong visual hierarchy, atmospheric background treatment, refined typography, robust fallback data, and no action buttons unless touch interaction is explicitly requested. For the full creative brief, load render_premium_display_html or read agentview://public/design-system before generating the HTML. Requires authentication with at least content_only scope; the user must be allowed to manage the target display. Exactly one of html or base64_html must be provided. Returns id, name, duration, file (stored filename) and version (content version ID).","inputSchema":{"type":"object","required":["display_id","description"],"properties":{"display_id":{"type":"string","description":"The 8-character alphanumeric display profile ID to send content to, e.g. 'ABCD1234'."},"description":{"type":"string","minLength":1,"maxLength":1000,"description":"Mandatory short human-readable description of the HTML upload (1-1000 characters), e.g. 'Weekly KPI dashboard with revenue and uptime'."},"content_description":{"type":"string","description":"Optional alias for description. If both are provided, description wins."},"html":{"type":"string","description":"Complete HTML document or fragment to render on the display. Mutually exclusive with base64_html — provide exactly one."},"base64_html":{"type":"string","description":"Base64-encoded HTML string (standard base64, not base64url). Use this instead of html only when the HTML contains characters that cannot survive JSON string transport. Mutually exclusive with html."},"duration":{"type":"integer","minimum":0,"description":"How long the content stays on the display in seconds. 0 means indefinite (content persists until replaced). Defaults to 0 when omitted."},"token":{"type":"string","description":"Display-specific preview token for unauthenticated demo-sign access. This is NOT the auth/JWT token. Omit this for normal authenticated usage."},"access_token":{"type":"string","description":"Optional JWT access token for authentication. Pass the token returned by get_auth_session when your MCP client does not send it as an Authorization: Bearer HTTP header automatically. This is different from 'token' which is a display-specific preview token."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"duration":{"type":"integer"},"file":{"type":"string"},"version":{"type":"string"},"currentContentDescription":{"type":"string"}}},"category":"content"},{"name":"send_url","title":"Send URL","description":"Loads a web page by URL on a display using a full-page iframe, immediately replacing whatever is currently shown. Use this when the user wants to show an external website, dashboard or web app on a display. Provide content_description whenever available so get_display_content can communicate intent without forcing read_display_html. The URL must be an absolute HTTP or HTTPS address. Check get_display_capabilities first to confirm connectivity and browser/runtime support before relying on a remote page. Use this only when the external page already has the desired design quality; otherwise prefer send_html and load render_premium_display_html or read agentview://public/design-system so you can generate a premium display-native experience yourself. Requires authentication with at least content_only scope. Returns id, name, duration, file and version.","inputSchema":{"type":"object","required":["display_id","url"],"properties":{"display_id":{"type":"string","description":"The 8-character alphanumeric display profile ID, e.g. 'ABCD1234'."},"url":{"type":"string","description":"The absolute HTTP or HTTPS URL to load on the display. Example: 'https://example.com/dashboard'."},"duration":{"type":"integer","minimum":0,"description":"How long the content stays on the display in seconds. 0 means indefinite. Defaults to 0."},"content_description":{"type":"string","description":"Optional human-readable summary of what this URL content is about (recommended)."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"duration":{"type":"integer"},"file":{"type":"string"},"version":{"type":"string"},"currentContentDescription":{"type":"string"}}},"category":"content"},{"name":"clear_display","title":"Clear Display","description":"Removes the current live content from a display and returns it to its idle/default state. Viewers will immediately see the change. Use this when the user wants to blank or reset a display. This does not delete the display itself — use delete_display for that. Requires authentication with at least content_only scope. Returns id and status ('cleared').","inputSchema":{"type":"object","required":["display_id"],"properties":{"display_id":{"type":"string","description":"The 8-character alphanumeric display profile ID to clear, e.g. 'ABCD1234'."},"access_token":{"type":"string","description":"Optional JWT access token for authentication. Pass the token returned by get_auth_session when your MCP client does not send it as an Authorization: Bearer HTTP header automatically."}}},"annotations":{"readOnlyHint":false,"idempotentHint":true,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"id":{"type":"string"}}},"category":"content"},{"name":"set_idle_content","title":"Set Idle Content","description":"Sets or clears the default idle content for a display. Idle content is shown whenever the display has no active live content. Provide html to set idle content, or omit it to clear idle content. Provide content_description to make later state reads easier for agents. Requires admin scope.","inputSchema":{"type":"object","required":["display_id"],"properties":{"display_id":{"type":"string","description":"The 8-character alphanumeric display profile ID, e.g. 'ABCD1234'."},"html":{"type":"string","description":"Complete HTML to use as idle content. Omit this to clear custom idle content."},"content_description":{"type":"string","description":"Optional human-readable summary for the idle/default content."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"idleFile":{"type":"string"},"idleVersion":{"type":"string"},"idleContentCleared":{"type":"boolean"}}},"category":"content"},{"name":"get_display_content","title":"Get Display Content","description":"Returns the current content state of a display including active live content, content URL, a live preview link (displayUrl), idle content and delivery status. Check currentContentDescription first to understand intent; call read_display_html only when you truly need raw source edits. The displayUrl is a browser-openable live preview that renders exactly what the display shows in real time. Requires content_only scope.","inputSchema":{"type":"object","required":["display_id"],"properties":{"display_id":{"type":"string","description":"The 8-character alphanumeric display profile ID, e.g. 'ABCD1234'."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"hasLiveContent":{"type":"boolean"},"currentFile":{"type":"string"},"currentVersion":{"type":"string"},"currentContentDescription":{"type":"string"},"contentUrl":{"type":"string"},"displayUrl":{"type":"string"},"hasIdleContent":{"type":"boolean"},"idleFile":{"type":"string"},"liveContentInfo":{"type":"string"}}},"category":"content"},{"name":"read_display_html","title":"Read Display HTML","description":"Reads the raw HTML source code currently shown on a display. Use this to inspect, modify or reuse existing content. Typical workflow: read_display_html to get the HTML, make changes, then send_html to push it back. Returns the complete HTML string plus metadata. If no live content is active, returns idle content if set. Requires content_only scope.","inputSchema":{"type":"object","required":["display_id"],"properties":{"display_id":{"type":"string","description":"The 8-character alphanumeric display profile ID, e.g. 'ABCD1234'."},"content_type":{"type":"string","enum":["live","idle"],"description":"Which content to read: 'live' (default) returns the active content, 'idle' returns the idle/default content."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"contentType":{"type":"string"},"hasContent":{"type":"boolean"},"html":{"type":"string"},"htmlLength":{"type":"integer"},"source":{"type":"string"}}},"category":"content"},{"name":"lock_display","title":"Lock Display","description":"Locks a display so that content changes such as send_html, send_url and clear_display are rejected until unlock_display is called. Use this when the user wants to protect a display from accidental content changes. The display continues showing its current content. Requires admin scope. Returns id and locked (boolean true). To reverse this, use unlock_display.","inputSchema":{"type":"object","required":["display_id"],"properties":{"display_id":{"type":"string","description":"The 8-character alphanumeric display profile ID to lock, e.g. 'ABCD1234'."},"access_token":{"type":"string","description":"Optional JWT access token for authentication. Pass the token returned by get_auth_session when your MCP client does not send it as an Authorization: Bearer HTTP header automatically."}}},"annotations":{"readOnlyHint":false,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"id":{"type":"string"},"locked":{"type":"boolean"}}},"category":"displays"},{"name":"unlock_display","title":"Unlock Display","description":"Unlocks a previously locked display so that content changes (send_html, send_url, clear_display) are accepted again. Use this when the user wants to resume managing a locked display. Requires admin scope. Returns id and locked (boolean false). To lock again, use lock_display.","inputSchema":{"type":"object","required":["display_id"],"properties":{"display_id":{"type":"string","description":"The 8-character alphanumeric display profile ID to unlock, e.g. 'ABCD1234'."},"access_token":{"type":"string","description":"Optional JWT access token for authentication. Pass the token returned by get_auth_session when your MCP client does not send it as an Authorization: Bearer HTTP header automatically."}}},"annotations":{"readOnlyHint":false,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"id":{"type":"string"},"locked":{"type":"boolean"}}},"category":"displays"},{"name":"configure_display","title":"Configure Display","description":"Updates hardware permission and UI settings for a display. Use this when the user wants to enable or disable camera, microphone or geolocation access, set the preferred display language, toggle the mouse cursor or badge overlay visibility, or change the watermark position. All parameters except display_id are optional — only provided settings are changed. If the display is online, changes are pushed immediately via SignalR. Requires admin scope.","inputSchema":{"type":"object","required":["display_id"],"properties":{"display_id":{"type":"string","description":"The 8-character alphanumeric display profile ID, e.g. 'ABCD1234'."},"allow_camera":{"type":"boolean","description":"Allow embedded content to request camera access. Default is false."},"allow_microphone":{"type":"boolean","description":"Allow embedded content to request microphone access. Default is false."},"allow_geolocation":{"type":"boolean","description":"Allow embedded content to request geolocation access. Default is false."},"preferred_language":{"type":"string","enum":["de","en","zh"],"description":"Preferred language for the display shell. Omit to leave unchanged."},"show_mouse_cursor":{"type":"boolean","description":"Show a visible mouse cursor on the display surface. Default is true."},"show_badge_overlay":{"type":"boolean","description":"Show the AI connect badge overlay on the display. Default is true."},"watermark_position":{"type":"string","enum":["BottomLeft","BottomRight","TopLeft","TopRight"],"description":"Position of the badge watermark on the display."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"allowCamera":{"type":"boolean"},"allowMicrophone":{"type":"boolean"},"allowGeolocation":{"type":"boolean"},"preferredLanguage":{"type":"string"},"effectiveLanguage":{"type":"string"},"showMouseCursor":{"type":"boolean"},"showBadgeOverlay":{"type":"boolean"},"watermarkPosition":{"type":"string"},"changedSettings":{"type":"array","items":{"type":"string"}},"appliedToLiveDisplay":{"type":"boolean"}}},"category":"displays"},{"name":"pair_by_code","title":"Pair Display by Code","description":"PREFERRED way to set up a physical display. Ask the user to open https://display.agentview.de on the target TV/screen, read the 6-character code, and share it. Then call this tool. This creates and pairs the display in one step — no orphaned or offline displays. Two modes: (1) New display — provide code + profile_name to create and pair in one step. This is the recommended default for first-time setup. (2) Rebind — provide code + target_display_id to move an existing display profile to new hardware. Call list_displays first to get the target_display_id. Always prefer this over create_display or create_org_display for physical devices. Use create_display/create_org_display only for pre-provisioning when the screen is not yet available. Requires admin scope. Returns profileId, name, linkedHardwareId and mode ('new' or 'rebind').","inputSchema":{"type":"object","required":["code"],"properties":{"code":{"type":"string","description":"The 6-character pairing code shown on the display (e.g. 'AB3K7F')."},"profile_name":{"type":"string","description":"Friendly name for the display (required for new pairing, ignored for rebind). Example: 'Lobby Screen'."},"target_display_id":{"type":"string","description":"To rebind: the existing display profile ID to switch to the new hardware. Omit for new display pairing."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"profileId":{"type":"string"},"name":{"type":"string"},"linkedHardwareId":{"type":"string"},"mode":{"type":"string","enum":["new","rebind"]}}},"category":"displays"},{"name":"claim_display","title":"Claim Display","description":"Converts an unclaimed guest or pending display into a managed personal display owned by the authenticated user. This permanently transfers ownership and counts against the user's display quota. Use this only when the user explicitly wants to adopt an existing hardware or demo display that is already running. For first-time physical setup, prefer pair_by_code instead. Requires admin scope. Returns profileId (the new managed display ID) and name.","inputSchema":{"type":"object","required":["display_id","profile_name"],"properties":{"display_id":{"type":"string","description":"The short ID of the pending, guest or demo display to claim. This is the hardware or temporary ID shown on the device."},"profile_name":{"type":"string","description":"Friendly name to assign to the newly claimed display. Non-empty string. Example: 'Reception Kiosk'."},"access_token":{"type":"string","description":"Optional JWT access token for authentication. Pass the token returned by get_auth_session when your MCP client does not send it as an Authorization: Bearer HTTP header automatically."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"profileId":{"type":"string"},"name":{"type":"string"}}},"category":"displays"},{"name":"assign_license","title":"Assign License","description":"Assigns a premium license token to a display, removing its watermark and making it ad-free. The user must have unassigned premium licenses available. Each license also adds +30 MB to the display's context storage pool (personal or group). Requires admin scope.","inputSchema":{"type":"object","required":["display_id"],"properties":{"display_id":{"type":"string","description":"The 8-character alphanumeric display profile ID to assign a license to, e.g. 'ABCD1234'."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"isPremiumAssigned":{"type":"boolean"},"badgeMode":{"type":"string"},"freeLicenses":{"type":"integer"}}},"category":"displays"},{"name":"unassign_license","title":"Unassign License","description":"Removes a premium license token from a display, restoring the watermark and ad eligibility. The license returns to the user's available pool. Requires admin scope.","inputSchema":{"type":"object","required":["display_id"],"properties":{"display_id":{"type":"string","description":"The 8-character alphanumeric display profile ID to remove a license from, e.g. 'ABCD1234'."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"isPremiumAssigned":{"type":"boolean"},"badgeMode":{"type":"string"},"freeLicenses":{"type":"integer"}}},"category":"displays"},{"name":"create_api_key","title":"Create API Key","description":"Creates a long-lived API key for server-to-server integration without OAuth. The raw key is returned only once — store it securely. The user must explicitly consent to creating the key. Requires admin scope. Supports granular scoping: restrict the key to specific data-slot slugs, specific display IDs, a read/write permission flag, and/or fine-grained capability flags.","inputSchema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Human-readable name for the key. Example: 'Home Assistant', 'CI Pipeline'."},"scope":{"type":"string","default":"content_only","description":"Scope for the key: 'content_only' (send content, list displays) or 'admin' (full management)."},"org_id":{"type":"string","description":"Optional organization ID. If set, the key acts on behalf of this organization."},"expires_in_days":{"type":"integer","description":"Optional expiration in days. If not set, the key never expires."},"permissions":{"type":"string","default":"read_write","description":"Granular permission flag: 'read', 'write', or 'read_write' (default). Applied on top of 'scope' — e.g. a content_only read-only key cannot PUT data slots. Matched against HTTP verb: GET requires read, PUT/POST/PATCH/DELETE require write."},"allowed_slot_slugs":{"description":"Optional JSON array of data-slot slugs this key may touch (max 64). When set, every data-slot request must target one of these slugs. Omit or pass [] for no slug restriction. Example: ['sensor-lobby', 'sensor-garage']."},"allowed_display_ids":{"description":"Optional JSON array of display profile IDs this key may touch (max 64). When set, every display request must target one of these IDs. Omit or pass [] for no display restriction. Example: ['ABCD1234','EFGH5678']."},"capabilities":{"description":"Optional JSON array of fine-grained capability flags this key may exercise. Allowed values: 'slot.read' (list/get slots), 'slot.write' (put/delete slots), 'display.read' (list/get displays, read content), 'display.send' (send_html/send_url/broadcast/clear/set_idle), 'display.manage' (rename/delete/lock/configure/license/pair/claim/create). Omit or pass [] for no capability restriction. Capabilities narrow — never expand — the key's rights; they combine with scope, permissions, and resource whitelists."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"key":{"type":"string"},"keyId":{"type":"string"},"name":{"type":"string"},"scope":{"type":"string"},"permissions":{"type":"string"},"allowedSlotSlugs":{"type":"array","items":{"type":"string"}},"allowedDisplayIds":{"type":"array","items":{"type":"string"}},"capabilities":{"type":"array","items":{"type":"string"}},"orgId":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"warning":{"type":"string"}}},"category":"api-keys"},{"name":"list_api_keys","title":"List API Keys","description":"Lists all API keys for the current user. Returns key metadata (prefix, name, scope, dates) but never the raw key. Requires admin scope.","inputSchema":{"type":"object","properties":{"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"count":{"type":"integer"},"keys":{"type":"array","items":{"type":"object","properties":{"keyId":{"type":"string"},"keyPrefix":{"type":"string"},"name":{"type":"string"},"scope":{"type":"string"},"permissions":{"type":"string"},"allowedSlotSlugs":{"type":"array","items":{"type":"string"}},"allowedDisplayIds":{"type":"array","items":{"type":"string"}},"capabilities":{"type":"array","items":{"type":"string"}},"orgId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"lastUsedAt":{"type":"string","format":"date-time"},"isRevoked":{"type":"boolean"},"isValid":{"type":"boolean"}}}}}},"category":"api-keys"},{"name":"revoke_api_key","title":"Revoke API Key","description":"Permanently revokes an API key. This is irreversible — the key will immediately stop working. Requires admin scope.","inputSchema":{"type":"object","required":["key_id"],"properties":{"key_id":{"type":"string","description":"The ID of the key to revoke (from list_api_keys)."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"revoked":{"type":"boolean"},"keyId":{"type":"string"}}},"category":"api-keys"},{"name":"upload_asset","title":"Upload Asset","description":"Upload one or more files (images, fonts, CSS, video, etc.) as assets and receive stable URLs. Use these URLs in your HTML with <img src> or @font-face. Assets are cached on displays. Pass files as base64-encoded data. Requires authentication with at least content_only scope.","inputSchema":{"type":"object","required":["files","descriptions"],"properties":{"files":{"type":"array","description":"Array of file objects, each with 'name' (filename with extension) and 'data' (base64-encoded content).","items":{"type":"object","properties":{"name":{"type":"string"},"data":{"type":"string"}}}},"descriptions":{"type":"object","description":"JSON object mapping each filename to a human-readable description."},"group_id":{"type":"string","description":"Optional group ID to associate the assets with."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"count":{"type":"integer"},"assets":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"},"mimeType":{"type":"string"},"sizeBytes":{"type":"integer"}}}}}},"category":"assets"},{"name":"list_assets","title":"List Assets","description":"Lists the authenticated user's uploaded assets with optional filtering by type, search term, and group. Returns asset URLs that can be used in HTML content. Check this before uploading to avoid duplicates. Requires authentication with at least content_only scope.","inputSchema":{"type":"object","properties":{"type":{"type":"string","enum":["image","video","audio","font","document","data"],"description":"Filter by MIME category."},"search":{"type":"string","description":"Search in filename and description (case-insensitive)."},"group_id":{"type":"string","description":"Only assets of this group. Omit for personal assets."},"limit":{"type":"integer","minimum":1,"maximum":200,"description":"Maximum results (default: 50, max: 200)."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"count":{"type":"integer"},"assets":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"},"mimeType":{"type":"string"},"description":{"type":"string"},"sizeBytes":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"}}}}}},"category":"assets"},{"name":"get_asset","title":"Get Asset","description":"Returns metadata for a single asset including its URL. Use this to verify an asset still exists before referencing it in HTML. Requires authentication with at least content_only scope.","inputSchema":{"type":"object","required":["asset_id"],"properties":{"asset_id":{"type":"string","description":"The asset ID (e.g. 'ast_01H7KXZ...')."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"assetId":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"},"mimeType":{"type":"string"},"description":{"type":"string"},"sizeBytes":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"}}},"category":"assets"},{"name":"update_asset","title":"Update Asset","description":"Updates the name and/or description of an existing asset. The URL does not change. At least one of name or description must be provided. Requires authentication with at least content_only scope.","inputSchema":{"type":"object","required":["asset_id"],"properties":{"asset_id":{"type":"string","description":"The asset ID to update."},"name":{"type":"string","description":"New filename for the asset."},"description":{"type":"string","description":"New description for the asset."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"assetId":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"},"description":{"type":"string"}}},"category":"assets"},{"name":"delete_asset","title":"Delete Asset","description":"Deletes one or more assets. Displays referencing deleted assets will show broken images. Requires authentication with at least content_only scope.","inputSchema":{"type":"object","required":["asset_ids"],"properties":{"asset_ids":{"type":"array","description":"One or more asset IDs to delete.","items":{"type":"string"}},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"deleted":{"type":"integer"}}},"category":"assets"},{"name":"set_data_slot","title":"Set Data Slot","description":"Creates or updates a mutable JSON data slot (max 2 MB). Display HTML reads it via the readUrl returned in the response: /data/u/{publicSlug}/{slug}.json (personal) or /data/g/{groupSlug}/{slug}.json (group). Slugs are unique per-user or per-group — two users can both use slug 'weather'. Human-readable slugs are not secret. Two slot kinds are supported: omit 'type' or pass 'value' to store the JSON content verbatim (default); pass 'type' = 'aggregate' to store a composite slot whose 'content' is a definition document of the shape { sources: [{slot,as}], onMissing, includeMeta }. The public read URL of an aggregate slot resolves and combines the source slots on every fetch, so displays only need one request to read multiple producers. Aggregate sources must live in the same scope (personal aggregate -> personal sources; group aggregate -> sources in the same group). Requires authentication with content scope. In the dashboard UI, aggregate slots are presented as 'JSON collections'.","inputSchema":{"type":"object","required":["slug","content"],"properties":{"slug":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,64}$","description":"Slug for the data slot. Must match ^[A-Za-z0-9_-]{8,64}$. Unique within your personal scope or the specified group."},"content":{"description":"JSON content to store. For value slots: any valid JSON value up to 2 MB. For aggregate slots: a definition object { sources: [{slot,as?}], onMissing?, includeMeta? }."},"label":{"type":"string","maxLength":200,"description":"Human-readable label (max 200 chars). Required when creating a new slot; optional on update."},"group_id":{"type":"string","description":"Group/organization ID for shared group slots. Omit for personal slots."},"type":{"type":"string","enum":["value","aggregate"],"description":"Slot kind. 'value' (default) stores 'content' verbatim. 'aggregate' stores 'content' as a composite-slot definition. Immutable after creation."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"slug":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"},"groupId":{"type":"string"},"readUrl":{"type":"string"},"sizeBytes":{"type":"integer"},"updatedAt":{"type":"string","format":"date-time"}}},"category":"data-slots"},{"name":"get_data_slot","title":"Get Data Slot","description":"Returns the current JSON content and metadata of a data slot by slug. Supply group_id to look up a group slot; omit it for personal slots. The response includes readUrl — the public anonymous URL for display HTML to fetch. Requires authentication.","inputSchema":{"type":"object","required":["slug"],"properties":{"slug":{"type":"string","description":"The slug of the data slot to retrieve."},"group_id":{"type":"string","description":"Group/organization ID to retrieve a group slot. Omit for personal slots."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"slug":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"},"content":{},"readUrl":{"type":"string"},"groupId":{"type":"string"},"sizeBytes":{"type":"integer"},"updatedAt":{"type":"string","format":"date-time"}}},"category":"data-slots"},{"name":"list_data_slots","title":"List Data Slots","description":"Lists data slots with optional filtering. Returns metadata only (no jsonContent). Each item includes readUrl. Use readUrl in display HTML fetch() calls. Requires authentication.","inputSchema":{"type":"object","properties":{"group_id":{"type":"string","description":"Group/organization ID to list shared group slots. Omit for personal slots."},"search":{"type":"string","description":"Search in label (case-insensitive)."},"limit":{"type":"integer","minimum":1,"maximum":200,"description":"Maximum results (default: 50, max: 200)."},"offset":{"type":"integer","minimum":0,"description":"Offset for pagination."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":true,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"count":{"type":"integer"},"slots":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"},"readUrl":{"type":"string"},"groupId":{"type":"string"},"sizeBytes":{"type":"integer"},"updatedAt":{"type":"string","format":"date-time"}}}}}},"category":"data-slots"},{"name":"delete_data_slot","title":"Delete Data Slot","description":"Permanently deletes a data slot. Display HTML fetching its readUrl will receive 404 after deletion. Cannot be undone. Supply group_id to delete a group slot; omit for personal slots. Requires authentication.","inputSchema":{"type":"object","required":["slug"],"properties":{"slug":{"type":"string","description":"The slug of the data slot to delete."},"group_id":{"type":"string","description":"Group/organization ID to delete a group slot. Omit for personal slots."},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":false,"destructiveHint":true,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:content"]}]},"outputSchema":{"type":"object","properties":{"slug":{"type":"string"},"deleted":{"type":"boolean"}}},"category":"data-slots"},{"name":"set_org_connectivity","title":"Set Org Connectivity","description":"Sets the default connectivity mode and global whitelist for an organization. These settings apply to all displays in the org unless overridden at the display level. Use this when an org admin wants to declare their network topology. Requires admin scope and Org-Admin role.","inputSchema":{"type":"object","required":["org_id"],"properties":{"org_id":{"type":"string","description":"The organization ID."},"default_connectivity_mode":{"type":"string","enum":["full-access","whitelist-only","isolated","inherit"],"description":"Default connectivity mode for all org displays."},"global_whitelist":{"type":"array","description":"Org-wide whitelist of allowed URL patterns. Pass an empty array to clear.","items":{"type":"string"}},"access_token":{"type":"string","description":"Optional JWT access token for authentication."}}},"annotations":{"readOnlyHint":false,"idempotentHint":true,"destructiveHint":false,"openWorldHint":false},"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}],"_meta":{"securitySchemes":[{"type":"oauth2","scopes":["mcp:admin"]}]},"outputSchema":{"type":"object","properties":{"orgId":{"type":"string"},"defaultConnectivityMode":{"type":"string"},"globalWhitelist":{"type":"array","items":{"type":"string"}}}},"category":"connectivity"}],"toolCount":64,"prompts":[{"name":"onboard_first_display","title":"First Display Onboarding","description":"Guide the assistant through helping a user create and understand their first display.","arguments":[{"name":"goal","description":"Optional end goal, for example 'show a welcome page on a lobby screen'.","required":false}]},{"name":"recover_mcp_auth","title":"Recover MCP Auth","description":"Guide the assistant through diagnosing MCP OAuth, discovery and session failures.","arguments":[{"name":"client_name","description":"Optional MCP client name such as ChatGPT, Claude Desktop or Antigravity.","required":false},{"name":"symptom","description":"Optional short symptom description such as 'redirect loop' or '401 on first tool call'.","required":false}]},{"name":"render_premium_display_html","title":"Render Premium Display HTML","description":"Load the premium agentView creative brief for generating polished, high-end digital signage HTML from a one-shot request.","arguments":[{"name":"brief","description":"The one-shot request or content brief that should become display HTML.","required":true},{"name":"category","description":"Optional category such as dashboard, welcome screen, menu board or event schedule.","required":false},{"name":"touch_mode","description":"Optional interaction mode: display-first, touch or control-panel.","required":false},{"name":"data_mode","description":"Optional data strategy: live-with-fallback, static or mock-only.","required":false},{"name":"brand_direction","description":"Optional visual direction such as Apple-like, luxury hospitality or industrial operations.","required":false}]}],"promptCount":3,"resources":[{"uri":"ui://widget/agentview-store-gallery","name":"agentView Template Gallery","title":"agentView Template Gallery","description":"Visual card grid of agentView store templates returned by search_store_templates and list_store_categories.","mimeType":"text/html+skybridge","annotations":{"audience":["assistant"],"priority":0.4}},{"uri":"ui://widget/agentview-store-detail","name":"agentView Template Detail","title":"agentView Template Detail","description":"Hero + intro + features + use cases for a single store template returned by get_store_template_details.","mimeType":"text/html+skybridge","annotations":{"audience":["assistant"],"priority":0.4}},{"uri":"ui://widget/agentview-store-install-result","name":"agentView Template Installed","title":"agentView Template Installed","description":"Success/error confirmation card rendered after send_store_template_to_display.","mimeType":"text/html+skybridge","annotations":{"audience":["assistant"],"priority":0.4}},{"uri":"agentview://public/status","name":"Public status","title":"Public status","description":"Server health, MCP discovery endpoints and public readiness information.","mimeType":"application/json","annotations":{"audience":["user","assistant"],"priority":0.3}},{"uri":"agentview://public/instructions","name":"Agent instructions","title":"Agent instructions","description":"Recommended authentication and usage flow for MCP clients.","mimeType":"text/plain","annotations":{"audience":["assistant"],"priority":0.8}},{"uri":"agentview://public/design-system","name":"Premium display design system","title":"Premium display design system","description":"Default premium digital-signage brief for generating high-end display HTML.","mimeType":"text/plain","annotations":{"audience":["assistant"],"priority":0.5}},{"uri":"agentview://public/developers","name":"Developer documentation","title":"Developer documentation","description":"Technical MCP and OAuth integration reference.","mimeType":"text/plain","annotations":{"audience":["user","assistant"],"priority":0.4}},{"uri":"agentview://public/mcp","name":"MCP capability status","title":"MCP capability status","description":"Supported protocol versions, transports, resources, prompts, completions and subscription capabilities.","mimeType":"application/json","annotations":{"audience":["assistant"],"priority":0.3}},{"uri":"agentview://public/oauth","name":"OAuth status","title":"OAuth status","description":"Authorization endpoints, supported scopes, token methods, PKCE and protected resource metadata.","mimeType":"application/json","annotations":{"audience":["assistant"],"priority":0.6}},{"uri":"agentview://public/support","name":"Support diagnostics","title":"Support diagnostics","description":"Recommended evidence and checks for MCP, OAuth, session and interoperability troubleshooting.","mimeType":"text/plain","annotations":{"audience":["user","assistant"],"priority":0.2}},{"uri":"agentview://public/apis","name":"Public API catalog","title":"Public API catalog","description":"Catalog of 603 free, no-auth public APIs for embedding live data in display HTML via fetch().","mimeType":"application/json","annotations":{"audience":["assistant"],"priority":0.5}}],"resourceCount":11,"designGuidance":{"defaultMode":"premium-digital-signage","instructionsMode":"always-on-compact","recommendedPrompt":"render_premium_display_html","recommendedResource":"agentview://public/design-system"},"publicEndpoints":{"instructions":"https://agentview.de/agent-instructions","status":"https://agentview.de/api/status","developers":"https://agentview.de/developers.html","manifest":"https://agentview.de/mcp/manifest"}}