diff --git a/CHATGPT-SETUP.md b/CHATGPT-SETUP.md
index 9f45d08..90c6a04 100644
--- a/CHATGPT-SETUP.md
+++ b/CHATGPT-SETUP.md
@@ -25,14 +25,45 @@ The expected flow is:
1. ChatGPT calls `shd_list_projects` with `archived: false`.
2. ChatGPT may call a module render tool after the corresponding list tool:
`shd_render_projects_widget`, `shd_render_documents_widget`,
- `shd_render_tasks_widget`, `shd_render_finance_widget` or
- `shd_render_crm_widget`.
+ `shd_render_tasks_widget`, `shd_render_finance_widget`,
+ `shd_render_crm_widget`, `shd_render_discussions_widget`,
+ `shd_render_notifications_widget`, `shd_render_scheduling_widget`,
+ `shd_render_inventory_widget`, `shd_render_agents_widget`,
+ `shd_render_status_page_widget`, `shd_render_project_db_widget` or
+ `shd_render_notes_widget`, `shd_render_project_overview_widget`,
+ `shd_render_files_widget`, `shd_render_proposals_widget`,
+ `shd_render_terms_widget`, `shd_render_activity_widget`,
+ `shd_render_organizations_widget`, `shd_render_gitea_widget` or
+ `shd_render_schemes_widget`, `shd_render_task_kanban_widget`,
+ `shd_render_team_workload_widget`, `shd_render_project_timeline_widget`,
+ `shd_render_crm_funnel_widget`, `shd_render_finance_dashboard_widget`,
+ `shd_render_proposal_approvals_widget`, `shd_render_documents_completeness_widget`,
+ `shd_render_agents_health_widget`, `shd_render_schedule_calendar_widget`,
+ `shd_render_acl_matrix_widget`, `shd_render_inventory_warnings_widget`,
+ `shd_render_gitea_board_widget`, `shd_render_schemes_progress_widget`,
+ `shd_render_notes_tree_widget` or `shd_render_project_db_preview_widget`.
3. The selected widget renders a read-only register and can call the matching
detail tool for one selected row.
The widget resources are versioned at `ui://shd/active-projects/v1.html`,
`ui://shd/documents/v1.html`, `ui://shd/tasks/v1.html`,
-`ui://shd/finance/v1.html` and `ui://shd/crm/v1.html`.
+`ui://shd/finance/v1.html`, `ui://shd/crm/v1.html`,
+`ui://shd/discussions/v1.html`, `ui://shd/notifications/v1.html`,
+`ui://shd/scheduling/v1.html`, `ui://shd/inventory/v1.html`,
+`ui://shd/agents/v1.html`, `ui://shd/status-page/v1.html`,
+`ui://shd/project-db/v1.html`, `ui://shd/notes/v1.html`,
+`ui://shd/project-overview/v1.html`, `ui://shd/files/v1.html`,
+`ui://shd/proposals/v1.html`, `ui://shd/terms/v1.html`,
+`ui://shd/activity/v1.html`, `ui://shd/organizations/v1.html`,
+`ui://shd/gitea/v1.html`, `ui://shd/schemes/v1.html`,
+`ui://shd/task-kanban/v1.html`, `ui://shd/team-workload/v1.html`,
+`ui://shd/project-timeline/v1.html`, `ui://shd/crm-funnel/v1.html`,
+`ui://shd/finance-dashboard/v1.html`, `ui://shd/proposal-approvals/v1.html`,
+`ui://shd/documents-completeness/v1.html`, `ui://shd/agents-health/v1.html`,
+`ui://shd/schedule-calendar/v1.html`, `ui://shd/acl-matrix/v1.html`,
+`ui://shd/inventory-warnings/v1.html`, `ui://shd/gitea-board/v1.html`,
+`ui://shd/schemes-progress/v1.html`, `ui://shd/notes-tree/v1.html` and
+`ui://shd/project-db-preview/v1.html`.
The MCP tools remain usable without the widget. A failed OAuth connection is
an account/endpoint configuration problem, not a missing token in this repo.
diff --git a/README.md b/README.md
index 18ddf82..26fc145 100644
--- a/README.md
+++ b/README.md
@@ -63,12 +63,45 @@ The backend serves the checked-in widget artifact at
to the HTML resource under `plugins/shd-mcp-plugin/widgets/active-projects/v1/`.
The same read-only data/render contract is available for Documents, Tasks,
-Finance and CRM:
+Finance, CRM, Discussions, Notifications, Scheduling, Inventory, Agents,
+Status Page, Project DB, Notes, Project overview, Files, Proposals, Terms,
+Activity, Organizations and access, Gitea Issues and Schemes:
- `shd_render_documents_widget` → `ui://shd/documents/v1.html`;
- `shd_render_tasks_widget` → `ui://shd/tasks/v1.html`;
- `shd_render_finance_widget` → `ui://shd/finance/v1.html`;
-- `shd_render_crm_widget` → `ui://shd/crm/v1.html`.
+- `shd_render_crm_widget` → `ui://shd/crm/v1.html`;
+- `shd_render_discussions_widget` → `ui://shd/discussions/v1.html`;
+- `shd_render_notifications_widget` → `ui://shd/notifications/v1.html`;
+- `shd_render_scheduling_widget` → `ui://shd/scheduling/v1.html`;
+- `shd_render_inventory_widget` → `ui://shd/inventory/v1.html`;
+- `shd_render_agents_widget` → `ui://shd/agents/v1.html`;
+- `shd_render_status_page_widget` → `ui://shd/status-page/v1.html`;
+- `shd_render_project_db_widget` → `ui://shd/project-db/v1.html`;
+- `shd_render_notes_widget` → `ui://shd/notes/v1.html`.
+- `shd_render_project_overview_widget` → `ui://shd/project-overview/v1.html`;
+- `shd_render_files_widget` → `ui://shd/files/v1.html`;
+- `shd_render_proposals_widget` → `ui://shd/proposals/v1.html`;
+- `shd_render_terms_widget` → `ui://shd/terms/v1.html`;
+- `shd_render_activity_widget` → `ui://shd/activity/v1.html`;
+- `shd_render_organizations_widget` → `ui://shd/organizations/v1.html`;
+- `shd_render_gitea_widget` → `ui://shd/gitea/v1.html`;
+- `shd_render_schemes_widget` → `ui://shd/schemes/v1.html`;
+- `shd_render_task_kanban_widget` → `ui://shd/task-kanban/v1.html`;
+- `shd_render_team_workload_widget` → `ui://shd/team-workload/v1.html`;
+- `shd_render_project_timeline_widget` → `ui://shd/project-timeline/v1.html`;
+- `shd_render_crm_funnel_widget` → `ui://shd/crm-funnel/v1.html`;
+- `shd_render_finance_dashboard_widget` → `ui://shd/finance-dashboard/v1.html`;
+- `shd_render_proposal_approvals_widget` → `ui://shd/proposal-approvals/v1.html`;
+- `shd_render_documents_completeness_widget` → `ui://shd/documents-completeness/v1.html`;
+- `shd_render_agents_health_widget` → `ui://shd/agents-health/v1.html`;
+- `shd_render_schedule_calendar_widget` → `ui://shd/schedule-calendar/v1.html`;
+- `shd_render_acl_matrix_widget` → `ui://shd/acl-matrix/v1.html`;
+- `shd_render_inventory_warnings_widget` → `ui://shd/inventory-warnings/v1.html`;
+- `shd_render_gitea_board_widget` → `ui://shd/gitea-board/v1.html`;
+- `shd_render_schemes_progress_widget` → `ui://shd/schemes-progress/v1.html`;
+- `shd_render_notes_tree_widget` → `ui://shd/notes-tree/v1.html`;
+- `shd_render_project_db_preview_widget` → `ui://shd/project-db-preview/v1.html`.
Each widget accepts normalized records from its list tool, keeps the plain
structured response as a fallback and uses the MCP Apps bridge before the
@@ -140,7 +173,7 @@ node /var/www/admin/scripts/mcp/mcp-catalog.mjs | \
```
The runtime smoke harness checks OAuth metadata, PKCE S256 support, the
-authenticated MCP handshake and all five widget resources. It never assumes
+authenticated MCP handshake and all thirty-six widget resources. It never assumes
an endpoint or prints a token:
```bash
diff --git a/RELEASE.md b/RELEASE.md
index 0fba466..3051426 100644
--- a/RELEASE.md
+++ b/RELEASE.md
@@ -35,7 +35,7 @@ catalog is a checked-in name snapshot, so a Skill cannot silently reference an
unpublished MCP tool. Refresh it from the backend catalog before publishing.
`scripts/mcp-runtime-smoke.mjs` checks OAuth metadata, authenticated MCP
-negotiation and the active-projects/Documents/Tasks/Finance/CRM resources.
+negotiation and all thirty-six widget resources.
`scripts/mcp-oauth-e2e.mjs` is an opt-in Playwright check for the complete
authorization-code + PKCE exchange using an already authenticated storage
state. Neither script stores credentials or belongs in the static CI job.
@@ -52,9 +52,9 @@ JWKS signature and rejects a repeated `jti`.
used by `SHD_MCP_WIDGET_ROOT`, or at the repository path documented by the
backend loader.
3. Run the backend MCP verification and a real authenticated OAuth/tool call.
-4. Reconnect the custom ChatGPT app and test active projects, Documents, Tasks,
- Finance and CRM, including the plain structured fallback and each widget’s
- refresh/detail action.
+4. Reconnect the custom ChatGPT app and test all thirty-six widgets, including
+ the plain structured fallback and each widget’s refresh/detail action where
+ supported.
5. Record the exact revision and any runtime/browser checks. Static tests do
not prove OAuth, ACLs, production hosting or ChatGPT rendering.
diff --git a/contracts/mcp-tool-catalog.json b/contracts/mcp-tool-catalog.json
new file mode 100644
index 0000000..6671ed0
--- /dev/null
+++ b/contracts/mcp-tool-catalog.json
@@ -0,0 +1,787 @@
+{
+ "schemaVersion": 1,
+ "source": "SHD backend scripts/mcp/mcp-catalog.mjs",
+ "tools": [
+ "shd_activate_proposal_variant",
+ "shd_add_asset_maintenance",
+ "shd_add_crm_activity",
+ "shd_add_crm_note",
+ "shd_add_discussion_message",
+ "shd_add_finance_document_item",
+ "shd_add_organization_member",
+ "shd_add_procurement_items",
+ "shd_add_stocktake_results",
+ "shd_add_task_comment",
+ "shd_add_task_dependency",
+ "shd_add_task_project_member",
+ "shd_add_task_time_entry",
+ "shd_add_terms_point",
+ "shd_add_terms_room",
+ "shd_adjust_inventory_balance",
+ "shd_admin_controller_action",
+ "shd_admin_diagnostics",
+ "shd_admin_get_access_settings",
+ "shd_admin_get_module_settings",
+ "shd_admin_get_module_widget_layout",
+ "shd_admin_get_organization_members",
+ "shd_admin_get_project_settings",
+ "shd_admin_list_integrations",
+ "shd_admin_list_organizations",
+ "shd_admin_list_public_pages",
+ "shd_admin_list_users",
+ "shd_admin_save_organization",
+ "shd_admin_save_public_page",
+ "shd_admin_update_integration",
+ "shd_admin_update_module_settings",
+ "shd_admin_update_module_widget_layout",
+ "shd_admin_update_project_settings",
+ "shd_admin_update_user",
+ "shd_agents_access_rules",
+ "shd_agents_auto_exit_network_route",
+ "shd_agents_close_tunnel",
+ "shd_agents_create_controller_ssh_tunnel",
+ "shd_agents_create_controller_tcp_tunnel",
+ "shd_agents_create_tunnel",
+ "shd_agents_create_user_agent_tcp_tunnel",
+ "shd_agents_delete_exit_network_route_policy",
+ "shd_agents_drain_exit_node",
+ "shd_agents_enable_exit_node",
+ "shd_agents_exit_network",
+ "shd_agents_exit_network_route_policies",
+ "shd_agents_exit_node_logs",
+ "shd_agents_force_exit_network_route",
+ "shd_agents_get_async_status",
+ "shd_agents_get_controller_access_policies",
+ "shd_agents_get_controller_diagnostics",
+ "shd_agents_get_diagnostics",
+ "shd_agents_get_speed_test_status",
+ "shd_agents_get_user_agent_access_policies",
+ "shd_agents_history",
+ "shd_agents_overview",
+ "shd_agents_publish_controller_endpoint",
+ "shd_agents_publish_user_agent_endpoint",
+ "shd_agents_reboot_user_agent",
+ "shd_agents_replace_controller_access_policies",
+ "shd_agents_replace_user_agent_access_policies",
+ "shd_agents_restart_exit_node",
+ "shd_agents_retry_async_action",
+ "shd_agents_revoke_controller_endpoint",
+ "shd_agents_revoke_user_agent_endpoint",
+ "shd_agents_routing_gateway_command",
+ "shd_agents_save_access_rules",
+ "shd_agents_save_exit_network_route_policy",
+ "shd_agents_set_controller_zabbix_monitoring",
+ "shd_agents_set_user_agent_zabbix_monitoring",
+ "shd_agents_start_async_action",
+ "shd_agents_start_controller_speed_test",
+ "shd_agents_start_user_agent_speed_test",
+ "shd_agents_update_alice_runtime_settings",
+ "shd_agents_update_controller_settings",
+ "shd_agents_update_exit_node_config",
+ "shd_agents_update_user_agent",
+ "shd_agents_update_user_agent_settings",
+ "shd_allocate_finance_payment",
+ "shd_apply_note_operations",
+ "shd_apply_proposal_template_migration",
+ "shd_apply_proposal_template_migration_batch",
+ "shd_apply_scheme_operations",
+ "shd_apply_stocktake_adjustments",
+ "shd_approve_procurement_request",
+ "shd_archive_agent",
+ "shd_archive_crm_entity",
+ "shd_archive_discussion_channel",
+ "shd_archive_discussion_topic",
+ "shd_archive_note_collection",
+ "shd_archive_organization",
+ "shd_archive_project",
+ "shd_archive_task",
+ "shd_archive_task_automation_rule",
+ "shd_archive_task_form",
+ "shd_archive_task_portfolio_automation_rule",
+ "shd_assign_inventory_asset",
+ "shd_assign_task_to_sprint",
+ "shd_attach_file_to_entity",
+ "shd_bulk_assign_crm_responsible",
+ "shd_bulk_move_crm_stage",
+ "shd_bulk_replace_finance_document_items",
+ "shd_bulk_update_crm_entities",
+ "shd_bulk_update_tasks",
+ "shd_bulk_upsert_inventory_items",
+ "shd_bulk_upsert_terms_points",
+ "shd_calculate_proposal_template_version",
+ "shd_cancel_discussion_message_reminder",
+ "shd_cancel_organization_invitation",
+ "shd_cancel_scheduled_discussion_message",
+ "shd_cancel_scheduling_booking",
+ "shd_capabilities",
+ "shd_close_asset_maintenance",
+ "shd_close_inventory_stocktake",
+ "shd_comment_gitea_issue",
+ "shd_compare_terms_versions",
+ "shd_complete_crm_activity",
+ "shd_complete_crm_reminder",
+ "shd_complete_stocktake",
+ "shd_confirm_scheduling_booking",
+ "shd_convert_crm_lead",
+ "shd_copy_file",
+ "shd_create_controller",
+ "shd_create_crm_activity",
+ "shd_create_crm_lead",
+ "shd_create_crm_note",
+ "shd_create_crm_reminder",
+ "shd_create_discussion_channel",
+ "shd_create_discussion_topic",
+ "shd_create_document_external_link",
+ "shd_create_document_public_link",
+ "shd_create_document_template",
+ "shd_create_file_action",
+ "shd_create_file_share_link",
+ "shd_create_file_zip_link",
+ "shd_create_folder",
+ "shd_create_gitea_issue",
+ "shd_create_inventory_resource",
+ "shd_create_note_collection",
+ "shd_create_note_database",
+ "shd_create_note_database_property",
+ "shd_create_note_database_record",
+ "shd_create_note_database_view",
+ "shd_create_note_page",
+ "shd_create_note_page_discussion",
+ "shd_create_note_page_from_template",
+ "shd_create_note_review_comment",
+ "shd_create_note_review_discussion",
+ "shd_create_note_space",
+ "shd_create_note_template",
+ "shd_create_organization",
+ "shd_create_procurement_request",
+ "shd_create_procurement_shipment",
+ "shd_create_project",
+ "shd_create_project_device",
+ "shd_create_project_service",
+ "shd_create_proposal",
+ "shd_create_proposal_documents_contract",
+ "shd_create_proposal_template_version",
+ "shd_create_proposal_variant",
+ "shd_create_scheduling_availability_rule",
+ "shd_create_scheduling_booking",
+ "shd_create_scheduling_booking_link",
+ "shd_create_scheduling_event_type",
+ "shd_create_scheme_description_comment",
+ "shd_create_scheme_document",
+ "shd_create_status_page_group",
+ "shd_create_status_page_monitor",
+ "shd_create_stocktake",
+ "shd_create_task",
+ "shd_create_task_approval_route",
+ "shd_create_task_attachment_annotation",
+ "shd_create_task_automation_rule",
+ "shd_create_task_checklist_item",
+ "shd_create_task_custom_field",
+ "shd_create_task_form",
+ "shd_create_task_goal",
+ "shd_create_task_portfolio",
+ "shd_create_task_portfolio_automation_rule",
+ "shd_create_task_portfolio_member",
+ "shd_create_task_portfolio_status_update",
+ "shd_create_task_project",
+ "shd_create_task_project_announcement",
+ "shd_create_task_project_member",
+ "shd_create_task_project_status_update",
+ "shd_create_task_sprint",
+ "shd_create_task_status",
+ "shd_create_task_tag",
+ "shd_create_task_template",
+ "shd_create_task_view",
+ "shd_create_terms_document",
+ "shd_crm_workflow",
+ "shd_decide_proposal_approval",
+ "shd_delete_agent",
+ "shd_delete_controller",
+ "shd_delete_crm_reminder",
+ "shd_delete_discussion_message",
+ "shd_delete_discussion_topic",
+ "shd_delete_discussion_topic_draft",
+ "shd_delete_document_comment",
+ "shd_delete_document_external_link",
+ "shd_delete_document_template",
+ "shd_delete_exchange_rate",
+ "shd_delete_finance_account",
+ "shd_delete_finance_attachment",
+ "shd_delete_finance_category",
+ "shd_delete_finance_counterparty",
+ "shd_delete_finance_document_item",
+ "shd_delete_finance_legal_entity",
+ "shd_delete_finance_payment",
+ "shd_delete_finance_project",
+ "shd_delete_inventory_item",
+ "shd_delete_note_attachment",
+ "shd_delete_note_database",
+ "shd_delete_note_database_property",
+ "shd_delete_note_database_record",
+ "shd_delete_note_database_view",
+ "shd_delete_note_space",
+ "shd_delete_project_device",
+ "shd_delete_project_service",
+ "shd_delete_proposal",
+ "shd_delete_proposal_template_library_item",
+ "shd_delete_scheduling_availability_rule",
+ "shd_delete_scheduling_event_type",
+ "shd_delete_scheme_document",
+ "shd_delete_status_page_group",
+ "shd_delete_status_page_monitor",
+ "shd_delete_task",
+ "shd_delete_task_attachment",
+ "shd_delete_task_attachment_annotation",
+ "shd_delete_task_checklist_item",
+ "shd_delete_task_custom_field",
+ "shd_delete_task_dependency",
+ "shd_delete_task_goal",
+ "shd_delete_task_import_template",
+ "shd_delete_task_portfolio_member",
+ "shd_delete_task_project_announcement",
+ "shd_delete_task_project_member",
+ "shd_delete_task_status",
+ "shd_delete_task_tag",
+ "shd_delete_task_template",
+ "shd_delete_task_view",
+ "shd_delete_terms_document",
+ "shd_delete_terms_point",
+ "shd_delete_terms_room",
+ "shd_diff_note_revisions",
+ "shd_disconnect_agent",
+ "shd_disconnect_scheduling_calendar",
+ "shd_disconnect_scheduling_meeting_account",
+ "shd_document_contract_workflow",
+ "shd_download_document_pdf",
+ "shd_download_finance_attachment",
+ "shd_download_note_attachment",
+ "shd_download_proposal_pdf",
+ "shd_download_scheme_pdf",
+ "shd_download_terms_pdf",
+ "shd_duplicate_document_template",
+ "shd_duplicate_note_page",
+ "shd_duplicate_proposal",
+ "shd_duplicate_scheme_document",
+ "shd_duplicate_task",
+ "shd_duplicate_task_automation_rule",
+ "shd_duplicate_task_portfolio_automation_rule",
+ "shd_duplicate_terms_document",
+ "shd_export_finance_csv",
+ "shd_export_finance_document_pdf",
+ "shd_export_note_markdown",
+ "shd_export_scheme_document",
+ "shd_export_task_time_report",
+ "shd_finance_document_action",
+ "shd_finance_presence_leave",
+ "shd_finance_presence_upsert",
+ "shd_generate_contract_from_template",
+ "shd_generate_document_pdf",
+ "shd_generate_terms_pdf",
+ "shd_get_agent_notifications",
+ "shd_get_agent_settings",
+ "shd_get_alice_devices",
+ "shd_get_alice_diagnostics",
+ "shd_get_alice_selected_devices",
+ "shd_get_alice_settings",
+ "shd_get_audit_history",
+ "shd_get_contract",
+ "shd_get_controller_status",
+ "shd_get_crm_entity",
+ "shd_get_current_user",
+ "shd_get_document_contract_config",
+ "shd_get_document_render_preview",
+ "shd_get_file_link",
+ "shd_get_file_metadata",
+ "shd_get_file_versions",
+ "shd_get_finance_account_balance",
+ "shd_get_finance_document",
+ "shd_get_finance_import_errors",
+ "shd_get_finance_payment",
+ "shd_get_finance_settings",
+ "shd_get_grafana_settings",
+ "shd_get_grafana_settings_schema",
+ "shd_get_homekit_inventory",
+ "shd_get_homekit_selected_devices",
+ "shd_get_homekit_state",
+ "shd_get_homekit_templates",
+ "shd_get_inventory_asset",
+ "shd_get_inventory_item",
+ "shd_get_inventory_procurement",
+ "shd_get_note_backlinks",
+ "shd_get_note_database",
+ "shd_get_note_external_reference",
+ "shd_get_note_page",
+ "shd_get_note_revision",
+ "shd_get_note_space_tree",
+ "shd_get_note_template",
+ "shd_get_notification_preferences",
+ "shd_get_notification_read_state",
+ "shd_get_organization_two_factor_policy",
+ "shd_get_project",
+ "shd_get_project_context",
+ "shd_get_project_delete_plan",
+ "shd_get_project_settings",
+ "shd_get_proposal",
+ "shd_get_proposal_approval",
+ "shd_get_proposal_public_analytics",
+ "shd_get_proposal_public_links",
+ "shd_get_proposal_settings",
+ "shd_get_proposal_template",
+ "shd_get_proposal_template_capabilities",
+ "shd_get_proposal_template_migration_report",
+ "shd_get_proposal_template_version",
+ "shd_get_realtime_events",
+ "shd_get_scheduling_oauth_links",
+ "shd_get_scheduling_oauth_status",
+ "shd_get_scheduling_overview",
+ "shd_get_scheme_changes",
+ "shd_get_scheme_description_template",
+ "shd_get_scheme_document",
+ "shd_get_scheme_events",
+ "shd_get_scheme_log",
+ "shd_get_scheme_point",
+ "shd_get_scheme_point_discussion",
+ "shd_get_scheme_point_discussions",
+ "shd_get_status_page_monitor_history",
+ "shd_get_status_page_monitors",
+ "shd_get_task",
+ "shd_get_task_budget_summary",
+ "shd_get_task_capacity",
+ "shd_get_task_form",
+ "shd_get_task_project_meta",
+ "shd_get_task_time_report",
+ "shd_get_task_utilization",
+ "shd_get_task_workload",
+ "shd_get_terms_completeness",
+ "shd_get_terms_document",
+ "shd_get_terms_document_completeness",
+ "shd_get_terms_document_revision",
+ "shd_get_voice_agent_config",
+ "shd_get_voice_agent_diagnostics",
+ "shd_get_voice_agent_status",
+ "shd_grant_note_member",
+ "shd_hide_discussion_channel",
+ "shd_hold_scheduling_slot",
+ "shd_import_finance_specification",
+ "shd_import_note_markdown",
+ "shd_import_note_pages",
+ "shd_install_homekit",
+ "shd_install_task_automation_bundle",
+ "shd_install_task_automation_template",
+ "shd_inventory_action",
+ "shd_invite_user_to_create_organization",
+ "shd_invite_user_to_organization",
+ "shd_leave_note_space_presence",
+ "shd_leave_task_project_presence",
+ "shd_link_crm_entities",
+ "shd_list_contracts",
+ "shd_list_crm",
+ "shd_list_crm_activities",
+ "shd_list_crm_audit_log",
+ "shd_list_crm_custom_field_values",
+ "shd_list_crm_custom_fields",
+ "shd_list_crm_entity_links",
+ "shd_list_crm_loss_reasons",
+ "shd_list_crm_notes",
+ "shd_list_crm_pipelines",
+ "shd_list_crm_reminders",
+ "shd_list_crm_saved_views",
+ "shd_list_discussion_channels",
+ "shd_list_discussion_mention_users",
+ "shd_list_discussion_messages",
+ "shd_list_discussion_topics",
+ "shd_list_document_comments",
+ "shd_list_document_external_links",
+ "shd_list_document_notifications",
+ "shd_list_document_public_links",
+ "shd_list_document_revisions",
+ "shd_list_document_templates",
+ "shd_list_files",
+ "shd_list_finance_audit_log",
+ "shd_list_finance_documents",
+ "shd_list_finance_exchange_rates",
+ "shd_list_finance_import_jobs",
+ "shd_list_finance_payments",
+ "shd_list_finance_public_links",
+ "shd_list_finance_realtime_events",
+ "shd_list_finance_refs",
+ "shd_list_gitea_issues",
+ "shd_list_gitea_labels",
+ "shd_list_inventory_asset_assignments",
+ "shd_list_inventory_asset_maintenance",
+ "shd_list_inventory_assets",
+ "shd_list_inventory_audit_log",
+ "shd_list_inventory_items",
+ "shd_list_inventory_labels",
+ "shd_list_inventory_locations",
+ "shd_list_inventory_lots",
+ "shd_list_inventory_movements",
+ "shd_list_inventory_procurement",
+ "shd_list_inventory_procurement_shipments",
+ "shd_list_inventory_public_links",
+ "shd_list_inventory_receipts",
+ "shd_list_inventory_reservations",
+ "shd_list_inventory_stocktakes",
+ "shd_list_note_attachments",
+ "shd_list_note_collections",
+ "shd_list_note_databases",
+ "shd_list_note_member_candidates",
+ "shd_list_note_members",
+ "shd_list_note_operations",
+ "shd_list_note_pages",
+ "shd_list_note_public_links",
+ "shd_list_note_review_comments",
+ "shd_list_note_revisions",
+ "shd_list_note_spaces",
+ "shd_list_note_templates",
+ "shd_list_notification_modules",
+ "shd_list_notifications",
+ "shd_list_organization_audit",
+ "shd_list_organization_invitations",
+ "shd_list_organization_members",
+ "shd_list_projects",
+ "shd_list_proposal_template_library",
+ "shd_list_proposal_template_versions",
+ "shd_list_proposal_templates",
+ "shd_list_proposal_variants",
+ "shd_list_proposal_versions",
+ "shd_list_proposals",
+ "shd_list_scheduling_availability",
+ "shd_list_scheduling_booking_links",
+ "shd_list_scheduling_bookings",
+ "shd_list_scheduling_event_types",
+ "shd_list_scheduling_integrations",
+ "shd_list_scheduling_slots",
+ "shd_list_scheme_documents",
+ "shd_list_scheme_electrical_points",
+ "shd_list_task_activity",
+ "shd_list_task_approval_routes",
+ "shd_list_task_attachment_annotations",
+ "shd_list_task_attachments",
+ "shd_list_task_audit",
+ "shd_list_task_automation_bundles",
+ "shd_list_task_automation_logs",
+ "shd_list_task_automation_rules",
+ "shd_list_task_automation_templates",
+ "shd_list_task_checklists",
+ "shd_list_task_comments",
+ "shd_list_task_dependencies",
+ "shd_list_task_form_submissions",
+ "shd_list_task_forms",
+ "shd_list_task_goals",
+ "shd_list_task_portfolio_automation_logs",
+ "shd_list_task_portfolio_automation_rules",
+ "shd_list_task_portfolio_members",
+ "shd_list_task_portfolio_status_updates",
+ "shd_list_task_portfolios",
+ "shd_list_task_project_announcements",
+ "shd_list_task_project_members",
+ "shd_list_task_project_status_updates",
+ "shd_list_task_projects",
+ "shd_list_task_templates",
+ "shd_list_task_time_entries",
+ "shd_list_task_timesheets",
+ "shd_list_task_view_shares",
+ "shd_list_tasks",
+ "shd_list_terms_document_log",
+ "shd_list_terms_document_ops",
+ "shd_list_terms_document_revisions",
+ "shd_list_terms_documents",
+ "shd_mark_all_notifications_read",
+ "shd_mark_crm_lead_lost",
+ "shd_mark_notification_read",
+ "shd_mark_notifications_read",
+ "shd_move_crm_deal_stage",
+ "shd_move_discussion_message",
+ "shd_move_inventory_stock",
+ "shd_move_note_collection",
+ "shd_move_task",
+ "shd_mutate_scheme_point",
+ "shd_note_page_action",
+ "shd_pause_task_timer",
+ "shd_pin_discussion_message",
+ "shd_preview_finance_import",
+ "shd_preview_project_db_csv_import",
+ "shd_preview_proposal_template",
+ "shd_preview_task_automation_rule",
+ "shd_preview_task_portfolio_automation_rule",
+ "shd_project_base_access_settings",
+ "shd_project_base_access_settings_update",
+ "shd_project_base_archive",
+ "shd_project_base_attach",
+ "shd_project_base_catalog",
+ "shd_project_base_create",
+ "shd_project_base_delete",
+ "shd_project_base_detach",
+ "shd_project_base_invite",
+ "shd_project_base_invite_revoke",
+ "shd_project_base_invites",
+ "shd_project_base_member_grant",
+ "shd_project_base_member_revoke",
+ "shd_project_base_member_update",
+ "shd_project_base_members",
+ "shd_project_base_metadata",
+ "shd_project_base_owner_update",
+ "shd_project_base_provisioning_retry",
+ "shd_project_base_provisioning_status",
+ "shd_project_base_public_link",
+ "shd_project_base_public_link_get",
+ "shd_project_base_public_link_revoke",
+ "shd_project_base_restore",
+ "shd_project_base_update",
+ "shd_project_db_action",
+ "shd_project_db_action_schema",
+ "shd_project_db_batch_rollback",
+ "shd_project_db_bulk_create_records",
+ "shd_project_db_bulk_upsert_records",
+ "shd_project_db_create_record",
+ "shd_project_db_delete_record",
+ "shd_project_db_import_csv",
+ "shd_project_db_list_attachments",
+ "shd_project_db_record_history",
+ "shd_project_db_records",
+ "shd_project_db_remove_attachment",
+ "shd_project_db_resolve_linked_records",
+ "shd_project_db_restore_record_version",
+ "shd_project_db_schema",
+ "shd_project_db_tables",
+ "shd_project_db_update_record",
+ "shd_project_db_upload_attachment",
+ "shd_project_db_validate_records",
+ "shd_proposal_template_version_workflow",
+ "shd_proposal_template_workflow",
+ "shd_proposal_workflow",
+ "shd_publish_discussion_note",
+ "shd_publish_document_public_link",
+ "shd_publish_proposal",
+ "shd_publish_scheme_point_discussion_note",
+ "shd_publish_status_page_incident",
+ "shd_publish_task_form",
+ "shd_react_to_discussion_message",
+ "shd_read_note_document",
+ "shd_reassign_task_resource",
+ "shd_reboot_agent",
+ "shd_receive_inventory_items",
+ "shd_receive_inventory_stock",
+ "shd_receive_procurement_shipment",
+ "shd_release_inventory_reservation",
+ "shd_release_inventory_stock",
+ "shd_release_scheduling_slot_hold",
+ "shd_remove_finance_payment_allocation",
+ "shd_remove_organization_member",
+ "shd_remove_task_project_member",
+ "shd_rename_scheme_document",
+ "shd_render_acl_matrix_widget",
+ "shd_render_activity_widget",
+ "shd_render_agents_health_widget",
+ "shd_render_agents_widget",
+ "shd_render_crm_funnel_widget",
+ "shd_render_crm_widget",
+ "shd_render_discussions_widget",
+ "shd_render_documents_completeness_widget",
+ "shd_render_documents_widget",
+ "shd_render_files_widget",
+ "shd_render_finance_dashboard_widget",
+ "shd_render_finance_widget",
+ "shd_render_gitea_board_widget",
+ "shd_render_gitea_widget",
+ "shd_render_inventory_warnings_widget",
+ "shd_render_inventory_widget",
+ "shd_render_notes_tree_widget",
+ "shd_render_notes_widget",
+ "shd_render_notifications_widget",
+ "shd_render_organizations_widget",
+ "shd_render_project_db_preview_widget",
+ "shd_render_project_db_widget",
+ "shd_render_project_overview_widget",
+ "shd_render_project_timeline_widget",
+ "shd_render_projects_widget",
+ "shd_render_proposal_approvals_widget",
+ "shd_render_proposals_widget",
+ "shd_render_schedule_calendar_widget",
+ "shd_render_scheduling_widget",
+ "shd_render_schemes_progress_widget",
+ "shd_render_schemes_widget",
+ "shd_render_status_page_widget",
+ "shd_render_task_kanban_widget",
+ "shd_render_tasks_widget",
+ "shd_render_team_workload_widget",
+ "shd_render_terms_widget",
+ "shd_replace_file",
+ "shd_replace_note_document",
+ "shd_replace_proposal_items",
+ "shd_request_proposal_approval",
+ "shd_request_task_approval",
+ "shd_reschedule_scheduling_booking",
+ "shd_resend_organization_invitation",
+ "shd_reserve_inventory_items",
+ "shd_reserve_inventory_stock",
+ "shd_resolve_discussion_topic",
+ "shd_resolve_document_comment",
+ "shd_resolve_scheme_description_comment",
+ "shd_resolve_scheme_point_discussion",
+ "shd_resolve_task_approval",
+ "shd_resolve_task_attachment_annotation",
+ "shd_restart_homekit",
+ "shd_restore_discussion_channel",
+ "shd_restore_discussion_topic",
+ "shd_restore_file_version",
+ "shd_restore_note_revision",
+ "shd_restore_organization",
+ "shd_restore_proposal_version",
+ "shd_restore_terms_document_revision",
+ "shd_restore_terms_version",
+ "shd_retry_finance_import",
+ "shd_retry_task_automation_log",
+ "shd_retry_task_form_submission",
+ "shd_retry_task_portfolio_automation_log",
+ "shd_return_inventory_asset",
+ "shd_review_task_timesheet",
+ "shd_revoke_document_public_link",
+ "shd_revoke_note_member",
+ "shd_revoke_proposal_public_link",
+ "shd_revoke_task_form",
+ "shd_run_task_automation_rule",
+ "shd_run_task_portfolio_automation_rule",
+ "shd_save_alice_selected_devices",
+ "shd_save_crm_entity",
+ "shd_save_discussion_topic_draft",
+ "shd_save_document_contract",
+ "shd_save_exchange_rate",
+ "shd_save_finance_account",
+ "shd_save_finance_category",
+ "shd_save_finance_counterparty",
+ "shd_save_finance_document",
+ "shd_save_finance_legal_entity",
+ "shd_save_finance_payment",
+ "shd_save_finance_project",
+ "shd_save_homekit_selected_devices",
+ "shd_save_proposal_template",
+ "shd_save_proposal_template_library_item",
+ "shd_save_scheme_description_template",
+ "shd_save_scheme_point_discussion",
+ "shd_save_scheme_state",
+ "shd_save_task_import_template",
+ "shd_save_voice_agent_config",
+ "shd_schedule_discussion_message",
+ "shd_search",
+ "shd_search_discussions",
+ "shd_search_note_blocks",
+ "shd_search_notes",
+ "shd_send_document",
+ "shd_send_proposal",
+ "shd_set_discussion_message_reminder",
+ "shd_set_note_review_comment_status",
+ "shd_set_project_archived",
+ "shd_set_scheduling_availability_active",
+ "shd_set_scheduling_availability_paused",
+ "shd_set_scheduling_event_type_active",
+ "shd_star_discussion_message",
+ "shd_start_finance_import",
+ "shd_start_realtime_session",
+ "shd_start_task_timer",
+ "shd_stop_task_timer",
+ "shd_stream_file",
+ "shd_submit_task_form",
+ "shd_submit_task_timesheet",
+ "shd_sync_alice_devices",
+ "shd_sync_homekit",
+ "shd_sync_task_portfolio_projects",
+ "shd_sync_voice_agent_config",
+ "shd_system_db_delete_record",
+ "shd_system_db_record",
+ "shd_system_db_records",
+ "shd_system_db_schema",
+ "shd_system_db_update_cell",
+ "shd_task_action",
+ "shd_terminate_realtime_session",
+ "shd_terms_description_comment",
+ "shd_terms_document_action",
+ "shd_terms_point_discussion",
+ "shd_test_controller_connection",
+ "shd_test_voice_agent_rule",
+ "shd_unhide_discussion_channel",
+ "shd_unlink_crm_entities",
+ "shd_unlink_current_user_oidc",
+ "shd_unpin_discussion_message",
+ "shd_update_agent",
+ "shd_update_agent_notifications",
+ "shd_update_controller",
+ "shd_update_crm_activity",
+ "shd_update_crm_lead",
+ "shd_update_crm_note",
+ "shd_update_crm_reminder",
+ "shd_update_current_user",
+ "shd_update_discussion_channel_state",
+ "shd_update_discussion_members",
+ "shd_update_discussion_message",
+ "shd_update_discussion_topic",
+ "shd_update_document_comment",
+ "shd_update_document_template",
+ "shd_update_finance_document_item",
+ "shd_update_finance_public_link_settings",
+ "shd_update_gitea_issue_labels",
+ "shd_update_grafana_settings",
+ "shd_update_inventory_public_link",
+ "shd_update_inventory_resource",
+ "shd_update_note_collection",
+ "shd_update_note_database",
+ "shd_update_note_database_property",
+ "shd_update_note_database_record",
+ "shd_update_note_database_view",
+ "shd_update_note_page",
+ "shd_update_note_space",
+ "shd_update_note_space_presence",
+ "shd_update_notification_preferences",
+ "shd_update_organization",
+ "shd_update_organization_member",
+ "shd_update_organization_two_factor_policy",
+ "shd_update_project",
+ "shd_update_project_device",
+ "shd_update_project_service",
+ "shd_update_project_settings",
+ "shd_update_proposal",
+ "shd_update_proposal_access_settings",
+ "shd_update_proposal_notification_settings",
+ "shd_update_scheduled_discussion_message",
+ "shd_update_scheduling_availability_rule",
+ "shd_update_scheduling_booking",
+ "shd_update_scheduling_event_type",
+ "shd_update_scheduling_settings",
+ "shd_update_scheme_description_comment",
+ "shd_update_status_page_group",
+ "shd_update_status_page_monitor",
+ "shd_update_task",
+ "shd_update_task_attachment_annotation",
+ "shd_update_task_automation_rule",
+ "shd_update_task_checklist_item",
+ "shd_update_task_custom_field",
+ "shd_update_task_form",
+ "shd_update_task_goal",
+ "shd_update_task_portfolio",
+ "shd_update_task_portfolio_automation_rule",
+ "shd_update_task_portfolio_member",
+ "shd_update_task_portfolio_workload_settings",
+ "shd_update_task_project_member",
+ "shd_update_task_project_presence",
+ "shd_update_task_project_settings",
+ "shd_update_task_project_workload_settings",
+ "shd_update_task_sprint",
+ "shd_update_task_status",
+ "shd_update_task_status_definition",
+ "shd_update_task_view",
+ "shd_update_terms_document",
+ "shd_update_terms_point",
+ "shd_update_terms_room",
+ "shd_upload_discussion_attachment",
+ "shd_upload_file",
+ "shd_upload_finance_document_attachment",
+ "shd_upload_gitea_issue_attachment",
+ "shd_upload_note_attachment",
+ "shd_upload_proposal_template_logo",
+ "shd_upload_task_attachment",
+ "shd_validate_terms_document",
+ "shd_write_off_inventory_items",
+ "shd_write_off_inventory_stock"
+ ]
+}
diff --git a/plugins/shd-mcp-plugin/README.md b/plugins/shd-mcp-plugin/README.md
index c95a641..73a4cf7 100644
--- a/plugins/shd-mcp-plugin/README.md
+++ b/plugins/shd-mcp-plugin/README.md
@@ -33,16 +33,23 @@ modules. Skills do not grant permissions or bypass server-side ACLs.
- linked Gitea issues, labels, comments and attachments;
- safe bulk-change planning and validation rules.
-When the connected MCP host supports MCP Apps UI, the active-projects workflow
-also has an inline widget: it sorts by the nearest completion date, filters by
-name/code, shows status pills and loads one project’s read-only details. The
-same tools still return normal structured data for hosts that do not render
+When the connected MCP host supports MCP Apps UI, the 36 SHD render tools have
+inline read-only widgets: active projects, module registers and specialized
+Kanban, workload, timeline, funnel, dashboard, calendar, matrix, tree and
+Project DB views. Each widget sorts or filters normalized records, shows
+status/value fields and can load one selected record’s details where supported.
+The same tools still return normal structured data for hosts that do not render
widgets.
The active-projects widget is versioned in `widgets/active-projects/v1/` with a
manifest, SHA256 checksum and source/provenance note. The SHD MCP backend reads
that artifact for the `ui://shd/active-projects/v1.html` resource.
+The other versioned resources are stored under `widgets/` with a manifest,
+SHA256 checksum and source/provenance note for each resource. Their render
+tools are deliberately separate from the list tools so the server can keep
+data access and UI rendering auditable.
+
## MCP connection
The package points to `https://shd.xyz.su/mcp` and requests OAuth for that MCP
diff --git a/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/SHA256SUMS
new file mode 100644
index 0000000..6044833
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/SHA256SUMS
@@ -0,0 +1 @@
+806f28ac654a7504ae5a258add4c03114dfc9fc80328d479e23b09be92c7a74d index.html
diff --git a/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/UPSTREAM.md
new file mode 100644
index 0000000..f91d1f0
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# ACL matrix widget
+
+This artifact is served by the SHD MCP backend as ui://shd/acl-matrix/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides a read-only organization membership and permission matrix.
diff --git a/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/index.html b/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/index.html
new file mode 100644
index 0000000..3e1f4ba
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/index.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/manifest.json
new file mode 100644
index 0000000..4c440a7
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-acl-matrix",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 48773,
+ "gzipBytes": 13973,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/acl-matrix/v1.html",
+ "sha256": "806f28ac654a7504ae5a258add4c03114dfc9fc80328d479e23b09be92c7a74d"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/acl-matrix/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/active-projects/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/active-projects/v1/SHA256SUMS
index b72c7fd..24355c2 100644
--- a/plugins/shd-mcp-plugin/widgets/active-projects/v1/SHA256SUMS
+++ b/plugins/shd-mcp-plugin/widgets/active-projects/v1/SHA256SUMS
@@ -1 +1 @@
-49b3ab8629540f2c1075c3e096e2990055ec56181e6dd02dcd998bc98d9c7069 index.html
+f5338c9d833ea57be5823d0f302e00ad8dc85ce5645681e71fdad134d6465ba1 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/active-projects/v1/index.html b/plugins/shd-mcp-plugin/widgets/active-projects/v1/index.html
index b4d0af4..ec7d687 100644
--- a/plugins/shd-mcp-plugin/widgets/active-projects/v1/index.html
+++ b/plugins/shd-mcp-plugin/widgets/active-projects/v1/index.html
@@ -7,40 +7,40 @@
:root {
color-scheme: light dark;
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
- --bg: #ffffff;
- --surface: #f6f8fb;
- --surface-hover: #eef3f9;
- --border: #d9e1ec;
- --text: #152235;
- --muted: #63728a;
- --accent: #1769e0;
- --accent-soft: #e7f0ff;
+ --bg: #f8fafc;
+ --surface: #e8edf2;
+ --surface-hover: #e1e8ef;
+ --border: rgba(31, 41, 55, .16);
+ --text: rgb(29, 31, 37);
+ --muted: rgb(97, 102, 112);
+ --accent: rgb(83, 89, 101);
+ --accent-soft: rgba(75, 85, 99, .12);
--success: #16794b;
--success-soft: #e6f7ef;
--warning: #9a6100;
--warning-soft: #fff4d8;
--danger: #b42318;
--danger-soft: #ffebe9;
- --shadow: 0 8px 24px rgba(25, 55, 95, .08);
+ --shadow: 0 0 0 1px rgba(15, 23, 42, .07), 0 8px 22px rgba(15, 23, 42, .11);
}
@media (prefers-color-scheme: dark) {
:root {
- --bg: #172131;
- --surface: #202c3e;
- --surface-hover: #29384c;
- --border: #39495f;
- --text: #eef4fc;
- --muted: #a8b6c9;
- --accent: #75a9ff;
- --accent-soft: #263f68;
+ --bg: #202020;
+ --surface: #292929;
+ --surface-hover: #303336;
+ --border: #43474c;
+ --text: #eaecf0;
+ --muted: #96999d;
+ --accent: #c7b07a;
+ --accent-soft: rgba(199, 176, 122, .18);
--success: #70d4a4;
--success-soft: #173d31;
--warning: #f4c467;
--warning-soft: #4b3918;
--danger: #ff9b91;
--danger-soft: #512522;
- --shadow: 0 8px 24px rgba(0, 0, 0, .22);
+ --shadow: 0 10px 26px rgba(0, 0, 0, .34);
}
}
diff --git a/plugins/shd-mcp-plugin/widgets/active-projects/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/active-projects/v1/manifest.json
index d9df018..d7ce7fa 100644
--- a/plugins/shd-mcp-plugin/widgets/active-projects/v1/manifest.json
+++ b/plugins/shd-mcp-plugin/widgets/active-projects/v1/manifest.json
@@ -5,11 +5,11 @@
"resources": [
{
"file": "index.html",
- "bytes": 22732,
- "gzipBytes": 6133,
+ "bytes": 22838,
+ "gzipBytes": 6186,
"mediaType": "text/html;profile=mcp-app",
"uri": "ui://shd/active-projects/v1.html",
- "sha256": "49b3ab8629540f2c1075c3e096e2990055ec56181e6dd02dcd998bc98d9c7069"
+ "sha256": "f5338c9d833ea57be5823d0f302e00ad8dc85ce5645681e71fdad134d6465ba1"
}
],
"license": "../../../../../LICENSE",
diff --git a/plugins/shd-mcp-plugin/widgets/activity/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/activity/v1/SHA256SUMS
new file mode 100644
index 0000000..6c549d3
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/activity/v1/SHA256SUMS
@@ -0,0 +1 @@
+3af72830f40d1cb3e10194f875c6e403bf5f112151399e623c858981dfcaab5b index.html
diff --git a/plugins/shd-mcp-plugin/widgets/activity/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/activity/v1/UPSTREAM.md
new file mode 100644
index 0000000..dd0e90f
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/activity/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Activity widget
+
+This artifact is served by the SHD MCP backend as ui://shd/activity/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides Authenticated realtime activity stream.
diff --git a/plugins/shd-mcp-plugin/widgets/activity/v1/index.html b/plugins/shd-mcp-plugin/widgets/activity/v1/index.html
new file mode 100644
index 0000000..537e772
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/activity/v1/index.html
@@ -0,0 +1,107 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/activity/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/activity/v1/manifest.json
new file mode 100644
index 0000000..c82e75d
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/activity/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-activity",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 25600,
+ "gzipBytes": 8709,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/activity/v1.html",
+ "sha256": "3af72830f40d1cb3e10194f875c6e403bf5f112151399e623c858981dfcaab5b"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/activity/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/agents-health/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/agents-health/v1/SHA256SUMS
new file mode 100644
index 0000000..a01e34a
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/agents-health/v1/SHA256SUMS
@@ -0,0 +1 @@
+2795c7d06cbcc95984f34ef5f0c802b4653ec4af9239d07337ba20e795017bc0 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/agents-health/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/agents-health/v1/UPSTREAM.md
new file mode 100644
index 0000000..7e43934
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/agents-health/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Agents health widget
+
+This artifact is served by the SHD MCP backend as ui://shd/agents-health/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides a read-only agent and controller health overview.
diff --git a/plugins/shd-mcp-plugin/widgets/agents-health/v1/index.html b/plugins/shd-mcp-plugin/widgets/agents-health/v1/index.html
new file mode 100644
index 0000000..18953be
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/agents-health/v1/index.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/agents-health/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/agents-health/v1/manifest.json
new file mode 100644
index 0000000..ef67124
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/agents-health/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-agents-health",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 48779,
+ "gzipBytes": 13974,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/agents-health/v1.html",
+ "sha256": "2795c7d06cbcc95984f34ef5f0c802b4653ec4af9239d07337ba20e795017bc0"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/agents-health/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/agents/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/agents/v1/SHA256SUMS
new file mode 100644
index 0000000..2ff0e3f
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/agents/v1/SHA256SUMS
@@ -0,0 +1 @@
+f1576f8f4653c7178b17545c136eb3609099ebd4c581ddbff5fe52331a7b71f0 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/agents/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/agents/v1/UPSTREAM.md
new file mode 100644
index 0000000..5748801
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/agents/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Agents widget
+
+This artifact is served by the SHD MCP backend as `ui://shd/agents/v1.html`.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps `window.openai` as a compatibility extension. It has no external script or network dependency. The widget provides agents and controllers with read-only status context.
diff --git a/plugins/shd-mcp-plugin/widgets/agents/v1/index.html b/plugins/shd-mcp-plugin/widgets/agents/v1/index.html
new file mode 100644
index 0000000..cde519f
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/agents/v1/index.html
@@ -0,0 +1,91 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/agents/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/agents/v1/manifest.json
new file mode 100644
index 0000000..c7507ff
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/agents/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-agents",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 21061,
+ "gzipBytes": 7411,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/agents/v1.html",
+ "sha256": "f1576f8f4653c7178b17545c136eb3609099ebd4c581ddbff5fe52331a7b71f0"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/agents/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/crm-funnel/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/crm-funnel/v1/SHA256SUMS
new file mode 100644
index 0000000..00551fb
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/crm-funnel/v1/SHA256SUMS
@@ -0,0 +1 @@
+8c7aab8e966bcb14f48ba6a24993654b5083c0b85f9898aec6d4d478c56b0c22 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/crm-funnel/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/crm-funnel/v1/UPSTREAM.md
new file mode 100644
index 0000000..156842d
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/crm-funnel/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# CRM funnel widget
+
+This artifact is served by the SHD MCP backend as ui://shd/crm-funnel/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides a read-only CRM deal funnel grouped by stage.
diff --git a/plugins/shd-mcp-plugin/widgets/crm-funnel/v1/index.html b/plugins/shd-mcp-plugin/widgets/crm-funnel/v1/index.html
new file mode 100644
index 0000000..2314f2f
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/crm-funnel/v1/index.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/crm-funnel/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/crm-funnel/v1/manifest.json
new file mode 100644
index 0000000..d101305
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/crm-funnel/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-crm-funnel",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 48773,
+ "gzipBytes": 13974,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/crm-funnel/v1.html",
+ "sha256": "8c7aab8e966bcb14f48ba6a24993654b5083c0b85f9898aec6d4d478c56b0c22"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/crm-funnel/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/crm/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/crm/v1/SHA256SUMS
new file mode 100644
index 0000000..947b7b7
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/crm/v1/SHA256SUMS
@@ -0,0 +1 @@
+64f552a54e178e55d0102a050d001751051ae4d2c50370dbdd24201263499603 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/crm/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/crm/v1/UPSTREAM.md
new file mode 100644
index 0000000..11c6945
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/crm/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# CRM widget
+
+This artifact is served by the SHD MCP backend as `ui://shd/crm/v1.html`.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps `window.openai` as a compatibility extension. It has no external script or network dependency.
diff --git a/plugins/shd-mcp-plugin/widgets/crm/v1/index.html b/plugins/shd-mcp-plugin/widgets/crm/v1/index.html
new file mode 100644
index 0000000..75341b1
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/crm/v1/index.html
@@ -0,0 +1,282 @@
+
+
+
+
+
+ CRM — SHD MCP
+
+
+
+
+
+
+
+
+
+
+
+
+ | Сущность | Статус | Обновлено | Тип |
+
+
+
Нет данных для отображения.
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/crm/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/crm/v1/manifest.json
new file mode 100644
index 0000000..ef20895
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/crm/v1/manifest.json
@@ -0,0 +1,19 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-crm",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "uri": "ui://shd/crm/v1.html",
+ "mediaType": "text/html;profile=mcp-app",
+ "bytes": 15485,
+ "sha256": "64f552a54e178e55d0102a050d001751051ae4d2c50370dbdd24201263499603"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/crm/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/discussions/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/discussions/v1/SHA256SUMS
new file mode 100644
index 0000000..472987c
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/discussions/v1/SHA256SUMS
@@ -0,0 +1 @@
+c9ae4958b7c0f9dc1e872811e310809b51e614ace2850e8558d6c240e612e3c0 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/discussions/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/discussions/v1/UPSTREAM.md
new file mode 100644
index 0000000..ff8125c
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/discussions/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Discussions widget
+
+This artifact is served by the SHD MCP backend as `ui://shd/discussions/v1.html`.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps `window.openai` as a compatibility extension. It has no external script or network dependency. The widget provides topics and read-only message details.
diff --git a/plugins/shd-mcp-plugin/widgets/discussions/v1/index.html b/plugins/shd-mcp-plugin/widgets/discussions/v1/index.html
new file mode 100644
index 0000000..4302107
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/discussions/v1/index.html
@@ -0,0 +1,91 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/discussions/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/discussions/v1/manifest.json
new file mode 100644
index 0000000..ecf6690
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/discussions/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-discussions",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 21071,
+ "gzipBytes": 7411,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/discussions/v1.html",
+ "sha256": "c9ae4958b7c0f9dc1e872811e310809b51e614ace2850e8558d6c240e612e3c0"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/discussions/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/documents-completeness/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/documents-completeness/v1/SHA256SUMS
new file mode 100644
index 0000000..b69e1c3
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/documents-completeness/v1/SHA256SUMS
@@ -0,0 +1 @@
+553db1686496a3fa6e2097924cb33db72ca24f0a68a4a8454cad2e14ad0ea960 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/documents-completeness/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/documents-completeness/v1/UPSTREAM.md
new file mode 100644
index 0000000..3e97ce2
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/documents-completeness/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Documents completeness widget
+
+This artifact is served by the SHD MCP backend as ui://shd/documents-completeness/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides a read-only Terms and document completeness dashboard.
diff --git a/plugins/shd-mcp-plugin/widgets/documents-completeness/v1/index.html b/plugins/shd-mcp-plugin/widgets/documents-completeness/v1/index.html
new file mode 100644
index 0000000..ec085c1
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/documents-completeness/v1/index.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/documents-completeness/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/documents-completeness/v1/manifest.json
new file mode 100644
index 0000000..a25aa71
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/documents-completeness/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-documents-completeness",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 48797,
+ "gzipBytes": 13975,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/documents-completeness/v1.html",
+ "sha256": "553db1686496a3fa6e2097924cb33db72ca24f0a68a4a8454cad2e14ad0ea960"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/documents-completeness/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/documents/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/documents/v1/SHA256SUMS
new file mode 100644
index 0000000..8be6430
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/documents/v1/SHA256SUMS
@@ -0,0 +1 @@
+5959d58c47ab81813202df203cf69a568a646d61884e64802e113e752229d925 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/documents/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/documents/v1/UPSTREAM.md
new file mode 100644
index 0000000..9093716
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/documents/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Документы widget
+
+This artifact is served by the SHD MCP backend as `ui://shd/documents/v1.html`.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps `window.openai` as a compatibility extension. It has no external script or network dependency.
diff --git a/plugins/shd-mcp-plugin/widgets/documents/v1/index.html b/plugins/shd-mcp-plugin/widgets/documents/v1/index.html
new file mode 100644
index 0000000..f8268ee
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/documents/v1/index.html
@@ -0,0 +1,282 @@
+
+
+
+
+
+ Документы — SHD MCP
+
+
+
+
+
+
+
+
+
+
+
+
+ | Документ | Статус | Обновлено | Сумма |
+
+
+
Нет данных для отображения.
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/documents/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/documents/v1/manifest.json
new file mode 100644
index 0000000..591640a
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/documents/v1/manifest.json
@@ -0,0 +1,19 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-documents",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "uri": "ui://shd/documents/v1.html",
+ "mediaType": "text/html;profile=mcp-app",
+ "bytes": 15510,
+ "sha256": "5959d58c47ab81813202df203cf69a568a646d61884e64802e113e752229d925"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/documents/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/files/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/files/v1/SHA256SUMS
new file mode 100644
index 0000000..56f90a9
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/files/v1/SHA256SUMS
@@ -0,0 +1 @@
+09c6eed7f36baf0b214e1c9252de4f239405ae86673d06c31f6b5f66913f4144 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/files/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/files/v1/UPSTREAM.md
new file mode 100644
index 0000000..d899de0
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/files/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Files widget
+
+This artifact is served by the SHD MCP backend as ui://shd/files/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides Project file register with safe read-only links.
diff --git a/plugins/shd-mcp-plugin/widgets/files/v1/index.html b/plugins/shd-mcp-plugin/widgets/files/v1/index.html
new file mode 100644
index 0000000..3ee08fb
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/files/v1/index.html
@@ -0,0 +1,107 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/files/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/files/v1/manifest.json
new file mode 100644
index 0000000..87a3500
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/files/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-files",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 25597,
+ "gzipBytes": 8708,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/files/v1.html",
+ "sha256": "09c6eed7f36baf0b214e1c9252de4f239405ae86673d06c31f6b5f66913f4144"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/files/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/finance-dashboard/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/finance-dashboard/v1/SHA256SUMS
new file mode 100644
index 0000000..7d83c14
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/finance-dashboard/v1/SHA256SUMS
@@ -0,0 +1 @@
+7e849281109ad6b9015673083b76ce73fe72b0409eded0ab381b4e48a52170b1 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/finance-dashboard/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/finance-dashboard/v1/UPSTREAM.md
new file mode 100644
index 0000000..bca4c01
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/finance-dashboard/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Finance dashboard widget
+
+This artifact is served by the SHD MCP backend as ui://shd/finance-dashboard/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides a read-only finance totals, statuses and records.
diff --git a/plugins/shd-mcp-plugin/widgets/finance-dashboard/v1/index.html b/plugins/shd-mcp-plugin/widgets/finance-dashboard/v1/index.html
new file mode 100644
index 0000000..4127fa6
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/finance-dashboard/v1/index.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/finance-dashboard/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/finance-dashboard/v1/manifest.json
new file mode 100644
index 0000000..9f3dd9e
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/finance-dashboard/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-finance-dashboard",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 48787,
+ "gzipBytes": 13972,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/finance-dashboard/v1.html",
+ "sha256": "7e849281109ad6b9015673083b76ce73fe72b0409eded0ab381b4e48a52170b1"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/finance-dashboard/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/finance/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/finance/v1/SHA256SUMS
new file mode 100644
index 0000000..ff8e40f
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/finance/v1/SHA256SUMS
@@ -0,0 +1 @@
+86a8d3275d1fdfaa6bbf5d1ab308b3e19a0b153897f614edd2c23d260030094e index.html
diff --git a/plugins/shd-mcp-plugin/widgets/finance/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/finance/v1/UPSTREAM.md
new file mode 100644
index 0000000..893a3f9
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/finance/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Финансы widget
+
+This artifact is served by the SHD MCP backend as `ui://shd/finance/v1.html`.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps `window.openai` as a compatibility extension. It has no external script or network dependency.
diff --git a/plugins/shd-mcp-plugin/widgets/finance/v1/index.html b/plugins/shd-mcp-plugin/widgets/finance/v1/index.html
new file mode 100644
index 0000000..e8da72f
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/finance/v1/index.html
@@ -0,0 +1,282 @@
+
+
+
+
+
+ Финансы — SHD MCP
+
+
+
+
+
+
+
+
+
+
+
+
+ | Документ | Статус | Срок | Сумма |
+
+
+
Нет данных для отображения.
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/finance/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/finance/v1/manifest.json
new file mode 100644
index 0000000..0cde08c
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/finance/v1/manifest.json
@@ -0,0 +1,19 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-finance",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "uri": "ui://shd/finance/v1.html",
+ "mediaType": "text/html;profile=mcp-app",
+ "bytes": 15532,
+ "sha256": "86a8d3275d1fdfaa6bbf5d1ab308b3e19a0b153897f614edd2c23d260030094e"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/finance/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/gitea-board/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/gitea-board/v1/SHA256SUMS
new file mode 100644
index 0000000..3b8a17b
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/gitea-board/v1/SHA256SUMS
@@ -0,0 +1 @@
+e68a43f81a322387f71b947124d40a108881f9204600758a0db4ac374d3e3e04 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/gitea-board/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/gitea-board/v1/UPSTREAM.md
new file mode 100644
index 0000000..5f3100c
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/gitea-board/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Gitea board widget
+
+This artifact is served by the SHD MCP backend as ui://shd/gitea-board/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides a read-only Gitea issues grouped by state.
diff --git a/plugins/shd-mcp-plugin/widgets/gitea-board/v1/index.html b/plugins/shd-mcp-plugin/widgets/gitea-board/v1/index.html
new file mode 100644
index 0000000..50abe3f
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/gitea-board/v1/index.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/gitea-board/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/gitea-board/v1/manifest.json
new file mode 100644
index 0000000..8060259
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/gitea-board/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-gitea-board",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 48775,
+ "gzipBytes": 13972,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/gitea-board/v1.html",
+ "sha256": "e68a43f81a322387f71b947124d40a108881f9204600758a0db4ac374d3e3e04"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/gitea-board/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/gitea/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/gitea/v1/SHA256SUMS
new file mode 100644
index 0000000..82d1433
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/gitea/v1/SHA256SUMS
@@ -0,0 +1 @@
+08a381ad106c5fa60d3c5c17c08949cd69f139c6fb5094251fa107f7c8bbaeb4 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/gitea/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/gitea/v1/UPSTREAM.md
new file mode 100644
index 0000000..5f4c2e9
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/gitea/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Gitea Issues widget
+
+This artifact is served by the SHD MCP backend as ui://shd/gitea/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides Read-only issue register for allowed targets.
diff --git a/plugins/shd-mcp-plugin/widgets/gitea/v1/index.html b/plugins/shd-mcp-plugin/widgets/gitea/v1/index.html
new file mode 100644
index 0000000..e0ba081
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/gitea/v1/index.html
@@ -0,0 +1,107 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/gitea/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/gitea/v1/manifest.json
new file mode 100644
index 0000000..053a603
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/gitea/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-gitea",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 25597,
+ "gzipBytes": 8708,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/gitea/v1.html",
+ "sha256": "08a381ad106c5fa60d3c5c17c08949cd69f139c6fb5094251fa107f7c8bbaeb4"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/gitea/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/inventory-warnings/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/inventory-warnings/v1/SHA256SUMS
new file mode 100644
index 0000000..b37bd9b
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/inventory-warnings/v1/SHA256SUMS
@@ -0,0 +1 @@
+346c27c4b13871b31b2e66116a0ca85f916127dbcb73c3f5b4c5709ec209ea81 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/inventory-warnings/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/inventory-warnings/v1/UPSTREAM.md
new file mode 100644
index 0000000..cb66efa
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/inventory-warnings/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Inventory warnings widget
+
+This artifact is served by the SHD MCP backend as ui://shd/inventory-warnings/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides a read-only low-stock and critical inventory dashboard.
diff --git a/plugins/shd-mcp-plugin/widgets/inventory-warnings/v1/index.html b/plugins/shd-mcp-plugin/widgets/inventory-warnings/v1/index.html
new file mode 100644
index 0000000..61d38a9
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/inventory-warnings/v1/index.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/inventory-warnings/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/inventory-warnings/v1/manifest.json
new file mode 100644
index 0000000..5a2597a
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/inventory-warnings/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-inventory-warnings",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 48789,
+ "gzipBytes": 13974,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/inventory-warnings/v1.html",
+ "sha256": "346c27c4b13871b31b2e66116a0ca85f916127dbcb73c3f5b4c5709ec209ea81"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/inventory-warnings/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/inventory/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/inventory/v1/SHA256SUMS
new file mode 100644
index 0000000..78f12b5
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/inventory/v1/SHA256SUMS
@@ -0,0 +1 @@
+684908987a55fd77f1b3d32dcd941b82163c03c04a48785589ccbb9ceeeb7f1f index.html
diff --git a/plugins/shd-mcp-plugin/widgets/inventory/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/inventory/v1/UPSTREAM.md
new file mode 100644
index 0000000..b57c8a4
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/inventory/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Inventory widget
+
+This artifact is served by the SHD MCP backend as `ui://shd/inventory/v1.html`.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps `window.openai` as a compatibility extension. It has no external script or network dependency. The widget provides stock quantities and read-only item details.
diff --git a/plugins/shd-mcp-plugin/widgets/inventory/v1/index.html b/plugins/shd-mcp-plugin/widgets/inventory/v1/index.html
new file mode 100644
index 0000000..6e5c3f7
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/inventory/v1/index.html
@@ -0,0 +1,91 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/inventory/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/inventory/v1/manifest.json
new file mode 100644
index 0000000..522bc55
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/inventory/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-inventory",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 21067,
+ "gzipBytes": 7411,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/inventory/v1.html",
+ "sha256": "684908987a55fd77f1b3d32dcd941b82163c03c04a48785589ccbb9ceeeb7f1f"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/inventory/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/notes-tree/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/notes-tree/v1/SHA256SUMS
new file mode 100644
index 0000000..8d5fe31
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/notes-tree/v1/SHA256SUMS
@@ -0,0 +1 @@
+00e5b692dd5d28f77ea210e6ee9f1c0ad07d68c978284f5380dc1db44f6d2107 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/notes-tree/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/notes-tree/v1/UPSTREAM.md
new file mode 100644
index 0000000..6e8414f
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/notes-tree/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Notes tree widget
+
+This artifact is served by the SHD MCP backend as ui://shd/notes-tree/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides a read-only Notes spaces and hierarchy tree.
diff --git a/plugins/shd-mcp-plugin/widgets/notes-tree/v1/index.html b/plugins/shd-mcp-plugin/widgets/notes-tree/v1/index.html
new file mode 100644
index 0000000..f00f8b3
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/notes-tree/v1/index.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/notes-tree/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/notes-tree/v1/manifest.json
new file mode 100644
index 0000000..6321471
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/notes-tree/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-notes-tree",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 48773,
+ "gzipBytes": 13976,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/notes-tree/v1.html",
+ "sha256": "00e5b692dd5d28f77ea210e6ee9f1c0ad07d68c978284f5380dc1db44f6d2107"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/notes-tree/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/notes/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/notes/v1/SHA256SUMS
new file mode 100644
index 0000000..12dfae8
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/notes/v1/SHA256SUMS
@@ -0,0 +1 @@
+3aeb485b0b27cf89fe160b6e826d83f0027c01809756ef46701668a03105d321 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/notes/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/notes/v1/UPSTREAM.md
new file mode 100644
index 0000000..d5ab9fd
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/notes/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Notes widget
+
+This artifact is served by the SHD MCP backend as `ui://shd/notes/v1.html`.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps `window.openai` as a compatibility extension. It has no external script or network dependency. The widget provides page register and read-only page details.
diff --git a/plugins/shd-mcp-plugin/widgets/notes/v1/index.html b/plugins/shd-mcp-plugin/widgets/notes/v1/index.html
new file mode 100644
index 0000000..6ecde7f
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/notes/v1/index.html
@@ -0,0 +1,91 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/notes/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/notes/v1/manifest.json
new file mode 100644
index 0000000..0cf47bd
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/notes/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-notes",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 21059,
+ "gzipBytes": 7411,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/notes/v1.html",
+ "sha256": "3aeb485b0b27cf89fe160b6e826d83f0027c01809756ef46701668a03105d321"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/notes/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/notifications/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/notifications/v1/SHA256SUMS
new file mode 100644
index 0000000..68c8e5b
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/notifications/v1/SHA256SUMS
@@ -0,0 +1 @@
+8fd7b9cdb616836d076ae8a4883d66fcd619bf3214e7891fa0fcda4411dbf3e7 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/notifications/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/notifications/v1/UPSTREAM.md
new file mode 100644
index 0000000..3fafd34
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/notifications/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Notifications widget
+
+This artifact is served by the SHD MCP backend as `ui://shd/notifications/v1.html`.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps `window.openai` as a compatibility extension. It has no external script or network dependency. The widget provides notifications and read-only event details.
diff --git a/plugins/shd-mcp-plugin/widgets/notifications/v1/index.html b/plugins/shd-mcp-plugin/widgets/notifications/v1/index.html
new file mode 100644
index 0000000..e99a797
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/notifications/v1/index.html
@@ -0,0 +1,91 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/notifications/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/notifications/v1/manifest.json
new file mode 100644
index 0000000..40e9d1b
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/notifications/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-notifications",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 21075,
+ "gzipBytes": 7410,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/notifications/v1.html",
+ "sha256": "8fd7b9cdb616836d076ae8a4883d66fcd619bf3214e7891fa0fcda4411dbf3e7"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/notifications/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/organizations/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/organizations/v1/SHA256SUMS
new file mode 100644
index 0000000..441da6f
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/organizations/v1/SHA256SUMS
@@ -0,0 +1 @@
+8059ccb18d02821666416ac717cd718479cb1a3f95baa27d1edfc19be5220c90 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/organizations/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/organizations/v1/UPSTREAM.md
new file mode 100644
index 0000000..0803058
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/organizations/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Organizations and access widget
+
+This artifact is served by the SHD MCP backend as ui://shd/organizations/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides Organization register with safe membership details.
diff --git a/plugins/shd-mcp-plugin/widgets/organizations/v1/index.html b/plugins/shd-mcp-plugin/widgets/organizations/v1/index.html
new file mode 100644
index 0000000..f1b6ce5
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/organizations/v1/index.html
@@ -0,0 +1,107 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/organizations/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/organizations/v1/manifest.json
new file mode 100644
index 0000000..7667eba
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/organizations/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-organizations",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 25605,
+ "gzipBytes": 8711,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/organizations/v1.html",
+ "sha256": "8059ccb18d02821666416ac717cd718479cb1a3f95baa27d1edfc19be5220c90"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/organizations/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/project-db-preview/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/project-db-preview/v1/SHA256SUMS
new file mode 100644
index 0000000..a1b2ff4
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/project-db-preview/v1/SHA256SUMS
@@ -0,0 +1 @@
+b114986b9c03d02c63c5bcf8c0697615f4c80fa853bc9cf0bb5f6529357d90a4 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/project-db-preview/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/project-db-preview/v1/UPSTREAM.md
new file mode 100644
index 0000000..d4bb60c
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/project-db-preview/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Project DB preview widget
+
+This artifact is served by the SHD MCP backend as ui://shd/project-db-preview/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides a read-only Project DB table record preview.
diff --git a/plugins/shd-mcp-plugin/widgets/project-db-preview/v1/index.html b/plugins/shd-mcp-plugin/widgets/project-db-preview/v1/index.html
new file mode 100644
index 0000000..696f965
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/project-db-preview/v1/index.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/project-db-preview/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/project-db-preview/v1/manifest.json
new file mode 100644
index 0000000..7cb66f3
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/project-db-preview/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-project-db-preview",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 48777,
+ "gzipBytes": 13982,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/project-db-preview/v1.html",
+ "sha256": "b114986b9c03d02c63c5bcf8c0697615f4c80fa853bc9cf0bb5f6529357d90a4"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/project-db-preview/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/project-db/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/project-db/v1/SHA256SUMS
new file mode 100644
index 0000000..4374d75
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/project-db/v1/SHA256SUMS
@@ -0,0 +1 @@
+bd34985f224325c18ae2427a49bf2355ee0d7009d47326000a10d9d7027effcb index.html
diff --git a/plugins/shd-mcp-plugin/widgets/project-db/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/project-db/v1/UPSTREAM.md
new file mode 100644
index 0000000..dc9547a
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/project-db/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Project DB widget
+
+This artifact is served by the SHD MCP backend as `ui://shd/project-db/v1.html`.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps `window.openai` as a compatibility extension. It has no external script or network dependency. The widget provides table catalog and read-only schema details.
diff --git a/plugins/shd-mcp-plugin/widgets/project-db/v1/index.html b/plugins/shd-mcp-plugin/widgets/project-db/v1/index.html
new file mode 100644
index 0000000..42a50fa
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/project-db/v1/index.html
@@ -0,0 +1,91 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/project-db/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/project-db/v1/manifest.json
new file mode 100644
index 0000000..2a8f31e
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/project-db/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-project-db",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 21069,
+ "gzipBytes": 7410,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/project-db/v1.html",
+ "sha256": "bd34985f224325c18ae2427a49bf2355ee0d7009d47326000a10d9d7027effcb"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/project-db/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/project-overview/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/project-overview/v1/SHA256SUMS
new file mode 100644
index 0000000..8196ad6
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/project-overview/v1/SHA256SUMS
@@ -0,0 +1 @@
+adf8b6f9a96bf904cadd3eee70f4f18e870ca8e0e6286d4ad0d18f04f6174452 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/project-overview/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/project-overview/v1/UPSTREAM.md
new file mode 100644
index 0000000..a69c819
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/project-overview/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Project overview widget
+
+This artifact is served by the SHD MCP backend as ui://shd/project-overview/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides Cross-module read-only project context.
diff --git a/plugins/shd-mcp-plugin/widgets/project-overview/v1/index.html b/plugins/shd-mcp-plugin/widgets/project-overview/v1/index.html
new file mode 100644
index 0000000..0526279
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/project-overview/v1/index.html
@@ -0,0 +1,107 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/project-overview/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/project-overview/v1/manifest.json
new file mode 100644
index 0000000..5dfe786
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/project-overview/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-project-overview",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 25608,
+ "gzipBytes": 8709,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/project-overview/v1.html",
+ "sha256": "adf8b6f9a96bf904cadd3eee70f4f18e870ca8e0e6286d4ad0d18f04f6174452"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/project-overview/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/project-timeline/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/project-timeline/v1/SHA256SUMS
new file mode 100644
index 0000000..b3b9c96
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/project-timeline/v1/SHA256SUMS
@@ -0,0 +1 @@
+6ab0655050f4c66631ce1a045daa3473b61f69aaafacdba7e290309c6652f7be index.html
diff --git a/plugins/shd-mcp-plugin/widgets/project-timeline/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/project-timeline/v1/UPSTREAM.md
new file mode 100644
index 0000000..459ceec
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/project-timeline/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Project timeline widget
+
+This artifact is served by the SHD MCP backend as ui://shd/project-timeline/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides a read-only chronological task timeline.
diff --git a/plugins/shd-mcp-plugin/widgets/project-timeline/v1/index.html b/plugins/shd-mcp-plugin/widgets/project-timeline/v1/index.html
new file mode 100644
index 0000000..78f3dc7
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/project-timeline/v1/index.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/project-timeline/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/project-timeline/v1/manifest.json
new file mode 100644
index 0000000..e566cf7
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/project-timeline/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-project-timeline",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 48785,
+ "gzipBytes": 13975,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/project-timeline/v1.html",
+ "sha256": "6ab0655050f4c66631ce1a045daa3473b61f69aaafacdba7e290309c6652f7be"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/project-timeline/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/proposal-approvals/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/proposal-approvals/v1/SHA256SUMS
new file mode 100644
index 0000000..ada6ceb
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/proposal-approvals/v1/SHA256SUMS
@@ -0,0 +1 @@
+118da1cb2a8b7d0f1dc1c063257e0e7d7882f79e85a54911176d0f75cbe277b1 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/proposal-approvals/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/proposal-approvals/v1/UPSTREAM.md
new file mode 100644
index 0000000..d3b34da
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/proposal-approvals/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Proposal approvals widget
+
+This artifact is served by the SHD MCP backend as ui://shd/proposal-approvals/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides a read-only proposal approval queue.
diff --git a/plugins/shd-mcp-plugin/widgets/proposal-approvals/v1/index.html b/plugins/shd-mcp-plugin/widgets/proposal-approvals/v1/index.html
new file mode 100644
index 0000000..0c99506
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/proposal-approvals/v1/index.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/proposal-approvals/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/proposal-approvals/v1/manifest.json
new file mode 100644
index 0000000..76d3c50
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/proposal-approvals/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-proposal-approvals",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 48789,
+ "gzipBytes": 13973,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/proposal-approvals/v1.html",
+ "sha256": "118da1cb2a8b7d0f1dc1c063257e0e7d7882f79e85a54911176d0f75cbe277b1"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/proposal-approvals/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/proposals/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/proposals/v1/SHA256SUMS
new file mode 100644
index 0000000..09f9ae6
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/proposals/v1/SHA256SUMS
@@ -0,0 +1 @@
+cc812d7531d1a0a512a032e8f9febbe302047daa8f45344d8e59cf46109dbec5 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/proposals/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/proposals/v1/UPSTREAM.md
new file mode 100644
index 0000000..abdb6b1
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/proposals/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Proposals widget
+
+This artifact is served by the SHD MCP backend as ui://shd/proposals/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides Proposal register with read-only details.
diff --git a/plugins/shd-mcp-plugin/widgets/proposals/v1/index.html b/plugins/shd-mcp-plugin/widgets/proposals/v1/index.html
new file mode 100644
index 0000000..080dd58
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/proposals/v1/index.html
@@ -0,0 +1,107 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/proposals/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/proposals/v1/manifest.json
new file mode 100644
index 0000000..8924af4
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/proposals/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-proposals",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 25601,
+ "gzipBytes": 8707,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/proposals/v1.html",
+ "sha256": "cc812d7531d1a0a512a032e8f9febbe302047daa8f45344d8e59cf46109dbec5"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/proposals/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/schedule-calendar/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/schedule-calendar/v1/SHA256SUMS
new file mode 100644
index 0000000..e2f80ec
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/schedule-calendar/v1/SHA256SUMS
@@ -0,0 +1 @@
+15caaf41295414b9edefad9d112341b3ab5d6172b085c4053177f855bb307e55 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/schedule-calendar/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/schedule-calendar/v1/UPSTREAM.md
new file mode 100644
index 0000000..22b28de
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/schedule-calendar/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Schedule calendar widget
+
+This artifact is served by the SHD MCP backend as ui://shd/schedule-calendar/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides a read-only bookings grouped by day.
diff --git a/plugins/shd-mcp-plugin/widgets/schedule-calendar/v1/index.html b/plugins/shd-mcp-plugin/widgets/schedule-calendar/v1/index.html
new file mode 100644
index 0000000..d3fc22b
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/schedule-calendar/v1/index.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/schedule-calendar/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/schedule-calendar/v1/manifest.json
new file mode 100644
index 0000000..1758dbb
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/schedule-calendar/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-schedule-calendar",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 48787,
+ "gzipBytes": 13973,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/schedule-calendar/v1.html",
+ "sha256": "15caaf41295414b9edefad9d112341b3ab5d6172b085c4053177f855bb307e55"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/schedule-calendar/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/scheduling/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/scheduling/v1/SHA256SUMS
new file mode 100644
index 0000000..d50371d
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/scheduling/v1/SHA256SUMS
@@ -0,0 +1 @@
+2aa242337b7a4e1976dec1b479c85ee3df718c7e3a2d98fec10b4f0c3a6f799c index.html
diff --git a/plugins/shd-mcp-plugin/widgets/scheduling/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/scheduling/v1/UPSTREAM.md
new file mode 100644
index 0000000..2518053
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/scheduling/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Scheduling widget
+
+This artifact is served by the SHD MCP backend as `ui://shd/scheduling/v1.html`.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps `window.openai` as a compatibility extension. It has no external script or network dependency. The widget provides upcoming bookings and read-only details.
diff --git a/plugins/shd-mcp-plugin/widgets/scheduling/v1/index.html b/plugins/shd-mcp-plugin/widgets/scheduling/v1/index.html
new file mode 100644
index 0000000..236c15a
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/scheduling/v1/index.html
@@ -0,0 +1,91 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/scheduling/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/scheduling/v1/manifest.json
new file mode 100644
index 0000000..5ab2f72
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/scheduling/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-scheduling",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 21069,
+ "gzipBytes": 7409,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/scheduling/v1.html",
+ "sha256": "2aa242337b7a4e1976dec1b479c85ee3df718c7e3a2d98fec10b4f0c3a6f799c"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/scheduling/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/schemes-progress/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/schemes-progress/v1/SHA256SUMS
new file mode 100644
index 0000000..6c8145e
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/schemes-progress/v1/SHA256SUMS
@@ -0,0 +1 @@
+7f3769dc8cb8c4676ca3e323f7b1a84875d8b3466d086d1eb78b52f9c4e72183 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/schemes-progress/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/schemes-progress/v1/UPSTREAM.md
new file mode 100644
index 0000000..6cd7f16
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/schemes-progress/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Schemes progress widget
+
+This artifact is served by the SHD MCP backend as ui://shd/schemes-progress/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides a read-only scheme document progress dashboard.
diff --git a/plugins/shd-mcp-plugin/widgets/schemes-progress/v1/index.html b/plugins/shd-mcp-plugin/widgets/schemes-progress/v1/index.html
new file mode 100644
index 0000000..7c6cb97
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/schemes-progress/v1/index.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/schemes-progress/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/schemes-progress/v1/manifest.json
new file mode 100644
index 0000000..9b8dcc5
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/schemes-progress/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-schemes-progress",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 48785,
+ "gzipBytes": 13976,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/schemes-progress/v1.html",
+ "sha256": "7f3769dc8cb8c4676ca3e323f7b1a84875d8b3466d086d1eb78b52f9c4e72183"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/schemes-progress/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/schemes/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/schemes/v1/SHA256SUMS
new file mode 100644
index 0000000..0dc911e
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/schemes/v1/SHA256SUMS
@@ -0,0 +1 @@
+d1ceb0813f9ef03cb19becf0bec007c423fafd06a398a2d3ea64af093f540cc4 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/schemes/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/schemes/v1/UPSTREAM.md
new file mode 100644
index 0000000..59e88db
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/schemes/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Schemes widget
+
+This artifact is served by the SHD MCP backend as ui://shd/schemes/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides PDF Scheme Editor document register.
diff --git a/plugins/shd-mcp-plugin/widgets/schemes/v1/index.html b/plugins/shd-mcp-plugin/widgets/schemes/v1/index.html
new file mode 100644
index 0000000..86c8a4f
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/schemes/v1/index.html
@@ -0,0 +1,107 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/schemes/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/schemes/v1/manifest.json
new file mode 100644
index 0000000..6252d85
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/schemes/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-schemes",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 25599,
+ "gzipBytes": 8708,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/schemes/v1.html",
+ "sha256": "d1ceb0813f9ef03cb19becf0bec007c423fafd06a398a2d3ea64af093f540cc4"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/schemes/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/status-page/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/status-page/v1/SHA256SUMS
new file mode 100644
index 0000000..9ca3884
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/status-page/v1/SHA256SUMS
@@ -0,0 +1 @@
+f26198ae7f8dc9cbb2138d58db51e0a09529e74a469eb913c722a0e569865962 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/status-page/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/status-page/v1/UPSTREAM.md
new file mode 100644
index 0000000..914a9f8
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/status-page/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Status Page widget
+
+This artifact is served by the SHD MCP backend as `ui://shd/status-page/v1.html`.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps `window.openai` as a compatibility extension. It has no external script or network dependency. The widget provides monitor availability and read-only history.
diff --git a/plugins/shd-mcp-plugin/widgets/status-page/v1/index.html b/plugins/shd-mcp-plugin/widgets/status-page/v1/index.html
new file mode 100644
index 0000000..a0c9e5c
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/status-page/v1/index.html
@@ -0,0 +1,91 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/status-page/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/status-page/v1/manifest.json
new file mode 100644
index 0000000..c6a278c
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/status-page/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-status-page",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 21071,
+ "gzipBytes": 7408,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/status-page/v1.html",
+ "sha256": "f26198ae7f8dc9cbb2138d58db51e0a09529e74a469eb913c722a0e569865962"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/status-page/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/task-kanban/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/task-kanban/v1/SHA256SUMS
new file mode 100644
index 0000000..b04fedc
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/task-kanban/v1/SHA256SUMS
@@ -0,0 +1 @@
+278e34a5a5652224fc3cb120b84d5fd719166997cb0cc78b2dc36446f8327ba7 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/task-kanban/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/task-kanban/v1/UPSTREAM.md
new file mode 100644
index 0000000..8b8bdc7
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/task-kanban/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Task Kanban widget
+
+This artifact is served by the SHD MCP backend as ui://shd/task-kanban/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides a read-only task Kanban grouped by workflow status.
diff --git a/plugins/shd-mcp-plugin/widgets/task-kanban/v1/index.html b/plugins/shd-mcp-plugin/widgets/task-kanban/v1/index.html
new file mode 100644
index 0000000..4d64d41
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/task-kanban/v1/index.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/task-kanban/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/task-kanban/v1/manifest.json
new file mode 100644
index 0000000..d9017c0
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/task-kanban/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-task-kanban",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 48775,
+ "gzipBytes": 13973,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/task-kanban/v1.html",
+ "sha256": "278e34a5a5652224fc3cb120b84d5fd719166997cb0cc78b2dc36446f8327ba7"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/task-kanban/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/tasks/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/tasks/v1/SHA256SUMS
new file mode 100644
index 0000000..d84a601
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/tasks/v1/SHA256SUMS
@@ -0,0 +1 @@
+25c7393439c388a94913500af93041637f2550d5b68022f6bf13fa19bf3223dc index.html
diff --git a/plugins/shd-mcp-plugin/widgets/tasks/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/tasks/v1/UPSTREAM.md
new file mode 100644
index 0000000..f5b4129
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/tasks/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Задачи widget
+
+This artifact is served by the SHD MCP backend as `ui://shd/tasks/v1.html`.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps `window.openai` as a compatibility extension. It has no external script or network dependency.
diff --git a/plugins/shd-mcp-plugin/widgets/tasks/v1/index.html b/plugins/shd-mcp-plugin/widgets/tasks/v1/index.html
new file mode 100644
index 0000000..136150d
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/tasks/v1/index.html
@@ -0,0 +1,282 @@
+
+
+
+
+
+ Задачи — SHD MCP
+
+
+
+
+
+
+
+
+
+
+
+
+ | Задача | Статус | Срок | Приоритет |
+
+
+
Нет данных для отображения.
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/tasks/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/tasks/v1/manifest.json
new file mode 100644
index 0000000..07ce9e3
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/tasks/v1/manifest.json
@@ -0,0 +1,19 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-tasks",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "uri": "ui://shd/tasks/v1.html",
+ "mediaType": "text/html;profile=mcp-app",
+ "bytes": 15440,
+ "sha256": "25c7393439c388a94913500af93041637f2550d5b68022f6bf13fa19bf3223dc"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/tasks/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/team-workload/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/team-workload/v1/SHA256SUMS
new file mode 100644
index 0000000..accec4f
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/team-workload/v1/SHA256SUMS
@@ -0,0 +1 @@
+0d262f0e309444eee8d2824d191b87bae7f60375e6be4f802fdf66b0cf606cef index.html
diff --git a/plugins/shd-mcp-plugin/widgets/team-workload/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/team-workload/v1/UPSTREAM.md
new file mode 100644
index 0000000..194e2bb
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/team-workload/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Team workload widget
+
+This artifact is served by the SHD MCP backend as ui://shd/team-workload/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides a read-only workload, capacity and utilization overview.
diff --git a/plugins/shd-mcp-plugin/widgets/team-workload/v1/index.html b/plugins/shd-mcp-plugin/widgets/team-workload/v1/index.html
new file mode 100644
index 0000000..cc55acb
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/team-workload/v1/index.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/team-workload/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/team-workload/v1/manifest.json
new file mode 100644
index 0000000..594af73
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/team-workload/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-team-workload",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 48779,
+ "gzipBytes": 13975,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/team-workload/v1.html",
+ "sha256": "0d262f0e309444eee8d2824d191b87bae7f60375e6be4f802fdf66b0cf606cef"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/team-workload/v1/index.html"
+ }
+}
diff --git a/plugins/shd-mcp-plugin/widgets/terms/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/terms/v1/SHA256SUMS
new file mode 100644
index 0000000..b1e794b
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/terms/v1/SHA256SUMS
@@ -0,0 +1 @@
+f7b692915628c89d91a411700525bd702f4a2bcf4db39d8afd8acc2b90692be7 index.html
diff --git a/plugins/shd-mcp-plugin/widgets/terms/v1/UPSTREAM.md b/plugins/shd-mcp-plugin/widgets/terms/v1/UPSTREAM.md
new file mode 100644
index 0000000..24c5f28
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/terms/v1/UPSTREAM.md
@@ -0,0 +1,5 @@
+# Terms / ТЗ widget
+
+This artifact is served by the SHD MCP backend as ui://shd/terms/v1.html.
+
+The HTML is standalone, uses the MCP Apps bridge first, and keeps window.openai as a compatibility extension. It has no external script or network dependency. The widget provides Terms of Reference document register.
diff --git a/plugins/shd-mcp-plugin/widgets/terms/v1/index.html b/plugins/shd-mcp-plugin/widgets/terms/v1/index.html
new file mode 100644
index 0000000..8f695fd
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/terms/v1/index.html
@@ -0,0 +1,107 @@
+
+
+
+
+
+ SHD MCP
+
+
+
+
+
+
+
diff --git a/plugins/shd-mcp-plugin/widgets/terms/v1/manifest.json b/plugins/shd-mcp-plugin/widgets/terms/v1/manifest.json
new file mode 100644
index 0000000..526484b
--- /dev/null
+++ b/plugins/shd-mcp-plugin/widgets/terms/v1/manifest.json
@@ -0,0 +1,20 @@
+{
+ "schemaVersion": 1,
+ "name": "shd-terms",
+ "version": "1.0.0",
+ "resources": [
+ {
+ "file": "index.html",
+ "bytes": 25597,
+ "gzipBytes": 8709,
+ "mediaType": "text/html;profile=mcp-app",
+ "uri": "ui://shd/terms/v1.html",
+ "sha256": "f7b692915628c89d91a411700525bd702f4a2bcf4db39d8afd8acc2b90692be7"
+ }
+ ],
+ "license": "../../../../../LICENSE",
+ "source": {
+ "repository": "https://github.com/bulava92/shd-mcp-plugin",
+ "path": "plugins/shd-mcp-plugin/widgets/terms/v1/index.html"
+ }
+}
diff --git a/scripts/mcp-runtime-smoke.mjs b/scripts/mcp-runtime-smoke.mjs
new file mode 100644
index 0000000..b7aab44
--- /dev/null
+++ b/scripts/mcp-runtime-smoke.mjs
@@ -0,0 +1,178 @@
+#!/usr/bin/env node
+
+import process from 'node:process';
+
+const runtimeUrl = process.env.SHD_MCP_RUNTIME_URL || process.env.MCP_RUNTIME_URL || '';
+const accessToken = process.env.SHD_MCP_ACCESS_TOKEN || process.env.MCP_ACCESS_TOKEN || '';
+const requireAuth = process.argv.includes('--require-auth');
+const jsonOutput = process.argv.includes('--json');
+
+if (!runtimeUrl) {
+ fail('Set SHD_MCP_RUNTIME_URL to the approved MCP endpoint; no endpoint is assumed.');
+ process.exit(1);
+}
+
+const mcpUrl = new URL(runtimeUrl);
+const origin = mcpUrl.origin;
+const checks = [];
+
+function fail(message) {
+ console.error(`MCP runtime smoke: ERROR: ${message}`);
+ process.exitCode = 1;
+}
+
+function addCheck(name, ok, detail = '') {
+ checks.push({ name, ok, detail });
+ if (!ok) throw new Error(`${name}${detail ? `: ${detail}` : ''}`);
+}
+
+function safeErrorBody(value) {
+ if (!value) return '';
+ return String(value).replace(/Bearer\s+[^\s]+/gi, 'Bearer [redacted]').replace(/(access_token|refresh_token|code|client_secret|cookie)=?[^&\s]*/gi, '$1=[redacted]').slice(0, 240);
+}
+
+async function request(url, options = {}) {
+ const response = await fetch(url, {
+ ...options,
+ headers: {
+ Accept: 'application/json',
+ ...(options.body ? { 'Content-Type': 'application/json' } : {}),
+ ...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {}),
+ ...(options.headers || {}),
+ },
+ });
+ const text = await response.text();
+ let body = null;
+ try { body = text ? JSON.parse(text) : null; } catch { body = null; }
+ return { response, body, text };
+}
+
+async function expectJson(url, name, expectedStatus = 200) {
+ const result = await request(url);
+ addCheck(`${name} HTTP`, result.response.status === expectedStatus, `received ${result.response.status}`);
+ addCheck(`${name} JSON`, result.body && typeof result.body === 'object', safeErrorBody(result.text));
+ return result.body;
+}
+
+async function rpc(method, params, id, sessionId) {
+ const headers = { Accept: 'application/json, text/event-stream' };
+ if (sessionId) headers['MCP-Session-Id'] = sessionId;
+ const result = await request(mcpUrl, {
+ method: 'POST',
+ headers,
+ body: JSON.stringify({ jsonrpc: '2.0', id, method, params }),
+ });
+ addCheck(`${method} HTTP`, result.response.ok, `received ${result.response.status}`);
+ addCheck(`${method} JSON`, result.body && typeof result.body === 'object', safeErrorBody(result.text));
+ if (result.body?.error) throw new Error(`${method}: MCP returned an error`);
+ return { result: result.body?.result || {}, sessionId: result.response.headers.get('MCP-Session-Id') || sessionId };
+}
+
+async function notifyRpc(method, params, sessionId) {
+ const headers = { Accept: 'application/json, text/event-stream' };
+ if (sessionId) headers['MCP-Session-Id'] = sessionId;
+ const result = await request(mcpUrl, {
+ method: 'POST',
+ headers,
+ body: JSON.stringify({ jsonrpc: '2.0', method, params }),
+ });
+ addCheck(`${method} HTTP`, result.response.ok, `received ${result.response.status}`);
+}
+
+async function run() {
+ const authorization = await expectJson(`${origin}/.well-known/oauth-authorization-server`, 'OAuth authorization metadata');
+ addCheck('OAuth issuer', typeof authorization.issuer === 'string' && authorization.issuer.length > 0);
+ addCheck('OAuth authorization endpoint', typeof authorization.authorization_endpoint === 'string');
+ addCheck('OAuth token endpoint', typeof authorization.token_endpoint === 'string');
+ addCheck('OAuth PKCE S256', Array.isArray(authorization.code_challenge_methods_supported) && authorization.code_challenge_methods_supported.includes('S256'));
+ const protectedResource = await expectJson(`${origin}/.well-known/oauth-protected-resource/mcp`, 'OAuth protected-resource metadata');
+ addCheck('Protected resource', typeof protectedResource.resource === 'string' && protectedResource.resource.startsWith(origin));
+ addCheck('Bearer header support', Array.isArray(protectedResource.bearer_methods_supported) && protectedResource.bearer_methods_supported.includes('header'));
+
+ if (!accessToken) {
+ addCheck('Authenticated MCP checks', !requireAuth, 'SHD_MCP_ACCESS_TOKEN is not set');
+ return;
+ }
+
+ let sessionId;
+ const initialized = await rpc('initialize', {
+ protocolVersion: '2025-11-25',
+ capabilities: {},
+ clientInfo: { name: 'shd-mcp-plugin-runtime-smoke', version: '1.0.0' },
+ }, 1);
+ sessionId = initialized.sessionId;
+ addCheck('MCP protocol', initialized.result.protocolVersion === '2025-11-25');
+ await notifyRpc('notifications/initialized', {}, sessionId);
+ const tools = (await rpc('tools/list', {}, 2, sessionId)).result.tools || [];
+ const toolNames = new Set(tools.map((tool) => tool.name));
+ for (const name of ['shd_list_projects', 'shd_render_projects_widget', 'shd_render_documents_widget', 'shd_render_tasks_widget', 'shd_render_finance_widget', 'shd_render_crm_widget', 'shd_render_discussions_widget', 'shd_render_notifications_widget', 'shd_render_scheduling_widget', 'shd_render_inventory_widget', 'shd_render_agents_widget', 'shd_render_status_page_widget', 'shd_render_project_db_widget', 'shd_render_notes_widget', 'shd_render_project_overview_widget', 'shd_render_files_widget', 'shd_render_proposals_widget', 'shd_render_terms_widget', 'shd_render_activity_widget', 'shd_render_organizations_widget', 'shd_render_gitea_widget', 'shd_render_schemes_widget', 'shd_render_task_kanban_widget', 'shd_render_team_workload_widget', 'shd_render_project_timeline_widget', 'shd_render_crm_funnel_widget', 'shd_render_finance_dashboard_widget', 'shd_render_proposal_approvals_widget', 'shd_render_documents_completeness_widget', 'shd_render_agents_health_widget', 'shd_render_schedule_calendar_widget', 'shd_render_acl_matrix_widget', 'shd_render_inventory_warnings_widget', 'shd_render_gitea_board_widget', 'shd_render_schemes_progress_widget', 'shd_render_notes_tree_widget', 'shd_render_project_db_preview_widget']) {
+ addCheck(`Tool ${name}`, toolNames.has(name));
+ }
+ for (const [name, items] of [
+ ['shd_render_projects_widget', { projects: [{ id: 1, code: 'runtime-smoke', display_name: 'Runtime smoke', status: 'check', deadline: null }] }],
+ ['shd_render_documents_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'check', date: null, value: null }] }],
+ ['shd_render_tasks_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'check', date: null, value: null }] }],
+ ['shd_render_finance_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'check', date: null, value: null }] }],
+ ['shd_render_crm_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'check', date: null, value: null }] }],
+ ['shd_render_discussions_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'open', date: null, value: null }] }],
+ ['shd_render_notifications_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'unread', date: null, value: null }] }],
+ ['shd_render_scheduling_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'scheduled', date: null, value: null }] }],
+ ['shd_render_inventory_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'available', date: null, value: null }] }],
+ ['shd_render_agents_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'online', date: null, value: null }] }],
+ ['shd_render_status_page_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'up', date: null, value: '100%' }] }],
+ ['shd_render_project_db_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'ready', date: null, value: null }] }],
+ ['shd_render_notes_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'published', date: null, value: null }] }],
+ ['shd_render_project_overview_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'ready', date: null, value: null }] }],
+ ['shd_render_files_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'available', date: null, value: null }] }],
+ ['shd_render_proposals_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'draft', date: null, value: null }] }],
+ ['shd_render_terms_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'ready', date: null, value: null }] }],
+ ['shd_render_activity_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'new', date: null, value: null }] }],
+ ['shd_render_organizations_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'active', date: null, value: null }] }],
+ ['shd_render_gitea_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'open', date: null, value: null }] }],
+ ['shd_render_schemes_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'ready', date: null, value: null }] }],
+ ['shd_render_task_kanban_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'todo', date: null, value: null }] }],
+ ['shd_render_team_workload_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'normal', date: null, value: '8' }] }],
+ ['shd_render_project_timeline_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'planned', date: null, value: null }] }],
+ ['shd_render_crm_funnel_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'qualified', date: null, value: null }] }],
+ ['shd_render_finance_dashboard_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'draft', date: null, value: '100' }] }],
+ ['shd_render_proposal_approvals_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'pending', date: null, value: null }] }],
+ ['shd_render_documents_completeness_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'complete', date: null, value: '100' }] }],
+ ['shd_render_agents_health_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'online', date: null, value: null }] }],
+ ['shd_render_schedule_calendar_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'scheduled', date: null, value: null }] }],
+ ['shd_render_acl_matrix_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'member', date: null, value: null }] }],
+ ['shd_render_inventory_warnings_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'low_stock', date: null, value: '1' }] }],
+ ['shd_render_gitea_board_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'open', date: null, value: null }] }],
+ ['shd_render_schemes_progress_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'in_progress', date: null, value: '50' }] }],
+ ['shd_render_notes_tree_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'active', date: null, value: null }] }],
+ ['shd_render_project_db_preview_widget', { items: [{ id: 'runtime-smoke', title: 'Runtime smoke', status: 'ready', date: null, value: null }] }],
+ ]) {
+ const render = await rpc('tools/call', { name, arguments: items }, 20 + checks.length, sessionId);
+ const output = render.result.structuredContent;
+ addCheck(`${name} output`, output?.ok === true && Array.isArray(output.data));
+ }
+ const resources = (await rpc('resources/list', {}, 3, sessionId)).result.resources || [];
+ for (const uri of ['ui://shd/active-projects/v1.html', 'ui://shd/documents/v1.html', 'ui://shd/tasks/v1.html', 'ui://shd/finance/v1.html', 'ui://shd/crm/v1.html', 'ui://shd/discussions/v1.html', 'ui://shd/notifications/v1.html', 'ui://shd/scheduling/v1.html', 'ui://shd/inventory/v1.html', 'ui://shd/agents/v1.html', 'ui://shd/status-page/v1.html', 'ui://shd/project-db/v1.html', 'ui://shd/notes/v1.html', 'ui://shd/project-overview/v1.html', 'ui://shd/files/v1.html', 'ui://shd/proposals/v1.html', 'ui://shd/terms/v1.html', 'ui://shd/activity/v1.html', 'ui://shd/organizations/v1.html', 'ui://shd/gitea/v1.html', 'ui://shd/schemes/v1.html', 'ui://shd/task-kanban/v1.html', 'ui://shd/team-workload/v1.html', 'ui://shd/project-timeline/v1.html', 'ui://shd/crm-funnel/v1.html', 'ui://shd/finance-dashboard/v1.html', 'ui://shd/proposal-approvals/v1.html', 'ui://shd/documents-completeness/v1.html', 'ui://shd/agents-health/v1.html', 'ui://shd/schedule-calendar/v1.html', 'ui://shd/acl-matrix/v1.html', 'ui://shd/inventory-warnings/v1.html', 'ui://shd/gitea-board/v1.html', 'ui://shd/schemes-progress/v1.html', 'ui://shd/notes-tree/v1.html', 'ui://shd/project-db-preview/v1.html']) {
+ addCheck(`Resource ${uri}`, resources.some((resource) => resource.uri === uri));
+ const resourceIndex = resources.findIndex((resource) => resource.uri === uri);
+ if (resourceIndex < 0) continue;
+ const content = (await rpc('resources/read', { uri }, 10 + resourceIndex, sessionId)).result.contents?.[0];
+ addCheck(`${uri} MIME`, content?.mimeType === 'text/html;profile=mcp-app');
+ addCheck(`${uri} bridge`, ['ui/initialize', 'ui/notifications/initialized', 'tools/call'].every((marker) => content?.text?.includes(marker)));
+ }
+ addCheck('Authenticated MCP resource checks', true);
+}
+
+try {
+ await run();
+ const result = { status: 'ok', authenticated: Boolean(accessToken), checks };
+ if (jsonOutput) console.log(JSON.stringify(result, null, 2));
+ else {
+ console.log(`MCP runtime smoke: ok (${checks.length} checks; authenticated=${Boolean(accessToken)})`);
+ for (const check of checks) console.log(`- ${check.name}`);
+ }
+} catch (error) {
+ const message = error instanceof Error ? error.message : 'unknown error';
+ if (jsonOutput) console.log(JSON.stringify({ status: 'error', authenticated: Boolean(accessToken), checks, error: message }, null, 2));
+ else fail(message);
+ process.exitCode = 1;
+}
diff --git a/tests/test_widget_artifact.py b/tests/test_widget_artifact.py
index 7f337fb..699c296 100644
--- a/tests/test_widget_artifact.py
+++ b/tests/test_widget_artifact.py
@@ -5,42 +5,92 @@ from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
-WIDGET = ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "active-projects" / "v1"
+WIDGETS = {
+ "active-projects": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "active-projects" / "v1",
+ "documents": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "documents" / "v1",
+ "tasks": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "tasks" / "v1",
+ "finance": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "finance" / "v1",
+ "crm": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "crm" / "v1",
+ "discussions": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "discussions" / "v1",
+ "notifications": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "notifications" / "v1",
+ "scheduling": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "scheduling" / "v1",
+ "inventory": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "inventory" / "v1",
+ "agents": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "agents" / "v1",
+ "status-page": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "status-page" / "v1",
+ "project-db": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "project-db" / "v1",
+ "notes": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "notes" / "v1",
+ "project-overview": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "project-overview" / "v1",
+ "files": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "files" / "v1",
+ "proposals": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "proposals" / "v1",
+ "terms": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "terms" / "v1",
+ "activity": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "activity" / "v1",
+ "organizations": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "organizations" / "v1",
+ "gitea": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "gitea" / "v1",
+ "schemes": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "schemes" / "v1",
+ "task-kanban": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "task-kanban" / "v1",
+ "team-workload": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "team-workload" / "v1",
+ "project-timeline": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "project-timeline" / "v1",
+ "crm-funnel": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "crm-funnel" / "v1",
+ "finance-dashboard": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "finance-dashboard" / "v1",
+ "proposal-approvals": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "proposal-approvals" / "v1",
+ "documents-completeness": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "documents-completeness" / "v1",
+ "agents-health": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "agents-health" / "v1",
+ "schedule-calendar": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "schedule-calendar" / "v1",
+ "acl-matrix": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "acl-matrix" / "v1",
+ "inventory-warnings": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "inventory-warnings" / "v1",
+ "gitea-board": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "gitea-board" / "v1",
+ "schemes-progress": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "schemes-progress" / "v1",
+ "notes-tree": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "notes-tree" / "v1",
+ "project-db-preview": ROOT / "plugins" / "shd-mcp-plugin" / "widgets" / "project-db-preview" / "v1",
+}
class WidgetArtifactTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
- cls.manifest = json.loads((WIDGET / "manifest.json").read_text(encoding="utf-8"))
- cls.resource = next(item for item in cls.manifest["resources"] if item["file"] == "index.html")
- cls.html = (WIDGET / "index.html").read_text(encoding="utf-8")
+ cls.artifacts = {}
+ for name, widget in WIDGETS.items():
+ manifest = json.loads((widget / "manifest.json").read_text(encoding="utf-8"))
+ resource = next(item for item in manifest["resources"] if item["file"] == "index.html")
+ cls.artifacts[name] = {
+ "widget": widget,
+ "manifest": manifest,
+ "resource": resource,
+ "html": (widget / "index.html").read_text(encoding="utf-8"),
+ }
def test_manifest_and_checksums_match_artifact(self):
- digest = hashlib.sha256(self.html.encode("utf-8")).hexdigest()
- self.assertEqual(self.resource["uri"], "ui://shd/active-projects/v1.html")
- self.assertEqual(self.resource["mediaType"], "text/html;profile=mcp-app")
- self.assertEqual(self.resource["bytes"], len(self.html.encode("utf-8")))
- self.assertEqual(self.resource["sha256"], digest)
+ for name, artifact in self.artifacts.items():
+ widget = artifact["widget"]
+ manifest = artifact["manifest"]
+ resource = artifact["resource"]
+ html = artifact["html"]
+ digest = hashlib.sha256(html.encode("utf-8")).hexdigest()
+ self.assertEqual(resource["uri"], f"ui://shd/{name}/v1.html", name)
+ self.assertEqual(resource["mediaType"], "text/html;profile=mcp-app", name)
+ self.assertEqual(resource["bytes"], len(html.encode("utf-8")), name)
+ self.assertEqual(resource["sha256"], digest, name)
- checksum = (WIDGET / "SHA256SUMS").read_text(encoding="utf-8").strip().split()
- self.assertEqual(checksum, [digest, "index.html"])
+ checksum = (widget / "SHA256SUMS").read_text(encoding="utf-8").strip().split()
+ self.assertEqual(checksum, [digest, "index.html"], name)
- license_path = (WIDGET / self.manifest["license"]).resolve()
- self.assertEqual(license_path, (ROOT / "LICENSE").resolve())
- source_path = (ROOT / self.manifest["source"]["path"]).resolve()
- self.assertEqual(source_path, (WIDGET / "index.html").resolve())
+ license_path = (widget / manifest["license"]).resolve()
+ self.assertEqual(license_path, (ROOT / "LICENSE").resolve(), name)
+ source_path = (ROOT / manifest["source"]["path"]).resolve()
+ self.assertEqual(source_path, (widget / "index.html").resolve(), name)
def test_widget_uses_portable_bridge_and_no_external_script(self):
- for marker in (
- "ui/initialize",
- "ui/notifications/initialized",
- "ui/notifications/tool-input",
- "ui/notifications/tool-result",
- "tools/call",
- "window.openai",
- ):
- self.assertIn(marker, self.html, marker)
- self.assertNotIn("