@hotmeshio/long-tail 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -8
- package/build/api/auth.d.ts +5 -0
- package/build/api/auth.js +42 -0
- package/build/api/bot-accounts.d.ts +50 -0
- package/build/api/bot-accounts.js +215 -0
- package/build/api/controlplane.d.ts +20 -0
- package/build/api/controlplane.js +110 -0
- package/build/api/dba.d.ts +15 -0
- package/build/api/dba.js +68 -0
- package/build/api/escalations.d.ts +70 -0
- package/build/api/escalations.js +656 -0
- package/build/api/exports.d.ts +32 -0
- package/build/api/exports.js +146 -0
- package/build/api/index.d.ts +18 -0
- package/build/api/index.js +54 -0
- package/build/api/insight.d.ts +29 -0
- package/build/api/insight.js +90 -0
- package/build/api/maintenance.d.ts +7 -0
- package/build/api/maintenance.js +28 -0
- package/build/api/mcp-runs.d.ts +16 -0
- package/build/api/mcp-runs.js +62 -0
- package/build/api/mcp.d.ts +52 -0
- package/build/api/mcp.js +212 -0
- package/build/api/namespaces.d.ts +7 -0
- package/build/{routes/escalations/helpers.js → api/namespaces.js} +24 -12
- package/build/api/roles.d.ts +25 -0
- package/build/api/roles.js +159 -0
- package/build/api/settings.d.ts +2 -0
- package/build/api/settings.js +35 -0
- package/build/api/tasks.d.ts +27 -0
- package/build/api/tasks.js +96 -0
- package/build/api/users.d.ts +44 -0
- package/build/api/users.js +162 -0
- package/build/api/workflow-sets.d.ts +26 -0
- package/build/api/workflow-sets.js +119 -0
- package/build/api/workflows.d.ts +48 -0
- package/build/api/workflows.js +298 -0
- package/build/api/yaml-workflows.d.ts +87 -0
- package/build/api/yaml-workflows.js +556 -0
- package/build/index.d.ts +4 -0
- package/build/index.js +6 -1
- package/build/lib/db/migrate.js +3 -6
- package/{lib → build/lib}/db/schemas/001_schema.sql +3 -0
- package/build/lib/db/schemas/004_workflow_sets.sql +29 -0
- package/build/lib/db/schemas/005_unique_graph_topic.sql +7 -0
- package/{lib → build/lib}/db/schemas/011_system_workflow_configs.sql +14 -0
- package/build/lib/db/schemas/016_streamable_http.sql +7 -0
- package/build/lib/events/callback.d.ts +41 -0
- package/build/lib/events/callback.js +98 -0
- package/build/modules/config.js +1 -1
- package/build/routes/auth.js +37 -36
- package/build/routes/bot-accounts.js +34 -164
- package/build/routes/controlplane.js +20 -60
- package/build/routes/dba.js +18 -28
- package/build/routes/docs.js +25 -7
- package/build/routes/escalations/bulk.js +17 -192
- package/build/routes/escalations/list.js +29 -75
- package/build/routes/escalations/resolve.js +3 -193
- package/build/routes/escalations/single.js +13 -122
- package/build/routes/exports.js +44 -95
- package/build/routes/index.js +2 -0
- package/build/routes/insight.js +61 -40
- package/build/routes/maintenance.js +41 -17
- package/build/routes/mcp-runs.js +52 -60
- package/build/routes/mcp.js +55 -161
- package/build/routes/namespaces.js +9 -20
- package/build/routes/roles.js +23 -97
- package/build/routes/settings.js +37 -25
- package/build/routes/tasks.js +28 -64
- package/build/routes/users.js +24 -113
- package/build/routes/workflow-sets.d.ts +2 -0
- package/build/routes/workflow-sets.js +98 -0
- package/build/routes/workflows/config.js +23 -57
- package/build/routes/workflows/discovery.js +11 -85
- package/build/routes/workflows/invocation.js +16 -84
- package/build/routes/yaml-workflows/cron.d.ts +2 -0
- package/build/routes/yaml-workflows/cron.js +68 -0
- package/build/routes/yaml-workflows/crud.js +38 -193
- package/build/routes/yaml-workflows/deployment.js +15 -140
- package/build/routes/yaml-workflows/index.js +4 -1
- package/build/routes/yaml-workflows/versions.js +20 -58
- package/build/sdk/index.d.ts +327 -0
- package/build/sdk/index.js +298 -0
- package/build/services/controlplane/index.d.ts +1 -2
- package/build/services/controlplane/index.js +3 -3
- package/build/services/controlplane/sql.d.ts +2 -2
- package/build/services/controlplane/sql.js +4 -5
- package/build/services/controlplane/types.d.ts +1 -0
- package/build/services/cron/index.d.ts +17 -0
- package/build/services/cron/index.js +94 -1
- package/build/services/export/index.js +6 -1
- package/build/services/hotmesh-utils.js +2 -4
- package/build/services/insight/index.d.ts +18 -0
- package/build/services/insight/index.js +60 -0
- package/build/services/mcp/client/connection.d.ts +9 -0
- package/build/services/mcp/client/connection.js +49 -1
- package/build/services/mcp/client/tools.js +13 -1
- package/build/services/mcp/db-server/schemas.d.ts +2 -2
- package/build/services/mcp/db.d.ts +1 -1
- package/build/services/mcp/db.js +10 -0
- package/build/services/mcp/playwright-server/schemas.d.ts +4 -4
- package/build/services/mcp/sql.d.ts +1 -1
- package/build/services/mcp/sql.js +2 -2
- package/build/services/mcp/types.d.ts +3 -1
- package/build/services/mcp-runs/sql.js +1 -1
- package/build/services/workflow-sets/db.d.ts +16 -0
- package/build/services/workflow-sets/db.js +78 -0
- package/build/services/workflow-sets/index.d.ts +1 -0
- package/build/services/workflow-sets/index.js +11 -0
- package/build/services/workflow-sets/sql.d.ts +6 -0
- package/build/services/workflow-sets/sql.js +24 -0
- package/build/services/yaml-workflow/db-utils.d.ts +1 -0
- package/build/services/yaml-workflow/db-utils.js +4 -0
- package/build/services/yaml-workflow/db.d.ts +8 -0
- package/build/services/yaml-workflow/db.js +41 -0
- package/build/services/yaml-workflow/invoke.d.ts +19 -0
- package/build/services/yaml-workflow/invoke.js +80 -0
- package/build/services/yaml-workflow/pipeline/build/dag.js +1 -1
- package/build/services/yaml-workflow/pipeline/build/wiring.d.ts +1 -1
- package/build/services/yaml-workflow/pipeline/build/wiring.js +102 -2
- package/build/services/yaml-workflow/pipeline/prompts.d.ts +1 -1
- package/build/services/yaml-workflow/pipeline/prompts.js +44 -1
- package/build/services/yaml-workflow/sql.d.ts +5 -1
- package/build/services/yaml-workflow/sql.js +23 -3
- package/build/services/yaml-workflow/types.d.ts +16 -1
- package/build/services/yaml-workflow/workers/callbacks.js +16 -2
- package/build/services/yaml-workflow/workers/register.js +36 -1
- package/build/start/adapters.js +4 -0
- package/build/system/index.js +12 -0
- package/build/system/mcp-servers/admin/schemas.d.ts +12 -12
- package/build/system/mcp-servers/db-query/schemas.d.ts +2 -2
- package/build/system/mcp-servers/knowledge.js +1 -1
- package/build/system/mcp-servers/playwright/schemas.d.ts +18 -18
- package/build/system/mcp-servers/playwright-cli/schemas.d.ts +34 -34
- package/build/system/mcp-servers/playwright-cli/tools-capture.js +5 -1
- package/build/system/mcp-servers/vision.js +54 -17
- package/build/system/seed/server-definitions.d.ts +7 -0
- package/build/system/seed/server-definitions.js +6 -2
- package/build/system/seed/tool-manifests-workflows.d.ts +7 -0
- package/build/system/seed/tool-manifests-workflows.js +10 -3
- package/build/system/workflows/mcp-workflow-builder/activities/caches.d.ts +5 -0
- package/build/system/workflows/mcp-workflow-builder/activities/caches.js +8 -0
- package/build/system/workflows/mcp-workflow-builder/activities/index.d.ts +2 -0
- package/build/system/workflows/mcp-workflow-builder/activities/index.js +8 -0
- package/build/system/workflows/mcp-workflow-builder/activities/llm.d.ts +2 -0
- package/build/system/workflows/mcp-workflow-builder/activities/llm.js +25 -0
- package/build/system/workflows/mcp-workflow-builder/activities/tool-loader.d.ts +11 -0
- package/build/system/workflows/mcp-workflow-builder/activities/tool-loader.js +34 -0
- package/build/system/workflows/mcp-workflow-builder/index.d.ts +16 -0
- package/build/system/workflows/mcp-workflow-builder/index.js +253 -0
- package/build/system/workflows/mcp-workflow-builder/prompts.d.ts +8 -0
- package/build/system/workflows/mcp-workflow-builder/prompts.js +316 -0
- package/build/system/workflows/mcp-workflow-planner/activities/analyze.d.ts +11 -0
- package/build/system/workflows/mcp-workflow-planner/activities/analyze.js +36 -0
- package/build/system/workflows/mcp-workflow-planner/activities/index.d.ts +3 -0
- package/build/system/workflows/mcp-workflow-planner/activities/index.js +12 -0
- package/build/system/workflows/mcp-workflow-planner/activities/persist.d.ts +19 -0
- package/build/system/workflows/mcp-workflow-planner/activities/persist.js +55 -0
- package/build/system/workflows/mcp-workflow-planner/activities/plan.d.ts +10 -0
- package/build/system/workflows/mcp-workflow-planner/activities/plan.js +43 -0
- package/build/system/workflows/mcp-workflow-planner/index.d.ts +7 -0
- package/build/system/workflows/mcp-workflow-planner/index.js +152 -0
- package/build/system/workflows/mcp-workflow-planner/prompts.d.ts +7 -0
- package/build/system/workflows/mcp-workflow-planner/prompts.js +77 -0
- package/build/system/workflows/shared/tool-loader.js +3 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/index.d.ts +1 -0
- package/build/types/mcp.d.ts +4 -3
- package/build/types/sdk.d.ts +27 -0
- package/build/types/sdk.js +2 -0
- package/build/types/workflow-set.d.ts +44 -0
- package/build/types/workflow-set.js +5 -0
- package/build/types/yaml-workflow.d.ts +6 -2
- package/dashboard/dist/assets/AdminDashboard-DRjkRSjJ.js +2 -0
- package/dashboard/dist/assets/{AdminDashboard-CTyAMUJR.js.map → AdminDashboard-DRjkRSjJ.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-CnivX4Tz.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-CnivX4Tz.js.map +1 -0
- package/dashboard/dist/assets/BotPicker-DwwaBhTH.js +2 -0
- package/dashboard/dist/assets/{BotPicker-C51nKFEu.js.map → BotPicker-DwwaBhTH.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-BSyfd8uL.js → CollapsibleSection-DQpaVA0M.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-BSyfd8uL.js.map → CollapsibleSection-DQpaVA0M.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-CBdhia5T.js → ConfirmDeleteModal-B7JoDNvt.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-CBdhia5T.js.map → ConfirmDeleteModal-B7JoDNvt.js.map} +1 -1
- package/dashboard/dist/assets/{CopyableId-dGlewBCS.js → CopyableId-AqoZayBG.js} +2 -2
- package/dashboard/dist/assets/{CopyableId-dGlewBCS.js.map → CopyableId-AqoZayBG.js.map} +1 -1
- package/dashboard/dist/assets/CredentialsPage-qGw1kQzi.js +2 -0
- package/dashboard/dist/assets/CredentialsPage-qGw1kQzi.js.map +1 -0
- package/dashboard/dist/assets/{CustomDurationPicker-BataWFj8.js → CustomDurationPicker-D1HUQcd0.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-BataWFj8.js.map → CustomDurationPicker-D1HUQcd0.js.map} +1 -1
- package/dashboard/dist/assets/{DataTable-B3uf5CCo.js → DataTable-DKvSKoVG.js} +2 -2
- package/dashboard/dist/assets/{DataTable-B3uf5CCo.js.map → DataTable-DKvSKoVG.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-G5oSwTpT.js → ElapsedCell-B0yrReGQ.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-G5oSwTpT.js.map → ElapsedCell-B0yrReGQ.js.map} +1 -1
- package/dashboard/dist/assets/{EmptyState-BChBJNGS.js → EmptyState-X0fIzYID.js} +2 -2
- package/dashboard/dist/assets/{EmptyState-BChBJNGS.js.map → EmptyState-X0fIzYID.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-CxUv8xjG.js → EscalationsOverview-BQAT9W7r.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-CxUv8xjG.js.map → EscalationsOverview-BQAT9W7r.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-CVt8B0BZ.js → EventTable-CX1KNLhZ.js} +2 -2
- package/dashboard/dist/assets/{EventTable-CVt8B0BZ.js.map → EventTable-CX1KNLhZ.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-CShf0oe7.js → FilterBar-DMTvuQy-.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-CShf0oe7.js.map → FilterBar-DMTvuQy-.js.map} +1 -1
- package/dashboard/dist/assets/ListToolbar-DTOSxoEy.js +2 -0
- package/dashboard/dist/assets/ListToolbar-DTOSxoEy.js.map +1 -0
- package/dashboard/dist/assets/{McpOverview-CbaZRnJl.js → McpOverview-BaKTIWrG.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-CbaZRnJl.js.map → McpOverview-BaKTIWrG.js.map} +1 -1
- package/dashboard/dist/assets/McpQueryDetailPage-CC08T5k8.js +5 -0
- package/dashboard/dist/assets/McpQueryDetailPage-CC08T5k8.js.map +1 -0
- package/dashboard/dist/assets/McpQueryPage-CVfF9dYg.js +2 -0
- package/dashboard/dist/assets/McpQueryPage-CVfF9dYg.js.map +1 -0
- package/dashboard/dist/assets/McpRunDetailPage-CKs1RWeV.js +2 -0
- package/dashboard/dist/assets/McpRunDetailPage-CKs1RWeV.js.map +1 -0
- package/dashboard/dist/assets/McpRunsPage-CcPD_tY1.js +2 -0
- package/dashboard/dist/assets/McpRunsPage-CcPD_tY1.js.map +1 -0
- package/dashboard/dist/assets/{Modal-CI5RBPOQ.js → Modal-_2AbWxJT.js} +2 -2
- package/dashboard/dist/assets/{Modal-CI5RBPOQ.js.map → Modal-_2AbWxJT.js.map} +1 -1
- package/dashboard/dist/assets/OperatorDashboard-BGiRaRDr.js +2 -0
- package/dashboard/dist/assets/OperatorDashboard-BGiRaRDr.js.map +1 -0
- package/dashboard/dist/assets/{PageHeader-SMD9qtOO.js → PageHeader-DVr5Qyzm.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-SMD9qtOO.js.map → PageHeader-DVr5Qyzm.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-TikLQsTp.js → PageHeaderWithStats-D0KRASML.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-TikLQsTp.js.map → PageHeaderWithStats-D0KRASML.js.map} +1 -1
- package/dashboard/dist/assets/{PriorityBadge-CQ0EsLTA.js → PriorityBadge-Bx2559OU.js} +2 -2
- package/dashboard/dist/assets/{PriorityBadge-CQ0EsLTA.js.map → PriorityBadge-Bx2559OU.js.map} +1 -1
- package/dashboard/dist/assets/ProcessDetailPage-69I--sry.js +2 -0
- package/dashboard/dist/assets/ProcessDetailPage-69I--sry.js.map +1 -0
- package/dashboard/dist/assets/ProcessesListPage-BDpUbua2.js +2 -0
- package/dashboard/dist/assets/ProcessesListPage-BDpUbua2.js.map +1 -0
- package/dashboard/dist/assets/{RolePill-Crj4TH5p.js → RolePill-CcAqEaSt.js} +2 -2
- package/dashboard/dist/assets/{RolePill-Crj4TH5p.js.map → RolePill-CcAqEaSt.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-C_RInUwS.js → RolesPage-Cl23Hjet.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-C_RInUwS.js.map → RolesPage-Cl23Hjet.js.map} +1 -1
- package/dashboard/dist/assets/{RowActions-Cp5HyK_w.js → RowActions-B4mqIt3Z.js} +2 -2
- package/dashboard/dist/assets/{RowActions-Cp5HyK_w.js.map → RowActions-B4mqIt3Z.js.map} +1 -1
- package/dashboard/dist/assets/{StatCard-BKZLSgNV.js → StatCard-Cz_2OjAZ.js} +2 -2
- package/dashboard/dist/assets/{StatCard-BKZLSgNV.js.map → StatCard-Cz_2OjAZ.js.map} +1 -1
- package/dashboard/dist/assets/{StatusBadge-BYNGGZK5.js → StatusBadge-Wi2FJZsn.js} +2 -2
- package/dashboard/dist/assets/{StatusBadge-BYNGGZK5.js.map → StatusBadge-Wi2FJZsn.js.map} +1 -1
- package/dashboard/dist/assets/StepIndicator-PW5NRDMb.js +2 -0
- package/dashboard/dist/assets/StepIndicator-PW5NRDMb.js.map +1 -0
- package/dashboard/dist/assets/{StickyPagination-CTosgiU2.js → StickyPagination-Bl2Uzz65.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-CTosgiU2.js.map → StickyPagination-Bl2Uzz65.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-ylG5Ps1s.js → SwimlaneTimeline-CUPqMd0z.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-ylG5Ps1s.js.map → SwimlaneTimeline-CUPqMd0z.js.map} +1 -1
- package/dashboard/dist/assets/TagInput-BLtf86Ly.js +2 -0
- package/dashboard/dist/assets/TagInput-BLtf86Ly.js.map +1 -0
- package/dashboard/dist/assets/{TaskDetailPage-C9pDGdD2.js → TaskDetailPage-BXJFX74D.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-C9pDGdD2.js.map → TaskDetailPage-BXJFX74D.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-BtJbZTT0.js → TaskQueuePill-CWYj3xKe.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-BtJbZTT0.js.map → TaskQueuePill-CWYj3xKe.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-DtFLUEhg.js → TasksListPage-C3cX94Mw.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-DtFLUEhg.js.map → TasksListPage-C3cX94Mw.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-WuM6xImZ.js → TimeAgo-B_5yDDHV.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-WuM6xImZ.js.map → TimeAgo-B_5yDDHV.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-IVL_-Upy.js → TimestampCell-DRX724uU.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-IVL_-Upy.js.map → TimestampCell-DRX724uU.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-DU9qeg13.js → UserName-Ca8FA469.js} +2 -2
- package/dashboard/dist/assets/{UserName-DU9qeg13.js.map → UserName-Ca8FA469.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-BBYWEV2P.js +2 -0
- package/dashboard/dist/assets/WorkflowExecutionPage-BBYWEV2P.js.map +1 -0
- package/dashboard/dist/assets/WorkflowPill-BXifAuLi.js +2 -0
- package/dashboard/dist/assets/{WorkflowPill-Diw8iWBP.js.map → WorkflowPill-BXifAuLi.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowsDashboard-Drl3juz9.js +2 -0
- package/dashboard/dist/assets/WorkflowsDashboard-Drl3juz9.js.map +1 -0
- package/dashboard/dist/assets/{WorkflowsOverview-CPuvA4t3.js → WorkflowsOverview-03IRrDLg.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-CPuvA4t3.js.map → WorkflowsOverview-03IRrDLg.js.map} +1 -1
- package/dashboard/dist/assets/YamlWorkflowsPage-DC2cLxVi.js +2 -0
- package/dashboard/dist/assets/YamlWorkflowsPage-DC2cLxVi.js.map +1 -0
- package/dashboard/dist/assets/{bots-BPiZXf2h.js → bots-DZEXcgiJ.js} +2 -2
- package/dashboard/dist/assets/{bots-BPiZXf2h.js.map → bots-DZEXcgiJ.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-DTY_OKRh.js → escalation-Cw48lNaF.js} +2 -2
- package/dashboard/dist/assets/{escalation-DTY_OKRh.js.map → escalation-Cw48lNaF.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-C91fHSkp.js → escalation-columns-NINpo3qf.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-C91fHSkp.js.map → escalation-columns-NINpo3qf.js.map} +1 -1
- package/dashboard/dist/assets/helpers-Cuu3xKfr.js +2 -0
- package/dashboard/dist/assets/helpers-Cuu3xKfr.js.map +1 -0
- package/dashboard/dist/assets/helpers-fk_qr729.js +2 -0
- package/dashboard/dist/assets/helpers-fk_qr729.js.map +1 -0
- package/dashboard/dist/assets/index-B98ipWxE.js +2 -0
- package/dashboard/dist/assets/{index-CDWOfCmi.js.map → index-B98ipWxE.js.map} +1 -1
- package/dashboard/dist/assets/{index-D_qEAYrg.js → index-BIG3KooI.js} +2 -2
- package/dashboard/dist/assets/{index-D_qEAYrg.js.map → index-BIG3KooI.js.map} +1 -1
- package/dashboard/dist/assets/{index-DSzSoku1.js → index-BwN3KP_L.js} +91 -93
- package/dashboard/dist/assets/index-BwN3KP_L.js.map +1 -0
- package/dashboard/dist/assets/index-Bxe8h1x4.js +17 -0
- package/dashboard/dist/assets/index-Bxe8h1x4.js.map +1 -0
- package/dashboard/dist/assets/index-CNI7k7oB.js +6 -0
- package/dashboard/dist/assets/index-CNI7k7oB.js.map +1 -0
- package/dashboard/dist/assets/index-CORHB0WC.js +2 -0
- package/dashboard/dist/assets/index-CORHB0WC.js.map +1 -0
- package/dashboard/dist/assets/index-DcIKW-cZ.css +1 -0
- package/dashboard/dist/assets/index-Dj-z-x8M.js +2 -0
- package/dashboard/dist/assets/index-Dj-z-x8M.js.map +1 -0
- package/dashboard/dist/assets/index-DwRytW9O.js +5 -0
- package/dashboard/dist/assets/index-DwRytW9O.js.map +1 -0
- package/dashboard/dist/assets/index-aRvL-dXp.js +2 -0
- package/dashboard/dist/assets/index-aRvL-dXp.js.map +1 -0
- package/dashboard/dist/assets/index-b03HlbnH.js +2 -0
- package/dashboard/dist/assets/{index-BtOwLI0K.js.map → index-b03HlbnH.js.map} +1 -1
- package/dashboard/dist/assets/mcp-BZoFryNc.js +2 -0
- package/dashboard/dist/assets/mcp-BZoFryNc.js.map +1 -0
- package/dashboard/dist/assets/mcp-query-wiw1kwm8.js +2 -0
- package/dashboard/dist/assets/mcp-query-wiw1kwm8.js.map +1 -0
- package/dashboard/dist/assets/{mcp-runs-DmXYJD19.js → mcp-runs-BaEKnf5v.js} +2 -2
- package/dashboard/dist/assets/{mcp-runs-DmXYJD19.js.map → mcp-runs-BaEKnf5v.js.map} +1 -1
- package/dashboard/dist/assets/{namespaces-DoGa7jc7.js → namespaces-BwnZI4_A.js} +2 -2
- package/dashboard/dist/assets/{namespaces-DoGa7jc7.js.map → namespaces-BwnZI4_A.js.map} +1 -1
- package/dashboard/dist/assets/{roles-wCdQ2Z7k.js → roles-Bgn1K8zU.js} +2 -2
- package/dashboard/dist/assets/{roles-wCdQ2Z7k.js.map → roles-Bgn1K8zU.js.map} +1 -1
- package/dashboard/dist/assets/{settings-DDe_L7JT.js → settings-CizYiutL.js} +2 -2
- package/dashboard/dist/assets/{settings-DDe_L7JT.js.map → settings-CizYiutL.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-3Hih8Bt7.js → tasks-Bmte_hc4.js} +2 -2
- package/dashboard/dist/assets/{tasks-3Hih8Bt7.js.map → tasks-Bmte_hc4.js.map} +1 -1
- package/dashboard/dist/assets/useEventHooks-CUCxpiI2.js +2 -0
- package/dashboard/dist/assets/useEventHooks-CUCxpiI2.js.map +1 -0
- package/dashboard/dist/assets/useExpandedRows-Cg9iq6Vy.js +2 -0
- package/dashboard/dist/assets/useExpandedRows-Cg9iq6Vy.js.map +1 -0
- package/dashboard/dist/assets/{useYamlActivityEvents-B5dHec6Y.js → useYamlActivityEvents-Cum02Ej9.js} +2 -2
- package/dashboard/dist/assets/useYamlActivityEvents-Cum02Ej9.js.map +1 -0
- package/dashboard/dist/assets/{users-BTagPmGW.js → users-NSDgTt-z.js} +2 -2
- package/dashboard/dist/assets/{users-BTagPmGW.js.map → users-NSDgTt-z.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-DCLlGYO9.js → vendor-icons-D1DdudfH.js} +141 -66
- package/dashboard/dist/assets/vendor-icons-D1DdudfH.js.map +1 -0
- package/dashboard/dist/assets/{workflows-B20dR3NE.js → workflows-k0XRdGXx.js} +2 -2
- package/dashboard/dist/assets/{workflows-B20dR3NE.js.map → workflows-k0XRdGXx.js.map} +1 -1
- package/dashboard/dist/assets/yaml-workflows-DAre8I78.js +2 -0
- package/dashboard/dist/assets/yaml-workflows-DAre8I78.js.map +1 -0
- package/dashboard/dist/index.html +3 -3
- package/docs/api/mcp-servers.md +60 -2
- package/docs/architecture.md +3 -3
- package/docs/dashboard.md +1 -1
- package/docs/epic-integration.md +224 -0
- package/docs/escalation-strategies.md +2 -3
- package/docs/events.md +28 -0
- package/docs/mcp.md +301 -31
- package/docs/sdk.md +177 -0
- package/docs/story.md +157 -0
- package/docs/workflow-builder.md +371 -0
- package/package.json +5 -4
- package/build/routes/escalations/helpers.d.ts +0 -5
- package/build/routes/resolve.d.ts +0 -9
- package/build/routes/resolve.js +0 -19
- package/build/routes/yaml-workflows/helpers.d.ts +0 -2
- package/build/routes/yaml-workflows/helpers.js +0 -8
- package/dashboard/dist/assets/AdminDashboard-CTyAMUJR.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-BMXV3Q4l.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-BMXV3Q4l.js.map +0 -1
- package/dashboard/dist/assets/BotPicker-C51nKFEu.js +0 -2
- package/dashboard/dist/assets/CredentialsPage-CoBNFSAu.js +0 -2
- package/dashboard/dist/assets/CredentialsPage-CoBNFSAu.js.map +0 -1
- package/dashboard/dist/assets/McpQueryDetailPage-CGoR9XK6.js +0 -5
- package/dashboard/dist/assets/McpQueryDetailPage-CGoR9XK6.js.map +0 -1
- package/dashboard/dist/assets/McpQueryPage-BjXoYQuU.js +0 -2
- package/dashboard/dist/assets/McpQueryPage-BjXoYQuU.js.map +0 -1
- package/dashboard/dist/assets/McpRunDetailPage-DLkA5Aar.js +0 -2
- package/dashboard/dist/assets/McpRunDetailPage-DLkA5Aar.js.map +0 -1
- package/dashboard/dist/assets/McpRunsPage-DCh9n11D.js +0 -2
- package/dashboard/dist/assets/McpRunsPage-DCh9n11D.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-Dc80suXd.js +0 -2
- package/dashboard/dist/assets/OperatorDashboard-Dc80suXd.js.map +0 -1
- package/dashboard/dist/assets/ProcessDetailPage-B2GKuGzk.js +0 -2
- package/dashboard/dist/assets/ProcessDetailPage-B2GKuGzk.js.map +0 -1
- package/dashboard/dist/assets/ProcessesListPage-CTjI3Wn6.js +0 -2
- package/dashboard/dist/assets/ProcessesListPage-CTjI3Wn6.js.map +0 -1
- package/dashboard/dist/assets/RefreshButton-BcQDObrv.js +0 -2
- package/dashboard/dist/assets/RefreshButton-BcQDObrv.js.map +0 -1
- package/dashboard/dist/assets/RunAsSelector-BhyWtofX.js +0 -2
- package/dashboard/dist/assets/RunAsSelector-BhyWtofX.js.map +0 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-DOocX81f.js +0 -2
- package/dashboard/dist/assets/WorkflowExecutionPage-DOocX81f.js.map +0 -1
- package/dashboard/dist/assets/WorkflowPill-Diw8iWBP.js +0 -2
- package/dashboard/dist/assets/WorkflowsDashboard-DDtUIrTy.js +0 -2
- package/dashboard/dist/assets/WorkflowsDashboard-DDtUIrTy.js.map +0 -1
- package/dashboard/dist/assets/YamlWorkflowsPage-DlwwkluN.js +0 -2
- package/dashboard/dist/assets/YamlWorkflowsPage-DlwwkluN.js.map +0 -1
- package/dashboard/dist/assets/helpers-DBUZ9pnG.js +0 -2
- package/dashboard/dist/assets/helpers-DBUZ9pnG.js.map +0 -1
- package/dashboard/dist/assets/index-BOeA-gfK.js +0 -17
- package/dashboard/dist/assets/index-BOeA-gfK.js.map +0 -1
- package/dashboard/dist/assets/index-BZ6K_kmL.js +0 -3
- package/dashboard/dist/assets/index-BZ6K_kmL.js.map +0 -1
- package/dashboard/dist/assets/index-Bpm0yeoi.js +0 -2
- package/dashboard/dist/assets/index-Bpm0yeoi.js.map +0 -1
- package/dashboard/dist/assets/index-BtOwLI0K.js +0 -2
- package/dashboard/dist/assets/index-CBF3ZvRZ.js +0 -6
- package/dashboard/dist/assets/index-CBF3ZvRZ.js.map +0 -1
- package/dashboard/dist/assets/index-CDWOfCmi.js +0 -2
- package/dashboard/dist/assets/index-Ce6sL__n.js +0 -2
- package/dashboard/dist/assets/index-Ce6sL__n.js.map +0 -1
- package/dashboard/dist/assets/index-DSzSoku1.js.map +0 -1
- package/dashboard/dist/assets/index-gCy9XX3W.css +0 -1
- package/dashboard/dist/assets/mcp-BzVpaaKF.js +0 -2
- package/dashboard/dist/assets/mcp-BzVpaaKF.js.map +0 -1
- package/dashboard/dist/assets/mcp-query-wTuxTTCV.js +0 -2
- package/dashboard/dist/assets/mcp-query-wTuxTTCV.js.map +0 -1
- package/dashboard/dist/assets/useNatsEvents-DeGKHFTX.js +0 -2
- package/dashboard/dist/assets/useNatsEvents-DeGKHFTX.js.map +0 -1
- package/dashboard/dist/assets/useYamlActivityEvents-B5dHec6Y.js.map +0 -1
- package/dashboard/dist/assets/vendor-icons-DCLlGYO9.js.map +0 -1
- package/dashboard/dist/assets/yaml-workflows-CaLPMQha.js +0 -2
- package/dashboard/dist/assets/yaml-workflows-CaLPMQha.js.map +0 -1
- package/docs/img/01-login.png +0 -0
- package/docs/img/02-dashboard-home.png +0 -0
- package/docs/img/03-processes-list.png +0 -0
- package/docs/img/04-escalations-list.png +0 -0
- package/docs/img/05-mcp-servers.png +0 -0
- package/docs/img/06-mcp-pipelines.png +0 -0
- package/docs/img/07-workflows-list.png +0 -0
- package/docs/img/compilation/01-query-submit.png +0 -0
- package/docs/img/compilation/02-mcp-servers.png +0 -0
- package/docs/img/compilation/03-query-completed.png +0 -0
- package/docs/img/compilation/04-wizard-original.png +0 -0
- package/docs/img/compilation/05-wizard-timeline.png +0 -0
- package/docs/img/compilation/06-wizard-profile.png +0 -0
- package/docs/img/compilation/07-wizard-deploy.png +0 -0
- package/docs/img/compilation/08-wizard-test-modal.png +0 -0
- package/docs/img/compilation/09-wizard-test-compare.png +0 -0
- package/docs/img/compilation/10-wizard-verify.png +0 -0
- package/lib/db/README.md +0 -8
- /package/{lib → build/lib}/db/schemas/002_seed.sql +0 -0
- /package/{lib → build/lib}/db/schemas/003_workflow_discovery.sql +0 -0
- /package/{lib → build/lib}/db/schemas/004_query_router.sql +0 -0
- /package/{lib → build/lib}/db/schemas/005_triage_router.sql +0 -0
- /package/{lib → build/lib}/db/schemas/006_oauth.sql +0 -0
- /package/{lib → build/lib}/db/schemas/007_security.sql +0 -0
- /package/{lib → build/lib}/db/schemas/008_bot_accounts.sql +0 -0
- /package/{lib → build/lib}/db/schemas/009_audit_trail.sql +0 -0
- /package/{lib → build/lib}/db/schemas/010_credential_providers.sql +0 -0
- /package/{lib → build/lib}/db/schemas/012_drop_modality.sql +0 -0
- /package/{lib → build/lib}/db/schemas/013_execute_as.sql +0 -0
- /package/{lib → build/lib}/db/schemas/014_ephemeral_credentials.sql +0 -0
- /package/{lib → build/lib}/db/schemas/015_knowledge.sql +0 -0
package/docs/mcp.md
CHANGED
|
@@ -4,11 +4,15 @@ Your agents speak MCP. Long Tail makes their tool calls durable and exposes huma
|
|
|
4
4
|
|
|
5
5
|
## Contents
|
|
6
6
|
|
|
7
|
-
- [
|
|
7
|
+
- [Everything is a Tool](#everything-is-a-tool)
|
|
8
|
+
- [Humans as Tools](#humans-as-tools)
|
|
9
|
+
- [Compiled Workflows as Tools](#compiled-workflows-as-tools)
|
|
10
|
+
- [The Cycle](#the-cycle)
|
|
8
11
|
- [Human Queue Server](#human-queue-server) — escalation as MCP tools
|
|
9
12
|
- [Document Vision Server](#document-vision-server) — AI tools as 3 MCP tools
|
|
10
13
|
- [MCP-Native Workflow](#mcp-native-workflow) — both sides MCP, end to end
|
|
11
|
-
- [
|
|
14
|
+
- [Server Registration Lifecycle](#server-registration-lifecycle) — two paths, startup sequence, when things connect
|
|
15
|
+
- [External MCP Servers](#external-mcp-servers) — Path B: dashboard/API registration
|
|
12
16
|
- [Built-in Servers](#built-in-servers) — servers that ship by default
|
|
13
17
|
- [Configuration](#configuration)
|
|
14
18
|
- [REST API](#rest-api) — server registration and management
|
|
@@ -16,14 +20,12 @@ Your agents speak MCP. Long Tail makes their tool calls durable and exposes huma
|
|
|
16
20
|
- [Testing](#testing) — InMemoryTransport and functional tests
|
|
17
21
|
- [Custom Adapters](#custom-adapters)
|
|
18
22
|
|
|
19
|
-
##
|
|
23
|
+
## Everything is a Tool
|
|
20
24
|
|
|
21
25
|
Everything is a tool. Every proxy activity — the functions that workflows call — is an MCP tool. Every collection of related tools is an MCP server. When an engineer writes a workflow, they're composing tool calls. When the triage agent fixes an edge case, it's calling the same tools. When that fix gets compiled into a deterministic pipeline, it becomes a new tool on a new server.
|
|
22
26
|
|
|
23
27
|
The protocol is the same whether the caller is deterministic code, an LLM, or a human clicking a button.
|
|
24
28
|
|
|
25
|
-
### Every Activity is a Tool
|
|
26
|
-
|
|
27
29
|
A proxy activity is a function that runs outside the deterministic sandbox — it makes an API call, queries a database, calls an LLM. HotMesh checkpoints the result. If the process crashes, it replays from cache. The activity isn't called twice.
|
|
28
30
|
|
|
29
31
|
Every one of these activities is also an MCP tool. Register an MCP server and its tools become proxy activities automatically:
|
|
@@ -410,27 +412,209 @@ npx vitest run tests/workflows/verify-document-mcp.test.ts --reporter=verbose
|
|
|
410
412
|
|
|
411
413
|
The examples above use built-in servers. Long Tail can also connect to any external MCP server.
|
|
412
414
|
|
|
415
|
+
## Server Registration Lifecycle
|
|
416
|
+
|
|
417
|
+
When you add an MCP server to Long Tail, two things must happen: the server must be **registered** (so the system knows it exists) and **connected** (so tools are callable). There are two paths depending on where your server runs.
|
|
418
|
+
|
|
419
|
+
### Path A: In-Process (serverFactories)
|
|
420
|
+
|
|
421
|
+
Your MCP server runs inside the Long Tail process. You pass a factory function at startup. The server connects lazily on first tool call via `InMemoryTransport` — no network, no subprocess.
|
|
422
|
+
|
|
423
|
+
```typescript
|
|
424
|
+
import { start } from '@hotmeshio/long-tail';
|
|
425
|
+
|
|
426
|
+
const lt = await start({
|
|
427
|
+
database: { connectionString: process.env.DATABASE_URL },
|
|
428
|
+
mcp: {
|
|
429
|
+
serverFactories: {
|
|
430
|
+
'my-classifier': () => import('./mcp-servers/classifier').then(m => m.createServer()),
|
|
431
|
+
},
|
|
432
|
+
},
|
|
433
|
+
});
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
Your factory is registered alongside the built-in factories. On first tool call, `resolveClient()` invokes the factory, creates an `InMemoryTransport` pair, connects, and caches the client. Subsequent calls reuse the cached connection.
|
|
437
|
+
|
|
438
|
+
To make this server visible in the dashboard and discoverable by tag-based workflows, seed a DB row for it (same pattern as the built-in servers) or register it via the API after startup.
|
|
439
|
+
|
|
440
|
+
This is the path all built-in servers use. It's the right choice when:
|
|
441
|
+
- Your server needs access to in-process state (DB pool, caches, other services)
|
|
442
|
+
- You want zero-latency tool calls (no IPC or network overhead)
|
|
443
|
+
- The server ships as part of your application code
|
|
444
|
+
|
|
445
|
+
### Path B: External (Dashboard or API)
|
|
446
|
+
|
|
447
|
+
Your MCP server runs as a separate process (stdio) or remote service (SSE/Streamable HTTP). You register it via the dashboard wizard or REST API. The system stores the registration in `lt_mcp_servers` and connects via the configured transport.
|
|
448
|
+
|
|
449
|
+
This is the path for:
|
|
450
|
+
- npm MCP server packages (e.g., `@modelcontextprotocol/server-filesystem`)
|
|
451
|
+
- Remote servers running on other machines
|
|
452
|
+
- Servers you want operators to add without redeploying
|
|
453
|
+
|
|
454
|
+
### Startup Sequence
|
|
455
|
+
|
|
456
|
+
Here's what happens when Long Tail boots, and where each path fits:
|
|
457
|
+
|
|
458
|
+
```
|
|
459
|
+
1. migrate() — DB tables created (lt_mcp_servers exists)
|
|
460
|
+
2. Start HotMesh workers — Workflow engines ready
|
|
461
|
+
3. mcpRegistry.connect() — Human queue server starts
|
|
462
|
+
└─ connectAutoServers() — External servers with auto_connect=true connect now
|
|
463
|
+
4. registerBuiltinServer() — All factories stored (system + your serverFactories)
|
|
464
|
+
5. seedSystemMcpServers() — Built-in servers upserted to lt_mcp_servers
|
|
465
|
+
6. HTTP server starts — Dashboard and API available
|
|
466
|
+
7. First tool call — Factory lazily connected via resolveClient()
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
**Path A factories** are registered at step 4 and connected lazily at step 7. They don't need a DB row to function — `resolveClient()` finds them by name in the factory Map. But adding a DB row (step 5 or via API after step 6) makes them visible in the dashboard and discoverable by tag-based workflows.
|
|
470
|
+
|
|
471
|
+
**Path B servers** are stored in the DB (via API at step 6 or pre-seeded). If `auto_connect` is true, they connect at step 3. Otherwise, they connect on demand via `POST /api/mcp/servers/:id/connect` or lazily on first tool call.
|
|
472
|
+
|
|
473
|
+
### Choosing a Path
|
|
474
|
+
|
|
475
|
+
| Consideration | Path A (in-process) | Path B (external) |
|
|
476
|
+
|---------------|--------------------|--------------------|
|
|
477
|
+
| Server location | Same process | Separate process or remote |
|
|
478
|
+
| Connection | InMemoryTransport (zero latency) | stdio / SSE / Streamable HTTP |
|
|
479
|
+
| Registration | `serverFactories` in startup config | Dashboard wizard or REST API |
|
|
480
|
+
| Deployment | Ships with your app code | Independent lifecycle |
|
|
481
|
+
| Access to app state | Yes (DB pool, caches, services) | No (isolated process) |
|
|
482
|
+
| Visibility in dashboard | Needs a DB row (seed or API) | Automatic (stored in DB) |
|
|
483
|
+
|
|
484
|
+
Both paths produce the same outcome: tools callable as durable activities via `proxyActivities()`.
|
|
485
|
+
|
|
413
486
|
## External MCP Servers
|
|
414
487
|
|
|
415
|
-
|
|
488
|
+
This section covers [Path B](#path-b-external-dashboard-or-api) — registering servers via the dashboard or API. For in-process servers, see [Path A](#path-a-in-process-serverfactories) above.
|
|
489
|
+
|
|
490
|
+
Every registration uses the same data model. The dashboard wizard and the REST API are interchangeable views of that data.
|
|
491
|
+
|
|
492
|
+
### The Registration Data Model
|
|
493
|
+
|
|
494
|
+
A server registration is a record with these fields. The dashboard wizard collects them across four steps; the API accepts them as a single JSON payload. Same data, two interfaces.
|
|
495
|
+
|
|
496
|
+
| Field | API field | Wizard step | Description |
|
|
497
|
+
|-------|-----------|-------------|-------------|
|
|
498
|
+
| Name | `name` | Transport | Unique identifier for the server |
|
|
499
|
+
| Description | `description` | Transport | What this server does |
|
|
500
|
+
| Transport type | `transport_type` | Transport | `stdio`, `sse`, or `streamable-http` |
|
|
501
|
+
| Transport config | `transport_config` | Transport | Connection details — command/args/env for stdio, url for network |
|
|
502
|
+
| Auto-connect | `auto_connect` | Transport | Start the connection when Long Tail boots |
|
|
503
|
+
| Tags | `tags` | Discovery | Categorize for tool discovery (e.g., `["database", "analytics"]`) |
|
|
504
|
+
| Compile hints | `compile_hints` | Discovery | Guidance for the workflow compiler |
|
|
505
|
+
| Credential providers | `credential_providers` | Discovery | IAM providers required by tools (e.g., `["github", "openai"]`) |
|
|
506
|
+
|
|
507
|
+
The wizard's **Test** step calls `POST /api/mcp/servers/test-connection` with the transport fields, and the **Review** step shows the full payload before saving.
|
|
508
|
+
|
|
509
|
+
#### Dashboard → API mapping
|
|
510
|
+
|
|
511
|
+
Each wizard step maps directly to API fields:
|
|
512
|
+
|
|
513
|
+
**Step 1 — Transport.** The mode cards select `transport_type` and determine which `transport_config` fields appear:
|
|
514
|
+
|
|
515
|
+
| Mode | `transport_type` | `transport_config` |
|
|
516
|
+
|------|------------------|--------------------|
|
|
517
|
+
| Local Process | `stdio` | `{ "command": "...", "args": [...], "env": {...} }` |
|
|
518
|
+
| Network Service (SSE) | `sse` | `{ "url": "..." }` |
|
|
519
|
+
| Network Service (Streamable HTTP) | `streamable-http` | `{ "url": "..." }` |
|
|
520
|
+
| In-Process | *(managed by the system)* | *(read-only for built-in servers)* |
|
|
521
|
+
|
|
522
|
+
**Step 2 — Discovery.** Maps directly to `tags`, `compile_hints`, and `credential_providers`.
|
|
523
|
+
|
|
524
|
+
**Step 3 — Test.** Calls the test-connection endpoint. No data is persisted.
|
|
525
|
+
|
|
526
|
+
**Step 4 — Review.** Shows the assembled payload. Save calls `POST /api/mcp/servers` (create) or `PUT /api/mcp/servers/:id` (edit).
|
|
527
|
+
|
|
528
|
+
#### When to use each field
|
|
529
|
+
|
|
530
|
+
| Field | When to use |
|
|
531
|
+
|-------|-------------|
|
|
532
|
+
| **Tags** | Always. Good tags make tools discoverable. Workflows like `mcpQuery` filter servers by tags. Use lowercase, hyphenated (e.g., `database`, `image-analysis`). |
|
|
533
|
+
| **Compile hints** | When the workflow compiler needs to know about tool ordering, timeouts, retry behavior, or output formats. |
|
|
534
|
+
| **Credential providers** | When tools call external APIs that need user-specific credentials. Users are prompted to connect via the Credentials page before tool execution. |
|
|
535
|
+
| **Auto-connect** | For servers you always want available. Skip for infrequently used servers. |
|
|
536
|
+
|
|
537
|
+
### How to Register: Three Scenarios
|
|
538
|
+
|
|
539
|
+
The registration data model is the same in all three scenarios. Only the transport config differs.
|
|
540
|
+
|
|
541
|
+
#### Scenario 1: npm MCP Server Package
|
|
542
|
+
|
|
543
|
+
Many MCP servers are published to npm (`@modelcontextprotocol/server-filesystem`, `@modelcontextprotocol/server-github`, `mcp-server-sqlite`). No wrapper code needed — install the package and register.
|
|
544
|
+
|
|
545
|
+
There are two binding strategies:
|
|
546
|
+
|
|
547
|
+
**Early-bound (production)** — install as a dependency, ship in the Docker image:
|
|
548
|
+
|
|
549
|
+
```bash
|
|
550
|
+
npm install @modelcontextprotocol/server-filesystem
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
```json
|
|
554
|
+
{
|
|
555
|
+
"transport_type": "stdio",
|
|
556
|
+
"transport_config": {
|
|
557
|
+
"command": "node",
|
|
558
|
+
"args": ["node_modules/@modelcontextprotocol/server-filesystem/dist/index.js", "/data"]
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
The package is in `package.json`, locked by `package-lock.json`, built into the image. Deterministic, auditable, no network call at runtime.
|
|
564
|
+
|
|
565
|
+
**Late-bound (exploration)** — pull on demand via `npx`:
|
|
566
|
+
|
|
567
|
+
```json
|
|
568
|
+
{
|
|
569
|
+
"transport_type": "stdio",
|
|
570
|
+
"transport_config": {
|
|
571
|
+
"command": "npx",
|
|
572
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/data"]
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
The package isn't in your repo, lockfile, or Docker image. It's resolved at runtime — downloaded on first spawn, cached for subsequent connections. Useful for trying out a server without committing to a dependency, or environments where operators add servers without redeploying.
|
|
578
|
+
|
|
579
|
+
Long Tail serves as the registry that decides which servers to connect, when to spawn them, and how they wire into workflows. The binding strategy is a transport detail.
|
|
580
|
+
|
|
581
|
+
**Dashboard:** Select **Local Process**, enter the command and args, walk through Discovery/Test/Review.
|
|
416
582
|
|
|
417
|
-
|
|
583
|
+
**API:**
|
|
418
584
|
|
|
419
585
|
```bash
|
|
420
586
|
curl -X POST http://localhost:3000/api/mcp/servers \
|
|
421
587
|
-H 'Content-Type: application/json' \
|
|
422
588
|
-d '{
|
|
423
|
-
"name": "
|
|
589
|
+
"name": "filesystem",
|
|
424
590
|
"transport_type": "stdio",
|
|
425
591
|
"transport_config": {
|
|
426
592
|
"command": "npx",
|
|
427
|
-
"args": ["-y", "
|
|
593
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/data"]
|
|
428
594
|
},
|
|
429
|
-
"auto_connect": true
|
|
595
|
+
"auto_connect": true,
|
|
596
|
+
"tags": ["files", "storage"]
|
|
430
597
|
}'
|
|
431
598
|
```
|
|
432
599
|
|
|
433
|
-
|
|
600
|
+
#### Scenario 2: Remote Server
|
|
601
|
+
|
|
602
|
+
Point Long Tail at a URL. The server runs elsewhere.
|
|
603
|
+
|
|
604
|
+
```json
|
|
605
|
+
{
|
|
606
|
+
"transport_type": "sse",
|
|
607
|
+
"transport_config": {
|
|
608
|
+
"url": "https://my-server.example.com/mcp"
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
For Streamable HTTP, use `"transport_type": "streamable-http"`. Same `transport_config`.
|
|
614
|
+
|
|
615
|
+
**Dashboard:** Select **Network Service**, enter the URL, choose SSE or Streamable HTTP, walk through Discovery/Test/Review.
|
|
616
|
+
|
|
617
|
+
**API:**
|
|
434
618
|
|
|
435
619
|
```bash
|
|
436
620
|
curl -X POST http://localhost:3000/api/mcp/servers \
|
|
@@ -438,15 +622,99 @@ curl -X POST http://localhost:3000/api/mcp/servers \
|
|
|
438
622
|
-d '{
|
|
439
623
|
"name": "my-remote-server",
|
|
440
624
|
"transport_type": "sse",
|
|
625
|
+
"transport_config": { "url": "https://my-server.example.com/mcp" },
|
|
626
|
+
"tags": ["api", "external"]
|
|
627
|
+
}'
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
#### Scenario 3: Build Your Own
|
|
631
|
+
|
|
632
|
+
Write a custom MCP server, then register it the same way as Scenarios 1 or 2.
|
|
633
|
+
|
|
634
|
+
**Create the server** using the MCP SDK:
|
|
635
|
+
|
|
636
|
+
```typescript
|
|
637
|
+
// my-server.ts
|
|
638
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
639
|
+
import { z } from 'zod';
|
|
640
|
+
|
|
641
|
+
const server = new McpServer({ name: 'my-tools', version: '1.0.0' });
|
|
642
|
+
|
|
643
|
+
server.tool('classify_document',
|
|
644
|
+
{ content: z.string() },
|
|
645
|
+
async ({ content }) => {
|
|
646
|
+
const result = await yourClassificationLogic(content);
|
|
647
|
+
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
648
|
+
},
|
|
649
|
+
);
|
|
650
|
+
|
|
651
|
+
export default server;
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
**Make it runnable** via stdio (simplest):
|
|
655
|
+
|
|
656
|
+
```typescript
|
|
657
|
+
// bin/serve.ts
|
|
658
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
659
|
+
import server from './my-server';
|
|
660
|
+
|
|
661
|
+
const transport = new StdioServerTransport();
|
|
662
|
+
await server.connect(transport);
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
**Register it.** The transport config points at your command — same as any stdio server:
|
|
666
|
+
|
|
667
|
+
```json
|
|
668
|
+
{
|
|
669
|
+
"transport_type": "stdio",
|
|
670
|
+
"transport_config": { "command": "node", "args": ["dist/bin/serve.js"] }
|
|
671
|
+
}
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
For in-process servers that run inside the Long Tail process, see the [Writing Your Own MCP Server](#writing-your-own-mcp-server) section above and the architecture guide's [Registering Your Own](architecture.md#registering-your-own) section.
|
|
675
|
+
|
|
676
|
+
### Test Connection
|
|
677
|
+
|
|
678
|
+
Test connectivity without saving a registration. The dashboard wizard's Test step and the API endpoint do the same thing — send transport fields, get back a tool list or error.
|
|
679
|
+
|
|
680
|
+
**Dashboard:** Click "Test Connection" on the Test step.
|
|
681
|
+
|
|
682
|
+
**API:**
|
|
683
|
+
|
|
684
|
+
```bash
|
|
685
|
+
curl -X POST http://localhost:3000/api/mcp/servers/test-connection \
|
|
686
|
+
-H 'Content-Type: application/json' \
|
|
687
|
+
-d '{
|
|
688
|
+
"transport_type": "stdio",
|
|
441
689
|
"transport_config": {
|
|
442
|
-
"
|
|
443
|
-
|
|
444
|
-
|
|
690
|
+
"command": "npx",
|
|
691
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
|
|
692
|
+
}
|
|
693
|
+
}'
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
Returns `{ "success": true, "tools": [...] }` on success, or `{ "success": false, "error": "..." }` on failure.
|
|
697
|
+
|
|
698
|
+
### Edit a Registration
|
|
699
|
+
|
|
700
|
+
**Dashboard:** Click any server row in **MCP > Servers** to open the detail page. All fields are editable. Built-in servers show read-only transport config but allow editing tags, hints, and credential providers.
|
|
701
|
+
|
|
702
|
+
**API:** `PUT /api/mcp/servers/:id` with any fields to update:
|
|
703
|
+
|
|
704
|
+
```bash
|
|
705
|
+
curl -X PUT http://localhost:3000/api/mcp/servers/$ID \
|
|
706
|
+
-H 'Content-Type: application/json' \
|
|
707
|
+
-d '{
|
|
708
|
+
"tags": ["database", "analytics"],
|
|
709
|
+
"compile_hints": "Returns paginated results. Always pass limit.",
|
|
710
|
+
"credential_providers": ["postgres"]
|
|
445
711
|
}'
|
|
446
712
|
```
|
|
447
713
|
|
|
448
714
|
### Use in a Workflow
|
|
449
715
|
|
|
716
|
+
Once registered, a server's tools are available as durable activities:
|
|
717
|
+
|
|
450
718
|
```typescript
|
|
451
719
|
import { Durable } from '@hotmeshio/hotmesh';
|
|
452
720
|
import { McpClient } from '@hotmeshio/long-tail';
|
|
@@ -482,8 +750,6 @@ Tool names are derived from the server name and tool name: `mcp_{serverName}_{to
|
|
|
482
750
|
|
|
483
751
|
If the process crashes between an MCP tool call and its checkpoint, HotMesh replays from cache. The external server is not called a second time. This gives you exactly-once semantics over a protocol that doesn't natively guarantee them.
|
|
484
752
|
|
|
485
|
-
Server registration can happen at runtime via the REST API (shown above) or at startup via configuration.
|
|
486
|
-
|
|
487
753
|
## Built-in Servers
|
|
488
754
|
|
|
489
755
|
Long Tail ships with built-in MCP servers. For descriptions, see the [architecture guide](architecture.md#built-in-mcp-servers).
|
|
@@ -562,6 +828,7 @@ All routes are mounted at `/api/mcp`.
|
|
|
562
828
|
|
|
563
829
|
| Method | Path | Description |
|
|
564
830
|
|--------|------|-------------|
|
|
831
|
+
| `POST` | `/api/mcp/servers/test-connection` | Test connectivity without saving |
|
|
565
832
|
| `POST` | `/api/mcp/servers/:id/connect` | Connect to a server |
|
|
566
833
|
| `POST` | `/api/mcp/servers/:id/disconnect` | Disconnect from a server |
|
|
567
834
|
|
|
@@ -588,21 +855,22 @@ MCP server registrations are stored in `lt_mcp_servers`:
|
|
|
588
855
|
|
|
589
856
|
```sql
|
|
590
857
|
CREATE TABLE IF NOT EXISTS lt_mcp_servers (
|
|
591
|
-
id
|
|
592
|
-
name
|
|
593
|
-
description
|
|
594
|
-
transport_type
|
|
595
|
-
transport_config
|
|
596
|
-
auto_connect
|
|
597
|
-
tool_manifest
|
|
598
|
-
tags
|
|
599
|
-
compile_hints
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
858
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
859
|
+
name TEXT UNIQUE NOT NULL,
|
|
860
|
+
description TEXT,
|
|
861
|
+
transport_type TEXT NOT NULL CHECK (transport_type IN ('stdio', 'sse', 'streamable-http')),
|
|
862
|
+
transport_config JSONB NOT NULL DEFAULT '{}'::JSONB,
|
|
863
|
+
auto_connect BOOLEAN NOT NULL DEFAULT false,
|
|
864
|
+
tool_manifest JSONB, -- cached from last listTools()
|
|
865
|
+
tags TEXT[], -- categorization for tag-based tool discovery
|
|
866
|
+
compile_hints TEXT, -- per-server instructions for the compilation pipeline
|
|
867
|
+
credential_providers TEXT[] DEFAULT '{}', -- IAM providers required by tools
|
|
868
|
+
status TEXT NOT NULL DEFAULT 'registered'
|
|
869
|
+
CHECK (status IN ('registered', 'connected', 'error', 'disconnected')),
|
|
870
|
+
last_connected_at TIMESTAMPTZ,
|
|
871
|
+
metadata JSONB,
|
|
872
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
873
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
606
874
|
);
|
|
607
875
|
```
|
|
608
876
|
|
|
@@ -612,6 +880,8 @@ The `tags` column is a PostgreSQL text array with a GIN index, enabling fast tag
|
|
|
612
880
|
|
|
613
881
|
The `compile_hints` column stores per-server instructions that are injected into the compilation prompt when that server's tools appear in an execution trace. This lets each server provide tool-specific constraints (e.g., timeout requirements, retry policies, ordering rules) that guide the compiler when converting dynamic executions into deterministic workflows.
|
|
614
882
|
|
|
883
|
+
The `credential_providers` column lists IAM credential providers required by the server's tools. When a user invokes a tool, the system checks whether they have registered credentials for each listed provider. Missing credentials trigger a `MissingCredentialError` with the provider name, prompting the user to connect via the Credentials page.
|
|
884
|
+
|
|
615
885
|
The schema is created automatically by `migrate()`. See `services/db/schemas/001_initial.sql`.
|
|
616
886
|
|
|
617
887
|
The test suite verifies the full MCP protocol against real PostgreSQL — no mocks.
|
package/docs/sdk.md
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# SDK
|
|
2
|
+
|
|
3
|
+
Long Tail exposes its full API as an in-process SDK. Every operation available through the REST API can be called directly as a function — same validation, same RBAC, same event publishing — without HTTP transport overhead.
|
|
4
|
+
|
|
5
|
+
Use the SDK when Long Tail runs as an embedded package inside your own application (NestJS, Next.js, Express, or any Node.js process). The HTTP server, socket.io, and dashboard are optional — disable them and call the SDK directly.
|
|
6
|
+
|
|
7
|
+
## Setup
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { start, createClient } from '@hotmeshio/long-tail';
|
|
11
|
+
|
|
12
|
+
// Start without HTTP server
|
|
13
|
+
await start({
|
|
14
|
+
database: { connectionString: process.env.DATABASE_URL },
|
|
15
|
+
server: { enabled: false },
|
|
16
|
+
workers: [{ taskQueue: 'default', workflow: myWorkflow.handler }],
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// Create a client with a default auth context
|
|
20
|
+
const lt = createClient({ auth: { userId: 'my-service' } });
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The `auth` context binds to every call that requires it. Override per-call when needed:
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
// Uses the default auth ('my-service')
|
|
27
|
+
await lt.escalations.list({ status: 'pending' });
|
|
28
|
+
|
|
29
|
+
// Override for a specific call
|
|
30
|
+
await lt.escalations.claim({ id: 'esc_123' }, { userId: 'user-456' });
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## LTApiResult
|
|
34
|
+
|
|
35
|
+
Every SDK call returns an `LTApiResult`:
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
interface LTApiResult<T = any> {
|
|
39
|
+
status: number; // HTTP-equivalent status code (200, 400, 403, 404, 409, 500)
|
|
40
|
+
data?: T; // Success payload (present when status is 2xx)
|
|
41
|
+
error?: string; // Error message (present when status is 4xx/5xx)
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Status codes follow the same semantics as the REST API. Check `result.status` to distinguish success from failure:
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
const result = await lt.tasks.get({ id: 'task-123' });
|
|
49
|
+
|
|
50
|
+
if (result.status === 200) {
|
|
51
|
+
console.log(result.data); // the task record
|
|
52
|
+
} else if (result.status === 404) {
|
|
53
|
+
console.log('not found');
|
|
54
|
+
} else {
|
|
55
|
+
console.error(result.error);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## API Namespaces
|
|
60
|
+
|
|
61
|
+
The client mirrors the REST route structure:
|
|
62
|
+
|
|
63
|
+
| Namespace | REST equivalent | Key operations |
|
|
64
|
+
|-----------|----------------|----------------|
|
|
65
|
+
| `lt.tasks` | `/api/tasks` | `list`, `get`, `listProcesses`, `getProcess`, `getProcessStats` |
|
|
66
|
+
| `lt.escalations` | `/api/escalations` | `list`, `listAvailable`, `get`, `claim`, `release`, `resolve`, `escalate`, `bulkClaim`, `bulkAssign` |
|
|
67
|
+
| `lt.workflows` | `/api/workflows` | `invoke`, `getStatus`, `getResult`, `terminate`, `listWorkers`, `listDiscovered`, `listConfigs`, `getConfig`, `upsertConfig` |
|
|
68
|
+
| `lt.yamlWorkflows` | `/api/yaml-workflows` | `list`, `get`, `create`, `deploy`, `activate`, `invoke`, `archive` |
|
|
69
|
+
| `lt.users` | `/api/users` | `list`, `get`, `create`, `update`, `delete`, `getRoles`, `addRole`, `removeRole` |
|
|
70
|
+
| `lt.roles` | `/api/roles` | `list`, `listWithDetails`, `create`, `delete`, `getEscalationChains` |
|
|
71
|
+
| `lt.auth` | `/api/auth` | `login` |
|
|
72
|
+
| `lt.mcp` | `/api/mcp` | `listServers`, `createServer`, `getServer`, `connectServer`, `listTools`, `callTool` |
|
|
73
|
+
| `lt.mcpRuns` | `/api/mcp-runs` | `listEntities`, `listJobs`, `getExecution` |
|
|
74
|
+
| `lt.insight` | `/api/insight` | `mcpQuery`, `buildWorkflow`, `refineWorkflow`, `describeWorkflow` |
|
|
75
|
+
| `lt.exports` | `/api/workflow-states` | `listJobs`, `exportState`, `exportExecution`, `getStatus`, `getState` |
|
|
76
|
+
| `lt.controlplane` | `/api/controlplane` | `listApps`, `rollCall`, `throttle`, `getStreamStats` |
|
|
77
|
+
| `lt.botAccounts` | `/api/bot-accounts` | `list`, `get`, `create`, `update`, `delete`, `listKeys`, `createKey` |
|
|
78
|
+
| `lt.workflowSets` | `/api/workflow-sets` | `create`, `list`, `get`, `updatePlan`, `build`, `deploy` |
|
|
79
|
+
| `lt.settings` | `/api/settings` | `get` |
|
|
80
|
+
| `lt.dba` | `/api/dba` | `prune`, `deploy` |
|
|
81
|
+
| `lt.namespaces` | `/api/namespaces` | `list`, `register` |
|
|
82
|
+
| `lt.maintenance` | `/api/config/maintenance` | `getConfig`, `updateConfig` |
|
|
83
|
+
|
|
84
|
+
## Events
|
|
85
|
+
|
|
86
|
+
The SDK includes a callback-based event adapter. Subscribe to events directly — no socket.io client, no WebSocket connection.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
// Exact event type
|
|
90
|
+
const unsub = lt.events.on('escalation.claimed', (event) => {
|
|
91
|
+
console.log('claimed:', event.escalationId, 'by:', event.data?.assigned_to);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Category wildcard — matches all task.* events
|
|
95
|
+
lt.events.on('task.*', (event) => {
|
|
96
|
+
metrics.increment(`task.${event.type}`);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Global wildcard — every event
|
|
100
|
+
lt.events.on('*', (event) => {
|
|
101
|
+
auditLog.append(event);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Unsubscribe when done
|
|
105
|
+
unsub();
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Events fire from the same publish calls that feed socket.io and NATS. The callback adapter runs in-process with zero serialization overhead. All event types documented in [Events](events.md) are available.
|
|
109
|
+
|
|
110
|
+
### Event types
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
task.created task.started task.completed task.escalated task.failed
|
|
114
|
+
escalation.created escalation.claimed escalation.released escalation.resolved
|
|
115
|
+
workflow.started workflow.completed workflow.failed
|
|
116
|
+
activity.started activity.completed activity.failed
|
|
117
|
+
milestone
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Running Alongside an HTTP Server
|
|
121
|
+
|
|
122
|
+
The SDK works whether or not the HTTP server is running. If your application already has its own Express/Fastify/Koa server, you can start Long Tail without its built-in server and expose routes however you like:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
// Your NestJS controller
|
|
126
|
+
@Controller('workflows')
|
|
127
|
+
export class WorkflowController {
|
|
128
|
+
private lt = createClient({ auth: { userId: 'nest-service' } });
|
|
129
|
+
|
|
130
|
+
@Post(':type/invoke')
|
|
131
|
+
async invoke(@Param('type') type: string, @Body() body: any) {
|
|
132
|
+
return this.lt.workflows.invoke({ type, data: body.data });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@Get(':id/status')
|
|
136
|
+
async status(@Param('id') id: string) {
|
|
137
|
+
return this.lt.workflows.getStatus({ workflowId: id });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## CallbackEventAdapter
|
|
143
|
+
|
|
144
|
+
If you need lower-level control over event subscriptions, use the `CallbackEventAdapter` directly:
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
import { eventRegistry, CallbackEventAdapter } from '@hotmeshio/long-tail';
|
|
148
|
+
|
|
149
|
+
const adapter = new CallbackEventAdapter();
|
|
150
|
+
eventRegistry.register(adapter);
|
|
151
|
+
await adapter.connect();
|
|
152
|
+
|
|
153
|
+
// Subscribe
|
|
154
|
+
const unsub = adapter.on('task.completed', (event) => { ... });
|
|
155
|
+
|
|
156
|
+
// Unsubscribe
|
|
157
|
+
unsub();
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
The `createClient()` function manages this automatically — you only need the adapter directly if you want event subscriptions without the full SDK client.
|
|
161
|
+
|
|
162
|
+
## Mixing Transports
|
|
163
|
+
|
|
164
|
+
The event registry supports multiple adapters simultaneously. Events publish to all registered adapters in parallel:
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
await start({
|
|
168
|
+
database: { connectionString: process.env.DATABASE_URL },
|
|
169
|
+
server: { enabled: false },
|
|
170
|
+
events: { nats: { url: 'nats://localhost:4222' } }, // NATS for external consumers
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const lt = createClient({ auth: { userId: 'system' } });
|
|
174
|
+
|
|
175
|
+
// In-process callbacks AND NATS — both receive every event
|
|
176
|
+
lt.events.on('task.*', handleTaskLocally);
|
|
177
|
+
```
|