indusagi 0.13.6 → 0.13.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/LICENSE +661 -0
- package/README.md +7 -1
- package/dist/cli.js +114 -23
- package/package.json +54 -47
- package/dist/agent.js +0 -28713
- package/dist/ai.js +0 -19964
- package/dist/capabilities.js +0 -2730
- package/dist/connectors-saas.js +0 -3355
- package/dist/index.js +0 -16644
- package/dist/interop.js +0 -3247
- package/dist/knowledge/guides/authoring-an-agent.md +0 -53
- package/dist/knowledge/guides/choosing-tools.md +0 -49
- package/dist/knowledge/guides/model-selection.md +0 -51
- package/dist/knowledge/guides/writing-system-prompts.md +0 -53
- package/dist/knowledge/index.ts +0 -19
- package/dist/knowledge/loader.ts +0 -200
- package/dist/knowledge/manifest.json +0 -29
- package/dist/llmgateway.js +0 -3243
- package/dist/mcp.js +0 -1639
- package/dist/memory.js +0 -0
- package/dist/react-host/index.js +0 -101
- package/dist/react-host/ink.js +0 -97
- package/dist/react-host/jsx-runtime.js +0 -95
- package/dist/react-ink.js +0 -3834
- package/dist/runtime.js +0 -4421
- package/dist/shell-app.js +0 -12333
- package/dist/smithy.js +0 -8033
- package/dist/swarm.js +0 -8818
- package/dist/tracing.js +0 -724
- package/dist/tui.js +0 -2213
- package/dist/types/capabilities/backends/index.d.ts +0 -10
- package/dist/types/capabilities/backends/node-backends.d.ts +0 -30
- package/dist/types/capabilities/capabilities.test.d.ts +0 -14
- package/dist/types/capabilities/files/diff.d.ts +0 -49
- package/dist/types/capabilities/files/edit.d.ts +0 -21
- package/dist/types/capabilities/files/ls.d.ts +0 -16
- package/dist/types/capabilities/files/read-state-gate.d.ts +0 -69
- package/dist/types/capabilities/files/read-state-gate.test.d.ts +0 -14
- package/dist/types/capabilities/files/read.d.ts +0 -15
- package/dist/types/capabilities/files/write.d.ts +0 -16
- package/dist/types/capabilities/index.d.ts +0 -29
- package/dist/types/capabilities/kernel/backends.d.ts +0 -119
- package/dist/types/capabilities/kernel/context.d.ts +0 -52
- package/dist/types/capabilities/kernel/index.d.ts +0 -24
- package/dist/types/capabilities/kernel/output.d.ts +0 -40
- package/dist/types/capabilities/kernel/registry.d.ts +0 -61
- package/dist/types/capabilities/kernel/spec.d.ts +0 -168
- package/dist/types/capabilities/planning/todo.d.ts +0 -62
- package/dist/types/capabilities/registry.d.ts +0 -44
- package/dist/types/capabilities/search/find.d.ts +0 -33
- package/dist/types/capabilities/search/grep.d.ts +0 -30
- package/dist/types/capabilities/shell/bash.d.ts +0 -18
- package/dist/types/capabilities/shell/process.d.ts +0 -33
- package/dist/types/capabilities/web/webfetch.d.ts +0 -25
- package/dist/types/capabilities/web/websearch.d.ts +0 -23
- package/dist/types/connectors-saas/connectors-saas.test.d.ts +0 -12
- package/dist/types/connectors-saas/index.d.ts +0 -16
- package/dist/types/connectors-saas/saas/adapter/composio-backend.d.ts +0 -60
- package/dist/types/connectors-saas/saas/control/connect.d.ts +0 -114
- package/dist/types/connectors-saas/saas/control/tools.d.ts +0 -67
- package/dist/types/connectors-saas/saas/core/builder.d.ts +0 -86
- package/dist/types/connectors-saas/saas/core/cache.d.ts +0 -53
- package/dist/types/connectors-saas/saas/core/index.d.ts +0 -14
- package/dist/types/connectors-saas/saas/core/port.d.ts +0 -157
- package/dist/types/connectors-saas/saas/core/scope-planner.d.ts +0 -74
- package/dist/types/connectors-saas/saas/gateway.d.ts +0 -133
- package/dist/types/connectors-saas/saas/render/format.d.ts +0 -54
- package/dist/types/connectors-saas/saas/render/index.d.ts +0 -19
- package/dist/types/connectors-saas/saas/render/summarizers.d.ts +0 -58
- package/dist/types/facade/agent.d.ts +0 -1
- package/dist/types/facade/ai.d.ts +0 -1
- package/dist/types/facade/bot/actions/bash.d.ts +0 -71
- package/dist/types/facade/bot/actions/bash.test.d.ts +0 -1
- package/dist/types/facade/bot/actions/checkpoint.d.ts +0 -49
- package/dist/types/facade/bot/actions/checkpoint.test.d.ts +0 -1
- package/dist/types/facade/bot/actions/composio/accounts.d.ts +0 -22
- package/dist/types/facade/bot/actions/composio/client.d.ts +0 -39
- package/dist/types/facade/bot/actions/composio/connect.d.ts +0 -19
- package/dist/types/facade/bot/actions/composio/enable.d.ts +0 -25
- package/dist/types/facade/bot/actions/composio/execute.d.ts +0 -26
- package/dist/types/facade/bot/actions/composio/helpers.d.ts +0 -16
- package/dist/types/facade/bot/actions/composio/index.d.ts +0 -9
- package/dist/types/facade/bot/actions/composio/provider.d.ts +0 -8
- package/dist/types/facade/bot/actions/composio/toolkits.d.ts +0 -22
- package/dist/types/facade/bot/actions/composio/tools.d.ts +0 -28
- package/dist/types/facade/bot/actions/composio/types.d.ts +0 -137
- package/dist/types/facade/bot/actions/crew/activity-tracker.d.ts +0 -65
- package/dist/types/facade/bot/actions/crew/cleanup.d.ts +0 -50
- package/dist/types/facade/bot/actions/crew/fs-lock.d.ts +0 -11
- package/dist/types/facade/bot/actions/crew/index.d.ts +0 -11
- package/dist/types/facade/bot/actions/crew/mailbox.d.ts +0 -20
- package/dist/types/facade/bot/actions/crew/model-policy.d.ts +0 -22
- package/dist/types/facade/bot/actions/crew/names.d.ts +0 -27
- package/dist/types/facade/bot/actions/crew/protocol.d.ts +0 -74
- package/dist/types/facade/bot/actions/crew/task-store.d.ts +0 -88
- package/dist/types/facade/bot/actions/crew/team-attach-claim.d.ts +0 -35
- package/dist/types/facade/bot/actions/crew/team-config.d.ts +0 -54
- package/dist/types/facade/bot/actions/crew/worktree.d.ts +0 -39
- package/dist/types/facade/bot/actions/edit-diff.d.ts +0 -66
- package/dist/types/facade/bot/actions/edit-utils.d.ts +0 -86
- package/dist/types/facade/bot/actions/edit.d.ts +0 -59
- package/dist/types/facade/bot/actions/edit.test.d.ts +0 -1
- package/dist/types/facade/bot/actions/find.d.ts +0 -27
- package/dist/types/facade/bot/actions/find.test.d.ts +0 -1
- package/dist/types/facade/bot/actions/grep.d.ts +0 -53
- package/dist/types/facade/bot/actions/grep.test.d.ts +0 -1
- package/dist/types/facade/bot/actions/index.d.ts +0 -316
- package/dist/types/facade/bot/actions/kit/hook-runner.d.ts +0 -12
- package/dist/types/facade/bot/actions/kit/image-resize.d.ts +0 -19
- package/dist/types/facade/bot/actions/kit/mime.d.ts +0 -1
- package/dist/types/facade/bot/actions/kit/shell.d.ts +0 -12
- package/dist/types/facade/bot/actions/ls.d.ts +0 -41
- package/dist/types/facade/bot/actions/path-utils.d.ts +0 -8
- package/dist/types/facade/bot/actions/process-controller.d.ts +0 -14
- package/dist/types/facade/bot/actions/process-manager.d.ts +0 -59
- package/dist/types/facade/bot/actions/process-types.d.ts +0 -73
- package/dist/types/facade/bot/actions/process.d.ts +0 -37
- package/dist/types/facade/bot/actions/read-state.d.ts +0 -83
- package/dist/types/facade/bot/actions/read-state.test.d.ts +0 -1
- package/dist/types/facade/bot/actions/read.d.ts +0 -43
- package/dist/types/facade/bot/actions/read.test.d.ts +0 -1
- package/dist/types/facade/bot/actions/registry.d.ts +0 -20
- package/dist/types/facade/bot/actions/sandbox-backend.d.ts +0 -99
- package/dist/types/facade/bot/actions/sandbox-backend.test.d.ts +0 -1
- package/dist/types/facade/bot/actions/todo-store.d.ts +0 -76
- package/dist/types/facade/bot/actions/todo-types.d.ts +0 -72
- package/dist/types/facade/bot/actions/todo.d.ts +0 -76
- package/dist/types/facade/bot/actions/truncate.d.ts +0 -78
- package/dist/types/facade/bot/actions/webfetch.d.ts +0 -35
- package/dist/types/facade/bot/actions/websearch.d.ts +0 -37
- package/dist/types/facade/bot/actions/websearch.test.d.ts +0 -1
- package/dist/types/facade/bot/actions/write.d.ts +0 -45
- package/dist/types/facade/bot/agent-loop.d.ts +0 -30
- package/dist/types/facade/bot/agent-loop.test.d.ts +0 -1
- package/dist/types/facade/bot/agent.d.ts +0 -140
- package/dist/types/facade/bot/error-handler.d.ts +0 -7
- package/dist/types/facade/bot/event-bus.d.ts +0 -8
- package/dist/types/facade/bot/index.d.ts +0 -7
- package/dist/types/facade/bot/messages.d.ts +0 -83
- package/dist/types/facade/bot/permission-gate.test.d.ts +0 -1
- package/dist/types/facade/bot/proxy.d.ts +0 -70
- package/dist/types/facade/bot/session-manager.d.ts +0 -409
- package/dist/types/facade/bot/state-manager.d.ts +0 -21
- package/dist/types/facade/bot/telemetry.d.ts +0 -6
- package/dist/types/facade/bot/types.d.ts +0 -267
- package/dist/types/facade/mcp-core/client-pool.d.ts +0 -105
- package/dist/types/facade/mcp-core/client.d.ts +0 -213
- package/dist/types/facade/mcp-core/client.test.d.ts +0 -18
- package/dist/types/facade/mcp-core/config.d.ts +0 -60
- package/dist/types/facade/mcp-core/errors.d.ts +0 -103
- package/dist/types/facade/mcp-core/index.d.ts +0 -55
- package/dist/types/facade/mcp-core/schema-converter.d.ts +0 -67
- package/dist/types/facade/mcp-core/server.d.ts +0 -110
- package/dist/types/facade/mcp-core/tool-factory.d.ts +0 -62
- package/dist/types/facade/mcp-core/types.d.ts +0 -298
- package/dist/types/facade/mcp.d.ts +0 -1
- package/dist/types/facade/memory.d.ts +0 -1
- package/dist/types/facade/ml/adapters/amazon-bedrock.d.ts +0 -32
- package/dist/types/facade/ml/adapters/anthropic-retry.test.d.ts +0 -1
- package/dist/types/facade/ml/adapters/anthropic.d.ts +0 -78
- package/dist/types/facade/ml/adapters/azure-openai-responses.d.ts +0 -14
- package/dist/types/facade/ml/adapters/google-shared.d.ts +0 -99
- package/dist/types/facade/ml/adapters/google-vertex.d.ts +0 -14
- package/dist/types/facade/ml/adapters/google.d.ts +0 -15
- package/dist/types/facade/ml/adapters/kimi.d.ts +0 -21
- package/dist/types/facade/ml/adapters/mock.d.ts +0 -9
- package/dist/types/facade/ml/adapters/nvidia.d.ts +0 -12
- package/dist/types/facade/ml/adapters/openai-codex-responses.d.ts +0 -8
- package/dist/types/facade/ml/adapters/openai-completions.d.ts +0 -24
- package/dist/types/facade/ml/adapters/openai-responses-shared.d.ts +0 -25
- package/dist/types/facade/ml/adapters/openai-responses.d.ts +0 -12
- package/dist/types/facade/ml/adapters/openai-scaffold.d.ts +0 -3
- package/dist/types/facade/ml/adapters/register-builtins.d.ts +0 -2
- package/dist/types/facade/ml/adapters/simple-options.d.ts +0 -39
- package/dist/types/facade/ml/adapters/simple-options.test.d.ts +0 -1
- package/dist/types/facade/ml/adapters/transform-messages.d.ts +0 -23
- package/dist/types/facade/ml/api-registry.d.ts +0 -49
- package/dist/types/facade/ml/cli.d.ts +0 -2
- package/dist/types/facade/ml/env-api-keys.d.ts +0 -19
- package/dist/types/facade/ml/index.d.ts +0 -27
- package/dist/types/facade/ml/kit/auth/anthropic.d.ts +0 -17
- package/dist/types/facade/ml/kit/auth/github-copilot.d.ts +0 -22
- package/dist/types/facade/ml/kit/auth/index.d.ts +0 -50
- package/dist/types/facade/ml/kit/auth/kimi.d.ts +0 -23
- package/dist/types/facade/ml/kit/auth/oauth-page.d.ts +0 -2
- package/dist/types/facade/ml/kit/auth/openai-codex.d.ts +0 -36
- package/dist/types/facade/ml/kit/auth/pkce.d.ts +0 -12
- package/dist/types/facade/ml/kit/auth/types.d.ts +0 -67
- package/dist/types/facade/ml/kit/base-stream-handler.d.ts +0 -30
- package/dist/types/facade/ml/kit/event-stream.d.ts +0 -63
- package/dist/types/facade/ml/kit/index.d.ts +0 -14
- package/dist/types/facade/ml/kit/json-parse.d.ts +0 -23
- package/dist/types/facade/ml/kit/message-transform.d.ts +0 -32
- package/dist/types/facade/ml/kit/output-factory.d.ts +0 -8
- package/dist/types/facade/ml/kit/overflow.d.ts +0 -9
- package/dist/types/facade/ml/kit/provider-adapter.d.ts +0 -56
- package/dist/types/facade/ml/kit/provider-client-builder.d.ts +0 -36
- package/dist/types/facade/ml/kit/provider-consolidation.d.ts +0 -3
- package/dist/types/facade/ml/kit/provider-constants.d.ts +0 -34
- package/dist/types/facade/ml/kit/provider-errors.d.ts +0 -52
- package/dist/types/facade/ml/kit/sanitize-unicode.d.ts +0 -2
- package/dist/types/facade/ml/kit/stream-event-helper.d.ts +0 -38
- package/dist/types/facade/ml/kit/stream-handler-types.d.ts +0 -46
- package/dist/types/facade/ml/kit/streaming-state-manager.d.ts +0 -42
- package/dist/types/facade/ml/kit/tool-converter.d.ts +0 -49
- package/dist/types/facade/ml/kit/typebox-helpers.d.ts +0 -24
- package/dist/types/facade/ml/kit/validation.d.ts +0 -26
- package/dist/types/facade/ml/models.d.ts +0 -41
- package/dist/types/facade/ml/models.generated.d.ts +0 -12405
- package/dist/types/facade/ml/stream.d.ts +0 -27
- package/dist/types/facade/ml/types.d.ts +0 -269
- package/dist/types/index.d.ts +0 -16
- package/dist/types/interop/index.d.ts +0 -12
- package/dist/types/interop/interop.test.d.ts +0 -19
- package/dist/types/interop/protocol-bridge/bridge.d.ts +0 -52
- package/dist/types/interop/protocol-bridge/contract.d.ts +0 -249
- package/dist/types/interop/protocol-bridge/endpoint.d.ts +0 -124
- package/dist/types/interop/protocol-bridge/fleet.d.ts +0 -92
- package/dist/types/interop/protocol-bridge/host.d.ts +0 -61
- package/dist/types/interop/protocol-bridge/index.d.ts +0 -16
- package/dist/types/interop/protocol-bridge/schema.d.ts +0 -29
- package/dist/types/llmgateway/catalog/cards.d.ts +0 -18
- package/dist/types/llmgateway/catalog/cost.d.ts +0 -15
- package/dist/types/llmgateway/catalog/index.d.ts +0 -7
- package/dist/types/llmgateway/catalog/query.d.ts +0 -40
- package/dist/types/llmgateway/connectors/anthropic.d.ts +0 -35
- package/dist/types/llmgateway/connectors/azure-openai.d.ts +0 -33
- package/dist/types/llmgateway/connectors/bedrock.d.ts +0 -113
- package/dist/types/llmgateway/connectors/google-vertex.d.ts +0 -38
- package/dist/types/llmgateway/connectors/google.d.ts +0 -40
- package/dist/types/llmgateway/connectors/index.d.ts +0 -26
- package/dist/types/llmgateway/connectors/kimi.d.ts +0 -28
- package/dist/types/llmgateway/connectors/mock.d.ts +0 -37
- package/dist/types/llmgateway/connectors/nvidia.d.ts +0 -27
- package/dist/types/llmgateway/connectors/ollama.d.ts +0 -45
- package/dist/types/llmgateway/connectors/openai-chat.d.ts +0 -25
- package/dist/types/llmgateway/connectors/openai-responses.d.ts +0 -49
- package/dist/types/llmgateway/contract/connector.d.ts +0 -32
- package/dist/types/llmgateway/contract/conversation.d.ts +0 -86
- package/dist/types/llmgateway/contract/emission.d.ts +0 -55
- package/dist/types/llmgateway/contract/errors.d.ts +0 -27
- package/dist/types/llmgateway/contract/index.d.ts +0 -13
- package/dist/types/llmgateway/contract/model-card.d.ts +0 -42
- package/dist/types/llmgateway/contract/options.d.ts +0 -31
- package/dist/types/llmgateway/contract/reply.d.ts +0 -33
- package/dist/types/llmgateway/conversion/index.d.ts +0 -10
- package/dist/types/llmgateway/conversion/mappers.d.ts +0 -65
- package/dist/types/llmgateway/conversion/openai-compatible.d.ts +0 -46
- package/dist/types/llmgateway/conversion/reduce.d.ts +0 -20
- package/dist/types/llmgateway/credentials/oauth.d.ts +0 -73
- package/dist/types/llmgateway/credentials/pkce.d.ts +0 -52
- package/dist/types/llmgateway/credentials/secrets.d.ts +0 -74
- package/dist/types/llmgateway/gateway.d.ts +0 -34
- package/dist/types/llmgateway/gateway.test.d.ts +0 -14
- package/dist/types/llmgateway/index.d.ts +0 -11
- package/dist/types/llmgateway/streaming/channel.d.ts +0 -24
- package/dist/types/llmgateway/streaming/index.d.ts +0 -10
- package/dist/types/llmgateway/streaming/ndjson.d.ts +0 -17
- package/dist/types/llmgateway/streaming/sse.d.ts +0 -31
- package/dist/types/react-host/index.d.ts +0 -9
- package/dist/types/react-host/ink.d.ts +0 -5
- package/dist/types/react-host/jsx-runtime.d.ts +0 -4
- package/dist/types/react-host/loader.d.ts +0 -3
- package/dist/types/react-ink/components/ChangelogBlock.d.ts +0 -8
- package/dist/types/react-ink/components/DisplayBlockView.d.ts +0 -8
- package/dist/types/react-ink/components/Footer.d.ts +0 -11
- package/dist/types/react-ink/components/MessageList.d.ts +0 -14
- package/dist/types/react-ink/components/MessageRow.d.ts +0 -13
- package/dist/types/react-ink/components/StatusLine.d.ts +0 -18
- package/dist/types/react-ink/components/TaskPanel.d.ts +0 -11
- package/dist/types/react-ink/components/ToolEventBlock.d.ts +0 -48
- package/dist/types/react-ink/components/ToolEventBlock.test.d.ts +0 -1
- package/dist/types/react-ink/components/dialogs/DialogFrame.d.ts +0 -8
- package/dist/types/react-ink/components/dialogs/LoginDialog.d.ts +0 -14
- package/dist/types/react-ink/components/dialogs/ModelDialog.d.ts +0 -9
- package/dist/types/react-ink/components/dialogs/OAuthDialog.d.ts +0 -9
- package/dist/types/react-ink/components/dialogs/ScopedModelsDialog.d.ts +0 -9
- package/dist/types/react-ink/components/dialogs/SelectableDialog.d.ts +0 -22
- package/dist/types/react-ink/components/dialogs/SessionDialog.d.ts +0 -13
- package/dist/types/react-ink/components/dialogs/SettingsDialog.d.ts +0 -14
- package/dist/types/react-ink/components/dialogs/StartupSessionPicker.d.ts +0 -9
- package/dist/types/react-ink/components/dialogs/ThemeDialog.d.ts +0 -26
- package/dist/types/react-ink/components/dialogs/TreeDialog.d.ts +0 -8
- package/dist/types/react-ink/components/dialogs/UserMessageDialog.d.ts +0 -8
- package/dist/types/react-ink/components/messages/AssistantMessage.d.ts +0 -12
- package/dist/types/react-ink/components/messages/BashMessage.d.ts +0 -8
- package/dist/types/react-ink/components/messages/BranchSummaryMessage.d.ts +0 -8
- package/dist/types/react-ink/components/messages/CompactionMessage.d.ts +0 -8
- package/dist/types/react-ink/components/messages/CustomMessage.d.ts +0 -9
- package/dist/types/react-ink/components/messages/SkillInvocationMessage.d.ts +0 -7
- package/dist/types/react-ink/components/messages/ToolCallMessage.d.ts +0 -8
- package/dist/types/react-ink/components/messages/ToolResultBlock.d.ts +0 -12
- package/dist/types/react-ink/components/messages/UserMessage.d.ts +0 -9
- package/dist/types/react-ink/diff/Diff.d.ts +0 -22
- package/dist/types/react-ink/diff/diff.test.d.ts +0 -1
- package/dist/types/react-ink/diff/structured.d.ts +0 -41
- package/dist/types/react-ink/diff/word-diff.d.ts +0 -27
- package/dist/types/react-ink/index.d.ts +0 -42
- package/dist/types/react-ink/markdown/Markdown.d.ts +0 -23
- package/dist/types/react-ink/markdown/MarkdownTable.d.ts +0 -19
- package/dist/types/react-ink/markdown/StreamingMarkdown.d.ts +0 -34
- package/dist/types/react-ink/markdown/format-token.d.ts +0 -39
- package/dist/types/react-ink/markdown/highlight.d.ts +0 -31
- package/dist/types/react-ink/theme-adapter.d.ts +0 -66
- package/dist/types/react-ink/types.d.ts +0 -133
- package/dist/types/react-ink/utils/message-groups.d.ts +0 -25
- package/dist/types/react-ink/utils/selection-dialog.d.ts +0 -2
- package/dist/types/react-ink/utils/session-browser.d.ts +0 -27
- package/dist/types/react-ink/utils/tool-display.d.ts +0 -37
- package/dist/types/runtime/cadence/cadence.test.d.ts +0 -6
- package/dist/types/runtime/cadence/fold.d.ts +0 -48
- package/dist/types/runtime/cadence/index.d.ts +0 -12
- package/dist/types/runtime/cadence/reducer.d.ts +0 -44
- package/dist/types/runtime/conductor/agent.d.ts +0 -71
- package/dist/types/runtime/conductor/index.d.ts +0 -11
- package/dist/types/runtime/contract/config.d.ts +0 -44
- package/dist/types/runtime/contract/effect.d.ts +0 -41
- package/dist/types/runtime/contract/errors.d.ts +0 -22
- package/dist/types/runtime/contract/events.d.ts +0 -63
- package/dist/types/runtime/contract/index.d.ts +0 -18
- package/dist/types/runtime/contract/run-state.d.ts +0 -57
- package/dist/types/runtime/contract/session.d.ts +0 -42
- package/dist/types/runtime/contract/signal.d.ts +0 -49
- package/dist/types/runtime/contract/tools.d.ts +0 -45
- package/dist/types/runtime/dispatch/index.d.ts +0 -9
- package/dist/types/runtime/dispatch/scheduler.d.ts +0 -53
- package/dist/types/runtime/index.d.ts +0 -22
- package/dist/types/runtime/ledger/accumulator.d.ts +0 -44
- package/dist/types/runtime/ledger/bus.d.ts +0 -50
- package/dist/types/runtime/ledger/index.d.ts +0 -11
- package/dist/types/runtime/memory/compactor.d.ts +0 -56
- package/dist/types/runtime/memory/estimate.d.ts +0 -21
- package/dist/types/runtime/memory/index.d.ts +0 -8
- package/dist/types/runtime/runtime.test.d.ts +0 -15
- package/dist/types/runtime/store/dag.d.ts +0 -72
- package/dist/types/runtime/store/hash.d.ts +0 -18
- package/dist/types/runtime/store/index.d.ts +0 -12
- package/dist/types/runtime/store/persist.d.ts +0 -49
- package/dist/types/runtime/turn/driver.d.ts +0 -32
- package/dist/types/runtime/turn/index.d.ts +0 -8
- package/dist/types/runtime/wire/index.d.ts +0 -10
- package/dist/types/runtime/wire/projectors.d.ts +0 -53
- package/dist/types/shell-app/auth-cli/index.d.ts +0 -9
- package/dist/types/shell-app/auth-cli/oauth-cli.d.ts +0 -73
- package/dist/types/shell-app/boot/context.d.ts +0 -108
- package/dist/types/shell-app/boot/index.d.ts +0 -13
- package/dist/types/shell-app/boot/pipeline.d.ts +0 -66
- package/dist/types/shell-app/boot/stages.d.ts +0 -77
- package/dist/types/shell-app/cli.d.ts +0 -75
- package/dist/types/shell-app/config/index.d.ts +0 -11
- package/dist/types/shell-app/config/locator.d.ts +0 -85
- package/dist/types/shell-app/config/settings.d.ts +0 -91
- package/dist/types/shell-app/index.d.ts +0 -26
- package/dist/types/shell-app/invocation/flags.d.ts +0 -89
- package/dist/types/shell-app/invocation/parse.d.ts +0 -89
- package/dist/types/shell-app/locate/brand.d.ts +0 -71
- package/dist/types/shell-app/locate/index.d.ts +0 -12
- package/dist/types/shell-app/locate/locator.d.ts +0 -122
- package/dist/types/shell-app/runners/contract.d.ts +0 -116
- package/dist/types/shell-app/runners/index.d.ts +0 -15
- package/dist/types/shell-app/runners/one-shot.d.ts +0 -21
- package/dist/types/shell-app/runners/registry.d.ts +0 -34
- package/dist/types/shell-app/runners/repl.d.ts +0 -51
- package/dist/types/shell-app/runners/wire.d.ts +0 -34
- package/dist/types/shell-app/shell-app.test.d.ts +0 -14
- package/dist/types/shell-app/upgrade/index.d.ts +0 -9
- package/dist/types/shell-app/upgrade/upgrades.d.ts +0 -62
- package/dist/types/smithy/config/flag-reader.d.ts +0 -128
- package/dist/types/smithy/config/index.d.ts +0 -9
- package/dist/types/smithy/forge.d.ts +0 -135
- package/dist/types/smithy/index.d.ts +0 -36
- package/dist/types/smithy/knowledge/index.d.ts +0 -10
- package/dist/types/smithy/knowledge/loader.d.ts +0 -64
- package/dist/types/smithy/persona/blueprint.d.ts +0 -75
- package/dist/types/smithy/persona/define-agent.d.ts +0 -51
- package/dist/types/smithy/persona/index.d.ts +0 -14
- package/dist/types/smithy/persona/profiles.d.ts +0 -44
- package/dist/types/smithy/runtime/index.d.ts +0 -9
- package/dist/types/smithy/runtime/tool-ledger.d.ts +0 -130
- package/dist/types/smithy/smithy.test.d.ts +0 -20
- package/dist/types/smithy/ui/index.d.ts +0 -11
- package/dist/types/smithy/ui/transcript.d.ts +0 -183
- package/dist/types/swarm/coordinator.d.ts +0 -192
- package/dist/types/swarm/index.d.ts +0 -33
- package/dist/types/swarm/isolation/index.d.ts +0 -14
- package/dist/types/swarm/isolation/runner.d.ts +0 -61
- package/dist/types/swarm/isolation/worktree.d.ts +0 -142
- package/dist/types/swarm/kernel/faults.d.ts +0 -52
- package/dist/types/swarm/kernel/ids.d.ts +0 -25
- package/dist/types/swarm/kernel/index.d.ts +0 -26
- package/dist/types/swarm/kernel/json-cell.d.ts +0 -113
- package/dist/types/swarm/kernel/jsonl-log.d.ts +0 -81
- package/dist/types/swarm/postbox/channel.d.ts +0 -88
- package/dist/types/swarm/postbox/codecs.d.ts +0 -253
- package/dist/types/swarm/postbox/index.d.ts +0 -16
- package/dist/types/swarm/roster/index.d.ts +0 -16
- package/dist/types/swarm/roster/manifest.d.ts +0 -185
- package/dist/types/swarm/swarm.test.d.ts +0 -24
- package/dist/types/swarm/telemetry/activity.d.ts +0 -143
- package/dist/types/swarm/workboard/board.d.ts +0 -174
- package/dist/types/swarm/workboard/dep-graph.d.ts +0 -77
- package/dist/types/swarm/workboard/index.d.ts +0 -12
- package/dist/types/tracing/adapter/index.d.ts +0 -12
- package/dist/types/tracing/adapter/runtime-trace.d.ts +0 -54
- package/dist/types/tracing/channel/index.d.ts +0 -9
- package/dist/types/tracing/channel/signal.d.ts +0 -93
- package/dist/types/tracing/index.d.ts +0 -25
- package/dist/types/tracing/recorder/index.d.ts +0 -12
- package/dist/types/tracing/recorder/recorder.d.ts +0 -75
- package/dist/types/tracing/recorder/sampling.d.ts +0 -55
- package/dist/types/tracing/redaction/index.d.ts +0 -8
- package/dist/types/tracing/redaction/secret-scrubber.d.ts +0 -95
- package/dist/types/tracing/registry/hub.d.ts +0 -57
- package/dist/types/tracing/registry/index.d.ts +0 -7
- package/dist/types/tracing/signal/handle.d.ts +0 -73
- package/dist/types/tracing/signal/index.d.ts +0 -12
- package/dist/types/tracing/signal/segment.d.ts +0 -124
- package/dist/types/tracing/sinks/base.d.ts +0 -51
- package/dist/types/tracing/sinks/console.d.ts +0 -44
- package/dist/types/tracing/sinks/file.d.ts +0 -47
- package/dist/types/tracing/sinks/index.d.ts +0 -16
- package/dist/types/tracing/sinks/stream.d.ts +0 -46
- package/dist/types/tracing/tracing.test.d.ts +0 -7
- package/dist/types/ui/autocomplete.d.ts +0 -59
- package/dist/types/ui/contracts.d.ts +0 -38
- package/dist/types/ui/editor-component.d.ts +0 -100
- package/dist/types/ui/fuzzy.d.ts +0 -29
- package/dist/types/ui/index.d.ts +0 -8
- package/dist/types/ui/keybindings.d.ts +0 -62
- package/dist/types/ui/keys.d.ts +0 -171
- package/dist/types/ui/theme-types.d.ts +0 -36
- package/dist/types/ui/utils.d.ts +0 -101
- package/dist/types/ui-bridge/InteractiveApp.d.ts +0 -38
- package/dist/types/ui-bridge/adapter.d.ts +0 -90
- package/dist/types/ui-bridge/index.d.ts +0 -37
package/dist/mcp.js
DELETED
|
@@ -1,1639 +0,0 @@
|
|
|
1
|
-
// src/facade/mcp-core/client.ts
|
|
2
|
-
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
3
|
-
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
4
|
-
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
5
|
-
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
6
|
-
import {
|
|
7
|
-
ListRootsRequestSchema,
|
|
8
|
-
ElicitRequestSchema,
|
|
9
|
-
CreateMessageRequestSchema,
|
|
10
|
-
PingRequestSchema,
|
|
11
|
-
ToolListChangedNotificationSchema,
|
|
12
|
-
ResourceListChangedNotificationSchema,
|
|
13
|
-
ResourceUpdatedNotificationSchema,
|
|
14
|
-
PromptListChangedNotificationSchema,
|
|
15
|
-
ProgressNotificationSchema,
|
|
16
|
-
LoggingMessageNotificationSchema,
|
|
17
|
-
CancelledNotificationSchema
|
|
18
|
-
} from "@modelcontextprotocol/sdk/types.js";
|
|
19
|
-
|
|
20
|
-
// src/facade/mcp-core/errors.ts
|
|
21
|
-
var MCPErrorCode = /* @__PURE__ */ ((MCPErrorCode2) => {
|
|
22
|
-
MCPErrorCode2["CONNECTION_FAILED"] = "CONNECTION_FAILED";
|
|
23
|
-
MCPErrorCode2["TIMEOUT"] = "TIMEOUT";
|
|
24
|
-
MCPErrorCode2["TOOL_NOT_FOUND"] = "TOOL_NOT_FOUND";
|
|
25
|
-
MCPErrorCode2["INVALID_PARAMETERS"] = "INVALID_PARAMETERS";
|
|
26
|
-
MCPErrorCode2["SERVER_ERROR"] = "SERVER_ERROR";
|
|
27
|
-
MCPErrorCode2["TRANSPORT_ERROR"] = "TRANSPORT_ERROR";
|
|
28
|
-
MCPErrorCode2["NOT_CONNECTED"] = "NOT_CONNECTED";
|
|
29
|
-
MCPErrorCode2["PROTOCOL_ERROR"] = "PROTOCOL_ERROR";
|
|
30
|
-
MCPErrorCode2["CONFIG_ERROR"] = "CONFIG_ERROR";
|
|
31
|
-
MCPErrorCode2["SCHEMA_CONVERSION_ERROR"] = "SCHEMA_CONVERSION_ERROR";
|
|
32
|
-
MCPErrorCode2["RESOURCE_NOT_FOUND"] = "RESOURCE_NOT_FOUND";
|
|
33
|
-
MCPErrorCode2["PROMPT_NOT_FOUND"] = "PROMPT_NOT_FOUND";
|
|
34
|
-
MCPErrorCode2["SESSION_ERROR"] = "SESSION_ERROR";
|
|
35
|
-
return MCPErrorCode2;
|
|
36
|
-
})(MCPErrorCode || {});
|
|
37
|
-
var MCPError = class extends Error {
|
|
38
|
-
/** Error code */
|
|
39
|
-
code;
|
|
40
|
-
/** Additional error details */
|
|
41
|
-
details;
|
|
42
|
-
/** Server name where error occurred */
|
|
43
|
-
serverName;
|
|
44
|
-
/** Tool name if error occurred during tool execution */
|
|
45
|
-
toolName;
|
|
46
|
-
constructor(message, code, details, options) {
|
|
47
|
-
super(message, options?.cause ? { cause: options.cause } : void 0);
|
|
48
|
-
this.name = "MCPError";
|
|
49
|
-
this.code = code;
|
|
50
|
-
this.details = details;
|
|
51
|
-
this.serverName = options?.serverName;
|
|
52
|
-
this.toolName = options?.toolName;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Convert error to JSON for logging/serialization.
|
|
56
|
-
*/
|
|
57
|
-
toJSON() {
|
|
58
|
-
return {
|
|
59
|
-
name: this.name,
|
|
60
|
-
message: this.message,
|
|
61
|
-
code: this.code,
|
|
62
|
-
details: this.details,
|
|
63
|
-
serverName: this.serverName,
|
|
64
|
-
toolName: this.toolName
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Create a string representation of the error.
|
|
69
|
-
*/
|
|
70
|
-
toString() {
|
|
71
|
-
let str = `${this.name} [${this.code}]: ${this.message}`;
|
|
72
|
-
if (this.serverName) str += ` (server: ${this.serverName})`;
|
|
73
|
-
if (this.toolName) str += ` (tool: ${this.toolName})`;
|
|
74
|
-
return str;
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
function isMCPError(error) {
|
|
78
|
-
return error instanceof MCPError;
|
|
79
|
-
}
|
|
80
|
-
function isSessionError(error) {
|
|
81
|
-
if (!isMCPError(error)) return false;
|
|
82
|
-
return error.code === "SESSION_ERROR" /* SESSION_ERROR */ || error.code === "NOT_CONNECTED" /* NOT_CONNECTED */;
|
|
83
|
-
}
|
|
84
|
-
function createConnectionError(serverName, cause) {
|
|
85
|
-
return new MCPError(
|
|
86
|
-
`Failed to connect to MCP server: ${serverName}`,
|
|
87
|
-
"CONNECTION_FAILED" /* CONNECTION_FAILED */,
|
|
88
|
-
{ cause: cause?.message },
|
|
89
|
-
{ serverName, cause }
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
function createTimeoutError(operation, serverName) {
|
|
93
|
-
return new MCPError(`Operation timed out: ${operation}`, "TIMEOUT" /* TIMEOUT */, { operation }, { serverName });
|
|
94
|
-
}
|
|
95
|
-
function createToolNotFoundError(toolName, serverName) {
|
|
96
|
-
return new MCPError(`Tool not found: ${toolName}`, "TOOL_NOT_FOUND" /* TOOL_NOT_FOUND */, { toolName }, { serverName, toolName });
|
|
97
|
-
}
|
|
98
|
-
function createInvalidParametersError(toolName, details, serverName) {
|
|
99
|
-
return new MCPError(
|
|
100
|
-
`Invalid parameters for tool: ${toolName}`,
|
|
101
|
-
"INVALID_PARAMETERS" /* INVALID_PARAMETERS */,
|
|
102
|
-
details,
|
|
103
|
-
{ serverName, toolName }
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
function createServerError(message, serverName, details) {
|
|
107
|
-
return new MCPError(message, "SERVER_ERROR" /* SERVER_ERROR */, details, { serverName });
|
|
108
|
-
}
|
|
109
|
-
function createNotConnectedError(serverName) {
|
|
110
|
-
return new MCPError("Not connected to MCP server", "NOT_CONNECTED" /* NOT_CONNECTED */, void 0, { serverName });
|
|
111
|
-
}
|
|
112
|
-
function createConfigError(message, details) {
|
|
113
|
-
return new MCPError(message, "CONFIG_ERROR" /* CONFIG_ERROR */, details);
|
|
114
|
-
}
|
|
115
|
-
function createSchemaConversionError(toolName, details, serverName) {
|
|
116
|
-
return new MCPError(
|
|
117
|
-
`Failed to convert schema for tool: ${toolName}`,
|
|
118
|
-
"SCHEMA_CONVERSION_ERROR" /* SCHEMA_CONVERSION_ERROR */,
|
|
119
|
-
details,
|
|
120
|
-
{ serverName, toolName }
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// src/facade/mcp-core/client.ts
|
|
125
|
-
var DEFAULT_REQUEST_TIMEOUT = 6e4;
|
|
126
|
-
var DEFAULT_CONNECT_TIMEOUT = 3e4;
|
|
127
|
-
var MCPClient = class {
|
|
128
|
-
constructor(options) {
|
|
129
|
-
this.options = options;
|
|
130
|
-
this.serverName = options.name;
|
|
131
|
-
this.config = options.config;
|
|
132
|
-
this.timeout = options.timeout ?? DEFAULT_REQUEST_TIMEOUT;
|
|
133
|
-
this.logHandler = options.logger;
|
|
134
|
-
this.enableServerLogs = options.enableServerLogs ?? true;
|
|
135
|
-
this.enableProgressTracking = options.enableProgressTracking ?? false;
|
|
136
|
-
this._roots = options.roots ?? [];
|
|
137
|
-
}
|
|
138
|
-
options;
|
|
139
|
-
client;
|
|
140
|
-
transport;
|
|
141
|
-
isConnected = false;
|
|
142
|
-
connectionPromise = null;
|
|
143
|
-
serverCapabilities;
|
|
144
|
-
logHandler;
|
|
145
|
-
enableServerLogs;
|
|
146
|
-
enableProgressTracking;
|
|
147
|
-
_roots;
|
|
148
|
-
// --- Host-overridable handlers (Core of #13) --------------------------------
|
|
149
|
-
// Server-initiated REQUESTS are answered by request handlers registered on the
|
|
150
|
-
// SDK client; the handlers delegate to these host-supplied callbacks when set,
|
|
151
|
-
// and fall back to sensible defaults otherwise.
|
|
152
|
-
elicitationHandler;
|
|
153
|
-
samplingHandler;
|
|
154
|
-
// Server-initiated NOTIFICATIONS are dispatched to these (so the host can, for
|
|
155
|
-
// example, re-list tools when a `tools/list_changed` arrives).
|
|
156
|
-
resourceUpdatedHandler;
|
|
157
|
-
resourceListChangedHandler;
|
|
158
|
-
toolListChangedHandler;
|
|
159
|
-
promptListChangedHandler;
|
|
160
|
-
progressHandler;
|
|
161
|
-
/** Server name */
|
|
162
|
-
serverName;
|
|
163
|
-
/** Server config */
|
|
164
|
-
config;
|
|
165
|
-
/** Request timeout */
|
|
166
|
-
timeout;
|
|
167
|
-
// ========================================================================
|
|
168
|
-
// Connection Lifecycle
|
|
169
|
-
// ========================================================================
|
|
170
|
-
/**
|
|
171
|
-
* Connect to the MCP server.
|
|
172
|
-
* Safe to call multiple times - returns existing connection if already connected.
|
|
173
|
-
*/
|
|
174
|
-
async connect() {
|
|
175
|
-
if (this.isConnected) return;
|
|
176
|
-
if (this.connectionPromise) {
|
|
177
|
-
return this.connectionPromise;
|
|
178
|
-
}
|
|
179
|
-
this.connectionPromise = this.doConnect();
|
|
180
|
-
try {
|
|
181
|
-
await this.connectionPromise;
|
|
182
|
-
} finally {
|
|
183
|
-
this.connectionPromise = null;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
async doConnect() {
|
|
187
|
-
const transport = this.createTransport(this.config);
|
|
188
|
-
this.transport = transport;
|
|
189
|
-
const client = new Client(
|
|
190
|
-
{ name: "indusagi-coding-agent", version: "0.13.0" },
|
|
191
|
-
{
|
|
192
|
-
capabilities: {
|
|
193
|
-
roots: { listChanged: true },
|
|
194
|
-
elicitation: {},
|
|
195
|
-
sampling: {}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
);
|
|
199
|
-
this.client = client;
|
|
200
|
-
this.registerServerHandlers(client);
|
|
201
|
-
const prevOnClose = transport.onclose;
|
|
202
|
-
transport.onclose = () => {
|
|
203
|
-
this.isConnected = false;
|
|
204
|
-
this.log("debug", "Transport closed");
|
|
205
|
-
prevOnClose?.();
|
|
206
|
-
};
|
|
207
|
-
await client.connect(transport, { timeout: DEFAULT_CONNECT_TIMEOUT });
|
|
208
|
-
this.serverCapabilities = client.getServerCapabilities();
|
|
209
|
-
this.isConnected = true;
|
|
210
|
-
this.log("info", `Connected to MCP server`);
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Build the SDK transport for the configured server.
|
|
214
|
-
*
|
|
215
|
-
* - stdio: `StdioClientTransport` (inherits the parent env, merges config.env).
|
|
216
|
-
* - http: `StreamableHTTPClientTransport` (POST + server-push SSE channel,
|
|
217
|
-
* reconnect + session-expiry handled by the SDK), unless the config
|
|
218
|
-
* asks for the legacy `SSEClientTransport`.
|
|
219
|
-
*/
|
|
220
|
-
createTransport(config) {
|
|
221
|
-
if ("command" in config) {
|
|
222
|
-
return new StdioClientTransport({
|
|
223
|
-
command: config.command,
|
|
224
|
-
args: config.args ?? [],
|
|
225
|
-
env: { ...sanitizeEnv(process.env), ...config.env ?? {} },
|
|
226
|
-
cwd: config.cwd,
|
|
227
|
-
stderr: "pipe"
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
if ("url" in config) {
|
|
231
|
-
const requestInit = config.headers ? { headers: config.headers } : void 0;
|
|
232
|
-
if (config.transport === "sse") {
|
|
233
|
-
return new SSEClientTransport(config.url, { requestInit });
|
|
234
|
-
}
|
|
235
|
-
return new StreamableHTTPClientTransport(config.url, { requestInit });
|
|
236
|
-
}
|
|
237
|
-
throw new MCPError(
|
|
238
|
-
"Server configuration must include either a command or a url",
|
|
239
|
-
"CONFIG_ERROR" /* CONFIG_ERROR */,
|
|
240
|
-
void 0,
|
|
241
|
-
{ serverName: this.serverName }
|
|
242
|
-
);
|
|
243
|
-
}
|
|
244
|
-
/**
|
|
245
|
-
* Register handlers for server-initiated REQUESTS and NOTIFICATIONS.
|
|
246
|
-
*
|
|
247
|
-
* REQUESTS (have both `.method` AND `.id`) must be ANSWERED with a JSON-RPC
|
|
248
|
-
* RESPONSE carrying the matching id — the SDK does this automatically for the
|
|
249
|
-
* value a request handler returns (or rejects). The previous hand-rolled
|
|
250
|
-
* transport routed these into the notification path, so they were never
|
|
251
|
-
* answered (bug #13).
|
|
252
|
-
*
|
|
253
|
-
* Defaults:
|
|
254
|
-
* - ping → {}
|
|
255
|
-
* - roots/list → the configured roots
|
|
256
|
-
* - elicitation/create→ decline ({action:"cancel"}) unless a host handler is set
|
|
257
|
-
* - sampling → reject "Method not found" unless a host handler is set
|
|
258
|
-
*/
|
|
259
|
-
registerServerHandlers(client) {
|
|
260
|
-
client.setRequestHandler(PingRequestSchema, async () => ({}));
|
|
261
|
-
client.setRequestHandler(ListRootsRequestSchema, async () => ({
|
|
262
|
-
roots: this._roots.map((r) => ({ uri: r.uri, name: r.name }))
|
|
263
|
-
}));
|
|
264
|
-
client.setRequestHandler(ElicitRequestSchema, async (request) => {
|
|
265
|
-
if (!this.elicitationHandler) {
|
|
266
|
-
return { action: "cancel" };
|
|
267
|
-
}
|
|
268
|
-
const params = request.params;
|
|
269
|
-
const elicitRequest = {
|
|
270
|
-
message: params.message,
|
|
271
|
-
requestedSchema: params.requestedSchema ?? {}
|
|
272
|
-
};
|
|
273
|
-
const result = await this.elicitationHandler(elicitRequest);
|
|
274
|
-
return mapToSdkElicitResult(result);
|
|
275
|
-
});
|
|
276
|
-
client.setRequestHandler(CreateMessageRequestSchema, async (request) => {
|
|
277
|
-
if (!this.samplingHandler) {
|
|
278
|
-
throw new MCPError(
|
|
279
|
-
"Method not found: sampling/createMessage",
|
|
280
|
-
"SERVER_ERROR" /* SERVER_ERROR */,
|
|
281
|
-
{ method: "sampling/createMessage" },
|
|
282
|
-
{ serverName: this.serverName }
|
|
283
|
-
);
|
|
284
|
-
}
|
|
285
|
-
return await this.samplingHandler(request.params);
|
|
286
|
-
});
|
|
287
|
-
client.setNotificationHandler(ToolListChangedNotificationSchema, () => {
|
|
288
|
-
this.log("debug", "Tool list changed");
|
|
289
|
-
this.toolListChangedHandler?.();
|
|
290
|
-
});
|
|
291
|
-
client.setNotificationHandler(ResourceListChangedNotificationSchema, () => {
|
|
292
|
-
this.log("debug", "Resource list changed");
|
|
293
|
-
this.resourceListChangedHandler?.();
|
|
294
|
-
});
|
|
295
|
-
client.setNotificationHandler(ResourceUpdatedNotificationSchema, (n) => {
|
|
296
|
-
const uri = n.params?.uri;
|
|
297
|
-
this.log("debug", `Resource updated: ${uri}`);
|
|
298
|
-
if (uri) this.resourceUpdatedHandler?.({ uri });
|
|
299
|
-
});
|
|
300
|
-
client.setNotificationHandler(PromptListChangedNotificationSchema, () => {
|
|
301
|
-
this.log("debug", "Prompt list changed");
|
|
302
|
-
this.promptListChangedHandler?.();
|
|
303
|
-
});
|
|
304
|
-
client.setNotificationHandler(ProgressNotificationSchema, (n) => {
|
|
305
|
-
const params = n.params;
|
|
306
|
-
this.log("debug", `Progress: ${JSON.stringify(params)}`);
|
|
307
|
-
if (this.progressHandler && params) {
|
|
308
|
-
const notification = {
|
|
309
|
-
progressToken: params.progressToken,
|
|
310
|
-
progress: params.progress,
|
|
311
|
-
total: params.total,
|
|
312
|
-
message: params.message
|
|
313
|
-
};
|
|
314
|
-
this.progressHandler(notification);
|
|
315
|
-
}
|
|
316
|
-
});
|
|
317
|
-
client.setNotificationHandler(LoggingMessageNotificationSchema, (n) => {
|
|
318
|
-
if (this.enableServerLogs && n.params) {
|
|
319
|
-
const { level, ...rest } = n.params;
|
|
320
|
-
this.log(level || "info", "[SERVER]", rest);
|
|
321
|
-
}
|
|
322
|
-
});
|
|
323
|
-
client.setNotificationHandler(CancelledNotificationSchema, (n) => {
|
|
324
|
-
this.log("debug", `Request cancelled: ${JSON.stringify(n.params)}`);
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* Disconnect from the MCP server.
|
|
329
|
-
*
|
|
330
|
-
* The SDK's `client.close()` closes the transport and rejects any pending
|
|
331
|
-
* requests — a clean teardown for both stdio (graceful subprocess shutdown)
|
|
332
|
-
* and HTTP (close the push channel / end the session).
|
|
333
|
-
*/
|
|
334
|
-
async disconnect() {
|
|
335
|
-
if (!this.client) {
|
|
336
|
-
this.log("debug", "Disconnect called but not connected");
|
|
337
|
-
this.isConnected = false;
|
|
338
|
-
return;
|
|
339
|
-
}
|
|
340
|
-
this.log("debug", "Disconnecting from MCP server");
|
|
341
|
-
try {
|
|
342
|
-
await this.client.close();
|
|
343
|
-
} catch (error) {
|
|
344
|
-
this.log("error", `Error during disconnect: ${error}`);
|
|
345
|
-
} finally {
|
|
346
|
-
this.client = void 0;
|
|
347
|
-
this.transport = void 0;
|
|
348
|
-
this.isConnected = false;
|
|
349
|
-
this.log("debug", "Successfully disconnected");
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
/**
|
|
353
|
-
* Whether the client is connected.
|
|
354
|
-
*/
|
|
355
|
-
get connected() {
|
|
356
|
-
return this.isConnected;
|
|
357
|
-
}
|
|
358
|
-
// ========================================================================
|
|
359
|
-
// Tool Operations
|
|
360
|
-
// ========================================================================
|
|
361
|
-
/**
|
|
362
|
-
* List all tools available from the server.
|
|
363
|
-
*/
|
|
364
|
-
async listTools() {
|
|
365
|
-
this.ensureConnected();
|
|
366
|
-
const result = await this.client.listTools(void 0, {
|
|
367
|
-
timeout: this.timeout
|
|
368
|
-
});
|
|
369
|
-
return result.tools;
|
|
370
|
-
}
|
|
371
|
-
/**
|
|
372
|
-
* Call a tool on the server.
|
|
373
|
-
*/
|
|
374
|
-
async callTool(name, args) {
|
|
375
|
-
this.ensureConnected();
|
|
376
|
-
this.log("debug", `Calling tool: ${name}`);
|
|
377
|
-
try {
|
|
378
|
-
const result = await this.client.callTool(
|
|
379
|
-
{ name, arguments: args },
|
|
380
|
-
void 0,
|
|
381
|
-
{ timeout: this.timeout }
|
|
382
|
-
);
|
|
383
|
-
this.log("debug", `Tool ${name} executed successfully`);
|
|
384
|
-
return result;
|
|
385
|
-
} catch (error) {
|
|
386
|
-
this.log("error", `Tool ${name} failed: ${error}`);
|
|
387
|
-
throw this.wrapError(error);
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
// ========================================================================
|
|
391
|
-
// Resource Operations
|
|
392
|
-
// ========================================================================
|
|
393
|
-
/**
|
|
394
|
-
* List all resources available from the server.
|
|
395
|
-
*/
|
|
396
|
-
async listResources() {
|
|
397
|
-
this.ensureConnected();
|
|
398
|
-
if (!this.serverCapabilities?.resources) {
|
|
399
|
-
return [];
|
|
400
|
-
}
|
|
401
|
-
const result = await this.client.listResources(void 0, {
|
|
402
|
-
timeout: this.timeout
|
|
403
|
-
});
|
|
404
|
-
return result.resources;
|
|
405
|
-
}
|
|
406
|
-
/**
|
|
407
|
-
* Read a resource from the server.
|
|
408
|
-
*/
|
|
409
|
-
async readResource(uri) {
|
|
410
|
-
this.ensureConnected();
|
|
411
|
-
return await this.client.readResource({ uri }, { timeout: this.timeout });
|
|
412
|
-
}
|
|
413
|
-
/**
|
|
414
|
-
* Subscribe to resource updates.
|
|
415
|
-
*/
|
|
416
|
-
async subscribeResource(uri) {
|
|
417
|
-
this.ensureConnected();
|
|
418
|
-
await this.client.subscribeResource({ uri }, { timeout: this.timeout });
|
|
419
|
-
}
|
|
420
|
-
/**
|
|
421
|
-
* Unsubscribe from resource updates.
|
|
422
|
-
*/
|
|
423
|
-
async unsubscribeResource(uri) {
|
|
424
|
-
this.ensureConnected();
|
|
425
|
-
await this.client.unsubscribeResource({ uri }, { timeout: this.timeout });
|
|
426
|
-
}
|
|
427
|
-
// ========================================================================
|
|
428
|
-
// Prompt Operations
|
|
429
|
-
// ========================================================================
|
|
430
|
-
/**
|
|
431
|
-
* List all prompts available from the server.
|
|
432
|
-
*/
|
|
433
|
-
async listPrompts() {
|
|
434
|
-
this.ensureConnected();
|
|
435
|
-
if (!this.serverCapabilities?.prompts) {
|
|
436
|
-
return [];
|
|
437
|
-
}
|
|
438
|
-
const result = await this.client.listPrompts(void 0, {
|
|
439
|
-
timeout: this.timeout
|
|
440
|
-
});
|
|
441
|
-
return result.prompts;
|
|
442
|
-
}
|
|
443
|
-
/**
|
|
444
|
-
* Get a prompt from the server.
|
|
445
|
-
*/
|
|
446
|
-
async getPrompt(name, args) {
|
|
447
|
-
this.ensureConnected();
|
|
448
|
-
return await this.client.getPrompt(
|
|
449
|
-
{ name, arguments: args },
|
|
450
|
-
{ timeout: this.timeout }
|
|
451
|
-
);
|
|
452
|
-
}
|
|
453
|
-
// ========================================================================
|
|
454
|
-
// Roots Operations
|
|
455
|
-
// ========================================================================
|
|
456
|
-
/**
|
|
457
|
-
* Get the configured roots.
|
|
458
|
-
*/
|
|
459
|
-
get roots() {
|
|
460
|
-
return [...this._roots];
|
|
461
|
-
}
|
|
462
|
-
/**
|
|
463
|
-
* Update the roots and notify the server.
|
|
464
|
-
*/
|
|
465
|
-
async setRoots(roots) {
|
|
466
|
-
this.log("debug", `Updating roots to ${roots.length} entries`);
|
|
467
|
-
this._roots = [...roots];
|
|
468
|
-
if (this.isConnected && this.client) {
|
|
469
|
-
try {
|
|
470
|
-
await this.client.sendRootsListChanged();
|
|
471
|
-
} catch (error) {
|
|
472
|
-
this.log("debug", `Failed to send roots/list_changed: ${error}`);
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
// ========================================================================
|
|
477
|
-
// Handler Registration
|
|
478
|
-
//
|
|
479
|
-
// Setters STORE the host handler (and, for notifications, the SDK handler
|
|
480
|
-
// registered in `registerServerHandlers` delegates to the stored callback).
|
|
481
|
-
// This is the host-overridable layer at the core of bug #13.
|
|
482
|
-
// ========================================================================
|
|
483
|
-
/**
|
|
484
|
-
* Set a handler for resource updated notifications.
|
|
485
|
-
*/
|
|
486
|
-
setResourceUpdatedHandler(handler) {
|
|
487
|
-
this.resourceUpdatedHandler = handler;
|
|
488
|
-
this.log("debug", "Resource updated handler registered");
|
|
489
|
-
}
|
|
490
|
-
/**
|
|
491
|
-
* Set a handler for resource list changed notifications.
|
|
492
|
-
*/
|
|
493
|
-
setResourceListChangedHandler(handler) {
|
|
494
|
-
this.resourceListChangedHandler = handler;
|
|
495
|
-
this.log("debug", "Resource list changed handler registered");
|
|
496
|
-
}
|
|
497
|
-
/**
|
|
498
|
-
* Set a handler for tool list changed notifications.
|
|
499
|
-
*/
|
|
500
|
-
setToolListChangedHandler(handler) {
|
|
501
|
-
this.toolListChangedHandler = handler;
|
|
502
|
-
this.log("debug", "Tool list changed handler registered");
|
|
503
|
-
}
|
|
504
|
-
/**
|
|
505
|
-
* Set a handler for prompt list changed notifications.
|
|
506
|
-
*/
|
|
507
|
-
setPromptListChangedHandler(handler) {
|
|
508
|
-
this.promptListChangedHandler = handler;
|
|
509
|
-
this.log("debug", "Prompt list changed handler registered");
|
|
510
|
-
}
|
|
511
|
-
/**
|
|
512
|
-
* Set a handler for elicitation requests. When set, the server's
|
|
513
|
-
* `elicitation/create` REQUEST is answered with the host's decision; when
|
|
514
|
-
* unset the request is declined ({action:"cancel"}).
|
|
515
|
-
*/
|
|
516
|
-
setElicitationHandler(handler) {
|
|
517
|
-
this.elicitationHandler = handler;
|
|
518
|
-
this.log("debug", "Elicitation handler registered");
|
|
519
|
-
}
|
|
520
|
-
/**
|
|
521
|
-
* Set a handler for sampling (`sampling/createMessage`) requests. When set,
|
|
522
|
-
* the server request is answered with the host's result; when unset the
|
|
523
|
-
* request is rejected with "Method not found".
|
|
524
|
-
*/
|
|
525
|
-
setSamplingHandler(handler) {
|
|
526
|
-
this.samplingHandler = handler;
|
|
527
|
-
this.log("debug", "Sampling handler registered");
|
|
528
|
-
}
|
|
529
|
-
/**
|
|
530
|
-
* Set a handler for progress notifications.
|
|
531
|
-
*/
|
|
532
|
-
setProgressHandler(handler) {
|
|
533
|
-
this.progressHandler = handler;
|
|
534
|
-
this.log("debug", "Progress handler registered");
|
|
535
|
-
}
|
|
536
|
-
// ========================================================================
|
|
537
|
-
// Private Methods
|
|
538
|
-
// ========================================================================
|
|
539
|
-
ensureConnected() {
|
|
540
|
-
if (!this.isConnected || !this.client) {
|
|
541
|
-
throw new MCPError(
|
|
542
|
-
"Not connected to MCP server",
|
|
543
|
-
"NOT_CONNECTED" /* NOT_CONNECTED */,
|
|
544
|
-
void 0,
|
|
545
|
-
{ serverName: this.serverName }
|
|
546
|
-
);
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
/**
|
|
550
|
-
* Normalize an SDK/transport error into an MCPError. Session-expiry style
|
|
551
|
-
* failures (404 session / -32001) are surfaced as SESSION_ERROR so callers
|
|
552
|
-
* (the pool) can decide to reconnect; the SDK's StreamableHTTP transport
|
|
553
|
-
* already attempts a bounded reconnect re-using the session id before this.
|
|
554
|
-
*/
|
|
555
|
-
wrapError(error) {
|
|
556
|
-
if (error instanceof MCPError) return error;
|
|
557
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
558
|
-
const code = error.code;
|
|
559
|
-
if (code === -32001 || /\b404\b|session/i.test(message)) {
|
|
560
|
-
return new MCPError(message, "SESSION_ERROR" /* SESSION_ERROR */, { code }, {
|
|
561
|
-
serverName: this.serverName
|
|
562
|
-
});
|
|
563
|
-
}
|
|
564
|
-
return new MCPError(message, "SERVER_ERROR" /* SERVER_ERROR */, { code }, {
|
|
565
|
-
serverName: this.serverName
|
|
566
|
-
});
|
|
567
|
-
}
|
|
568
|
-
log(level, message, details) {
|
|
569
|
-
const msg = `[${this.serverName}] ${message}`;
|
|
570
|
-
if (this.logHandler) {
|
|
571
|
-
this.logHandler({
|
|
572
|
-
level,
|
|
573
|
-
message: msg,
|
|
574
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
575
|
-
serverName: this.serverName,
|
|
576
|
-
details
|
|
577
|
-
});
|
|
578
|
-
} else {
|
|
579
|
-
if (process.env.INDUSAGI_DEBUG || level === "error") {
|
|
580
|
-
const prefix = `[MCP:${level.toUpperCase()}]`;
|
|
581
|
-
if (details) {
|
|
582
|
-
if (level === "error") {
|
|
583
|
-
console.error(prefix, msg, details);
|
|
584
|
-
} else {
|
|
585
|
-
console.log(prefix, msg, details);
|
|
586
|
-
}
|
|
587
|
-
} else {
|
|
588
|
-
if (level === "error") {
|
|
589
|
-
console.error(prefix, msg);
|
|
590
|
-
} else {
|
|
591
|
-
console.log(prefix, msg);
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
};
|
|
598
|
-
function mapToSdkElicitResult(result) {
|
|
599
|
-
if (result.action === "accept") {
|
|
600
|
-
return {
|
|
601
|
-
action: "accept",
|
|
602
|
-
content: result.content ?? {}
|
|
603
|
-
};
|
|
604
|
-
}
|
|
605
|
-
return { action: result.action };
|
|
606
|
-
}
|
|
607
|
-
function sanitizeEnv(env) {
|
|
608
|
-
const out = {};
|
|
609
|
-
for (const [k, v] of Object.entries(env)) {
|
|
610
|
-
if (typeof v === "string") out[k] = v;
|
|
611
|
-
}
|
|
612
|
-
return out;
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
// src/facade/mcp-core/client-pool.ts
|
|
616
|
-
var MCPClientPool = class {
|
|
617
|
-
constructor(options) {
|
|
618
|
-
this.options = options;
|
|
619
|
-
}
|
|
620
|
-
options;
|
|
621
|
-
clients = /* @__PURE__ */ new Map();
|
|
622
|
-
isConnecting = false;
|
|
623
|
-
/**
|
|
624
|
-
* Connect to all configured servers.
|
|
625
|
-
*
|
|
626
|
-
* Errors for individual servers are logged but don't fail the entire operation.
|
|
627
|
-
*/
|
|
628
|
-
async connectAll() {
|
|
629
|
-
if (this.isConnecting) {
|
|
630
|
-
throw new MCPError(
|
|
631
|
-
"Already connecting to servers",
|
|
632
|
-
"CONNECTION_FAILED" /* CONNECTION_FAILED */
|
|
633
|
-
);
|
|
634
|
-
}
|
|
635
|
-
this.isConnecting = true;
|
|
636
|
-
try {
|
|
637
|
-
for (const serverConfig of this.options.servers) {
|
|
638
|
-
try {
|
|
639
|
-
const client = new MCPClient(serverConfig);
|
|
640
|
-
await client.connect();
|
|
641
|
-
this.clients.set(serverConfig.name, client);
|
|
642
|
-
console.log(`[MCP] Connected to ${serverConfig.name}`);
|
|
643
|
-
} catch (error) {
|
|
644
|
-
console.error(
|
|
645
|
-
`[MCP] Failed to connect to ${serverConfig.name}:`,
|
|
646
|
-
error instanceof Error ? error.message : String(error)
|
|
647
|
-
);
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
} finally {
|
|
651
|
-
this.isConnecting = false;
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
/**
|
|
655
|
-
* Disconnect from all servers.
|
|
656
|
-
*/
|
|
657
|
-
async disconnectAll() {
|
|
658
|
-
for (const [name, client] of this.clients) {
|
|
659
|
-
try {
|
|
660
|
-
await client.disconnect();
|
|
661
|
-
console.log(`[MCP] Disconnected from ${name}`);
|
|
662
|
-
} catch (error) {
|
|
663
|
-
console.error(`[MCP] Error disconnecting from ${name}:`, error);
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
this.clients.clear();
|
|
667
|
-
}
|
|
668
|
-
/**
|
|
669
|
-
* Get a specific client by name.
|
|
670
|
-
*/
|
|
671
|
-
getClient(name) {
|
|
672
|
-
return this.clients.get(name);
|
|
673
|
-
}
|
|
674
|
-
/**
|
|
675
|
-
* Get all connected clients.
|
|
676
|
-
*/
|
|
677
|
-
getAllClients() {
|
|
678
|
-
return Array.from(this.clients.values());
|
|
679
|
-
}
|
|
680
|
-
/**
|
|
681
|
-
* Check if a client is connected.
|
|
682
|
-
*/
|
|
683
|
-
isConnected(name) {
|
|
684
|
-
return this.clients.get(name)?.connected ?? false;
|
|
685
|
-
}
|
|
686
|
-
/**
|
|
687
|
-
* Get status of all servers.
|
|
688
|
-
*/
|
|
689
|
-
async getStatus() {
|
|
690
|
-
const statuses = [];
|
|
691
|
-
for (const [name, client] of this.clients) {
|
|
692
|
-
const status = {
|
|
693
|
-
name,
|
|
694
|
-
connected: client.connected
|
|
695
|
-
};
|
|
696
|
-
if (client.connected) {
|
|
697
|
-
try {
|
|
698
|
-
const tools = await client.listTools();
|
|
699
|
-
status.toolCount = tools.length;
|
|
700
|
-
} catch {
|
|
701
|
-
}
|
|
702
|
-
try {
|
|
703
|
-
const resources = await client.listResources();
|
|
704
|
-
status.resourceCount = resources.length;
|
|
705
|
-
} catch {
|
|
706
|
-
}
|
|
707
|
-
try {
|
|
708
|
-
const prompts = await client.listPrompts();
|
|
709
|
-
status.promptCount = prompts.length;
|
|
710
|
-
} catch {
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
statuses.push(status);
|
|
714
|
-
}
|
|
715
|
-
return statuses;
|
|
716
|
-
}
|
|
717
|
-
/**
|
|
718
|
-
* Get all tools from all connected servers.
|
|
719
|
-
*/
|
|
720
|
-
async listAllTools() {
|
|
721
|
-
const allTools = {};
|
|
722
|
-
for (const [name, client] of this.clients) {
|
|
723
|
-
if (client.connected) {
|
|
724
|
-
try {
|
|
725
|
-
allTools[name] = await client.listTools();
|
|
726
|
-
} catch (error) {
|
|
727
|
-
console.error(`[MCP] Failed to list tools from ${name}:`, error);
|
|
728
|
-
allTools[name] = [];
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
return allTools;
|
|
733
|
-
}
|
|
734
|
-
/**
|
|
735
|
-
* Get all resources from all connected servers.
|
|
736
|
-
*/
|
|
737
|
-
async listAllResources() {
|
|
738
|
-
const allResources = {};
|
|
739
|
-
for (const [name, client] of this.clients) {
|
|
740
|
-
if (client.connected) {
|
|
741
|
-
try {
|
|
742
|
-
allResources[name] = await client.listResources();
|
|
743
|
-
} catch (error) {
|
|
744
|
-
console.error(`[MCP] Failed to list resources from ${name}:`, error);
|
|
745
|
-
allResources[name] = [];
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
return allResources;
|
|
750
|
-
}
|
|
751
|
-
/**
|
|
752
|
-
* Get all prompts from all connected servers.
|
|
753
|
-
*/
|
|
754
|
-
async listAllPrompts() {
|
|
755
|
-
const allPrompts = {};
|
|
756
|
-
for (const [name, client] of this.clients) {
|
|
757
|
-
if (client.connected) {
|
|
758
|
-
try {
|
|
759
|
-
allPrompts[name] = await client.listPrompts();
|
|
760
|
-
} catch (error) {
|
|
761
|
-
console.error(`[MCP] Failed to list prompts from ${name}:`, error);
|
|
762
|
-
allPrompts[name] = [];
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
return allPrompts;
|
|
767
|
-
}
|
|
768
|
-
/**
|
|
769
|
-
* Reload all connections.
|
|
770
|
-
*/
|
|
771
|
-
async reload() {
|
|
772
|
-
await this.disconnectAll();
|
|
773
|
-
await this.connectAll();
|
|
774
|
-
}
|
|
775
|
-
/**
|
|
776
|
-
* Add a new server connection.
|
|
777
|
-
*/
|
|
778
|
-
async addServer(config) {
|
|
779
|
-
if (this.clients.has(config.name)) {
|
|
780
|
-
console.warn(`[MCP] Server ${config.name} already exists`);
|
|
781
|
-
return false;
|
|
782
|
-
}
|
|
783
|
-
try {
|
|
784
|
-
const client = new MCPClient(config);
|
|
785
|
-
await client.connect();
|
|
786
|
-
this.clients.set(config.name, client);
|
|
787
|
-
console.log(`[MCP] Connected to ${config.name}`);
|
|
788
|
-
return true;
|
|
789
|
-
} catch (error) {
|
|
790
|
-
console.error(`[MCP] Failed to connect to ${config.name}:`, error);
|
|
791
|
-
return false;
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
/**
|
|
795
|
-
* Remove a server connection.
|
|
796
|
-
*/
|
|
797
|
-
async removeServer(name) {
|
|
798
|
-
const client = this.clients.get(name);
|
|
799
|
-
if (!client) {
|
|
800
|
-
return false;
|
|
801
|
-
}
|
|
802
|
-
try {
|
|
803
|
-
await client.disconnect();
|
|
804
|
-
this.clients.delete(name);
|
|
805
|
-
console.log(`[MCP] Disconnected from ${name}`);
|
|
806
|
-
return true;
|
|
807
|
-
} catch (error) {
|
|
808
|
-
console.error(`[MCP] Error disconnecting from ${name}:`, error);
|
|
809
|
-
return false;
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
};
|
|
813
|
-
|
|
814
|
-
// src/facade/mcp-core/config.ts
|
|
815
|
-
import { existsSync, readFileSync, mkdirSync, statSync, writeFileSync } from "fs";
|
|
816
|
-
import { join, dirname } from "path";
|
|
817
|
-
import { homedir } from "os";
|
|
818
|
-
function loadMCPConfig(configPathOrCwd = process.cwd()) {
|
|
819
|
-
const configs = [];
|
|
820
|
-
if (existsSync(configPathOrCwd)) {
|
|
821
|
-
try {
|
|
822
|
-
const stats = statSync(configPathOrCwd);
|
|
823
|
-
if (stats.isFile()) {
|
|
824
|
-
const fileConfigs = parseConfigFile(configPathOrCwd);
|
|
825
|
-
configs.push(...fileConfigs);
|
|
826
|
-
return configs;
|
|
827
|
-
}
|
|
828
|
-
} catch {
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
const cwd = configPathOrCwd;
|
|
832
|
-
const projectConfig = join(cwd, ".indusvx", "mcp.json");
|
|
833
|
-
if (existsSync(projectConfig)) {
|
|
834
|
-
try {
|
|
835
|
-
const projectConfigs = parseConfigFile(projectConfig);
|
|
836
|
-
configs.push(...projectConfigs);
|
|
837
|
-
console.log(`[MCP] Loaded ${projectConfigs.length} servers from project config`);
|
|
838
|
-
} catch (error) {
|
|
839
|
-
console.error(`[MCP] Error loading project config:`, error);
|
|
840
|
-
}
|
|
841
|
-
}
|
|
842
|
-
const xdgConfigHome = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
|
|
843
|
-
const userConfig = join(xdgConfigHome, "indusvx", "mcp.json");
|
|
844
|
-
if (existsSync(userConfig)) {
|
|
845
|
-
try {
|
|
846
|
-
const userConfigs = parseConfigFile(userConfig);
|
|
847
|
-
configs.push(...userConfigs);
|
|
848
|
-
console.log(`[MCP] Loaded ${userConfigs.length} servers from user config`);
|
|
849
|
-
} catch (error) {
|
|
850
|
-
console.error(`[MCP] Error loading user config:`, error);
|
|
851
|
-
}
|
|
852
|
-
}
|
|
853
|
-
const legacyConfig = join(homedir(), ".indusvx", "agent", "mcp.json");
|
|
854
|
-
if (existsSync(legacyConfig)) {
|
|
855
|
-
try {
|
|
856
|
-
const legacyConfigs = parseConfigFile(legacyConfig);
|
|
857
|
-
configs.push(...legacyConfigs);
|
|
858
|
-
console.log(`[MCP] Loaded ${legacyConfigs.length} servers from legacy config`);
|
|
859
|
-
} catch (error) {
|
|
860
|
-
console.error(`[MCP] Error loading legacy config:`, error);
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
const legacyServersConfig = join(homedir(), ".indusvx", "agent", "mcp-servers.json");
|
|
864
|
-
if (existsSync(legacyServersConfig)) {
|
|
865
|
-
try {
|
|
866
|
-
const legacyConfigs = parseConfigFile(legacyServersConfig);
|
|
867
|
-
configs.push(...legacyConfigs);
|
|
868
|
-
console.log(`[MCP] Loaded ${legacyConfigs.length} servers from mcp-servers.json`);
|
|
869
|
-
} catch (error) {
|
|
870
|
-
console.error(`[MCP] Error loading mcp-servers.json:`, error);
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
return configs;
|
|
874
|
-
}
|
|
875
|
-
function parseConfigFile(path) {
|
|
876
|
-
const content = readFileSync(path, "utf-8");
|
|
877
|
-
const config = JSON.parse(content);
|
|
878
|
-
if (!config.servers) {
|
|
879
|
-
console.warn(`[MCP] Invalid config file ${path}: missing "servers" field`);
|
|
880
|
-
return [];
|
|
881
|
-
}
|
|
882
|
-
let serversArray;
|
|
883
|
-
if (Array.isArray(config.servers)) {
|
|
884
|
-
serversArray = config.servers;
|
|
885
|
-
} else if (typeof config.servers === "object") {
|
|
886
|
-
serversArray = Object.entries(config.servers).map(([name, serverConfig]) => ({
|
|
887
|
-
name,
|
|
888
|
-
...serverConfig
|
|
889
|
-
}));
|
|
890
|
-
} else {
|
|
891
|
-
console.warn(`[MCP] Invalid config file ${path}: "servers" must be array or object`);
|
|
892
|
-
return [];
|
|
893
|
-
}
|
|
894
|
-
return serversArray.filter((server) => server.enabled !== false).map((server) => {
|
|
895
|
-
if (server.url) {
|
|
896
|
-
return {
|
|
897
|
-
name: server.name,
|
|
898
|
-
config: {
|
|
899
|
-
url: new URL(server.url),
|
|
900
|
-
headers: server.headers,
|
|
901
|
-
...server.transport ? { transport: server.transport } : {}
|
|
902
|
-
},
|
|
903
|
-
timeout: server.timeout
|
|
904
|
-
};
|
|
905
|
-
} else if (server.command) {
|
|
906
|
-
return {
|
|
907
|
-
name: server.name,
|
|
908
|
-
config: {
|
|
909
|
-
command: server.command,
|
|
910
|
-
args: server.args,
|
|
911
|
-
env: server.env
|
|
912
|
-
},
|
|
913
|
-
timeout: server.timeout
|
|
914
|
-
};
|
|
915
|
-
}
|
|
916
|
-
throw new MCPError(
|
|
917
|
-
`Invalid server config: ${server.name}`,
|
|
918
|
-
"CONFIG_ERROR" /* CONFIG_ERROR */,
|
|
919
|
-
{ server }
|
|
920
|
-
);
|
|
921
|
-
});
|
|
922
|
-
}
|
|
923
|
-
function getUserConfigPath() {
|
|
924
|
-
const xdgConfigHome = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
|
|
925
|
-
return join(xdgConfigHome, "indusvx", "mcp.json");
|
|
926
|
-
}
|
|
927
|
-
function getProjectConfigPath(cwd = process.cwd()) {
|
|
928
|
-
return join(cwd, ".indusvx", "mcp.json");
|
|
929
|
-
}
|
|
930
|
-
function ensureUserConfigDir() {
|
|
931
|
-
const xdgConfigHome = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
|
|
932
|
-
const configDir = join(xdgConfigHome, "indusvx");
|
|
933
|
-
if (!existsSync(configDir)) {
|
|
934
|
-
mkdirSync(configDir, { recursive: true });
|
|
935
|
-
}
|
|
936
|
-
return configDir;
|
|
937
|
-
}
|
|
938
|
-
function ensureProjectConfigDir(cwd = process.cwd()) {
|
|
939
|
-
const configDir = join(cwd, ".indusvx");
|
|
940
|
-
if (!existsSync(configDir)) {
|
|
941
|
-
mkdirSync(configDir, { recursive: true });
|
|
942
|
-
}
|
|
943
|
-
return configDir;
|
|
944
|
-
}
|
|
945
|
-
function saveConfig(path, config) {
|
|
946
|
-
const dir = dirname(path);
|
|
947
|
-
if (!existsSync(dir)) {
|
|
948
|
-
mkdirSync(dir, { recursive: true });
|
|
949
|
-
}
|
|
950
|
-
const content = JSON.stringify(config, null, 2);
|
|
951
|
-
writeFileSync(path, content, "utf-8");
|
|
952
|
-
}
|
|
953
|
-
function saveUserConfig(config) {
|
|
954
|
-
saveConfig(getUserConfigPath(), config);
|
|
955
|
-
}
|
|
956
|
-
function saveProjectConfig(config, cwd = process.cwd()) {
|
|
957
|
-
saveConfig(getProjectConfigPath(cwd), config);
|
|
958
|
-
}
|
|
959
|
-
function createDefaultConfig() {
|
|
960
|
-
return {
|
|
961
|
-
servers: []
|
|
962
|
-
};
|
|
963
|
-
}
|
|
964
|
-
var EXAMPLE_CONFIG = {
|
|
965
|
-
servers: [
|
|
966
|
-
{
|
|
967
|
-
name: "filesystem",
|
|
968
|
-
command: "npx",
|
|
969
|
-
args: ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"],
|
|
970
|
-
enabled: true
|
|
971
|
-
},
|
|
972
|
-
{
|
|
973
|
-
name: "github",
|
|
974
|
-
command: "npx",
|
|
975
|
-
args: ["-y", "@modelcontextprotocol/server-github"],
|
|
976
|
-
env: {
|
|
977
|
-
GITHUB_TOKEN: "your-github-token"
|
|
978
|
-
},
|
|
979
|
-
enabled: true
|
|
980
|
-
},
|
|
981
|
-
{
|
|
982
|
-
name: "remote-server",
|
|
983
|
-
url: "http://localhost:8080/mcp",
|
|
984
|
-
headers: {
|
|
985
|
-
Authorization: "Bearer your-token"
|
|
986
|
-
},
|
|
987
|
-
enabled: false
|
|
988
|
-
}
|
|
989
|
-
]
|
|
990
|
-
};
|
|
991
|
-
|
|
992
|
-
// src/facade/mcp-core/schema-converter.ts
|
|
993
|
-
import { Type } from "@sinclair/typebox";
|
|
994
|
-
function jsonSchemaToTypeBox(schema) {
|
|
995
|
-
if (schema.type === "null") {
|
|
996
|
-
return Type.Null({ description: schema.description });
|
|
997
|
-
}
|
|
998
|
-
if (schema.enum) {
|
|
999
|
-
if (schema.enum.length === 1) {
|
|
1000
|
-
return Type.Literal(schema.enum[0], {
|
|
1001
|
-
description: schema.description
|
|
1002
|
-
});
|
|
1003
|
-
}
|
|
1004
|
-
const literals = schema.enum.map((e) => {
|
|
1005
|
-
if (e === null) return Type.Null();
|
|
1006
|
-
return Type.Literal(e);
|
|
1007
|
-
});
|
|
1008
|
-
return Type.Union(literals, { description: schema.description });
|
|
1009
|
-
}
|
|
1010
|
-
if (schema.const !== void 0) {
|
|
1011
|
-
if (schema.const === null) {
|
|
1012
|
-
return Type.Null({ description: schema.description });
|
|
1013
|
-
}
|
|
1014
|
-
return Type.Literal(schema.const, {
|
|
1015
|
-
description: schema.description
|
|
1016
|
-
});
|
|
1017
|
-
}
|
|
1018
|
-
if (schema.oneOf || schema.anyOf) {
|
|
1019
|
-
const schemas = (schema.oneOf || schema.anyOf).map((s) => jsonSchemaToTypeBox(s));
|
|
1020
|
-
return Type.Union(schemas, { description: schema.description });
|
|
1021
|
-
}
|
|
1022
|
-
if (schema.allOf) {
|
|
1023
|
-
const schemas = schema.allOf.map((s) => jsonSchemaToTypeBox(s));
|
|
1024
|
-
return Type.Intersect(schemas, { description: schema.description });
|
|
1025
|
-
}
|
|
1026
|
-
if (schema.type === "array" || Array.isArray(schema.type) && schema.type.includes("array")) {
|
|
1027
|
-
return convertArraySchema(schema);
|
|
1028
|
-
}
|
|
1029
|
-
if (schema.type === "object" || Array.isArray(schema.type) && schema.type.includes("object")) {
|
|
1030
|
-
return convertObjectSchema(schema);
|
|
1031
|
-
}
|
|
1032
|
-
switch (schema.type) {
|
|
1033
|
-
case "string":
|
|
1034
|
-
return convertStringSchema(schema);
|
|
1035
|
-
case "number":
|
|
1036
|
-
case "integer":
|
|
1037
|
-
return convertNumberSchema(schema);
|
|
1038
|
-
case "boolean":
|
|
1039
|
-
return Type.Boolean({ description: schema.description });
|
|
1040
|
-
default:
|
|
1041
|
-
if (schema.properties) {
|
|
1042
|
-
return convertObjectSchema(schema);
|
|
1043
|
-
}
|
|
1044
|
-
if (schema.items) {
|
|
1045
|
-
return convertArraySchema(schema);
|
|
1046
|
-
}
|
|
1047
|
-
return Type.Any({ description: schema.description });
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
function convertStringSchema(schema) {
|
|
1051
|
-
return Type.String({
|
|
1052
|
-
description: schema.description,
|
|
1053
|
-
minLength: schema.minLength,
|
|
1054
|
-
maxLength: schema.maxLength,
|
|
1055
|
-
pattern: schema.pattern,
|
|
1056
|
-
format: schema.format
|
|
1057
|
-
});
|
|
1058
|
-
}
|
|
1059
|
-
function convertNumberSchema(schema) {
|
|
1060
|
-
const options = {
|
|
1061
|
-
description: schema.description
|
|
1062
|
-
};
|
|
1063
|
-
if (schema.minimum !== void 0) options.minimum = schema.minimum;
|
|
1064
|
-
if (schema.maximum !== void 0) options.maximum = schema.maximum;
|
|
1065
|
-
if (typeof schema.exclusiveMinimum === "number") options.exclusiveMinimum = schema.exclusiveMinimum;
|
|
1066
|
-
if (typeof schema.exclusiveMaximum === "number") options.exclusiveMaximum = schema.exclusiveMaximum;
|
|
1067
|
-
if (schema.multipleOf !== void 0) options.multipleOf = schema.multipleOf;
|
|
1068
|
-
return Type.Number(options);
|
|
1069
|
-
}
|
|
1070
|
-
function convertArraySchema(schema) {
|
|
1071
|
-
let itemsSchema;
|
|
1072
|
-
if (schema.items) {
|
|
1073
|
-
if (Array.isArray(schema.items)) {
|
|
1074
|
-
const items = schema.items.map((item) => jsonSchemaToTypeBox(item));
|
|
1075
|
-
itemsSchema = Type.Tuple(items);
|
|
1076
|
-
} else {
|
|
1077
|
-
itemsSchema = jsonSchemaToTypeBox(schema.items);
|
|
1078
|
-
}
|
|
1079
|
-
} else {
|
|
1080
|
-
itemsSchema = Type.Any();
|
|
1081
|
-
}
|
|
1082
|
-
return Type.Array(itemsSchema, {
|
|
1083
|
-
description: schema.description,
|
|
1084
|
-
minItems: schema.minItems,
|
|
1085
|
-
maxItems: schema.maxItems
|
|
1086
|
-
});
|
|
1087
|
-
}
|
|
1088
|
-
function convertObjectSchema(schema) {
|
|
1089
|
-
const properties = {};
|
|
1090
|
-
const required = new Set(schema.required ?? []);
|
|
1091
|
-
for (const [key, value] of Object.entries(schema.properties ?? {})) {
|
|
1092
|
-
let propSchema = jsonSchemaToTypeBox(value);
|
|
1093
|
-
if (!required.has(key)) {
|
|
1094
|
-
propSchema = Type.Optional(propSchema);
|
|
1095
|
-
}
|
|
1096
|
-
properties[key] = propSchema;
|
|
1097
|
-
}
|
|
1098
|
-
let additionalProperties = void 0;
|
|
1099
|
-
if (schema.additionalProperties === true) {
|
|
1100
|
-
additionalProperties = true;
|
|
1101
|
-
} else if (schema.additionalProperties && typeof schema.additionalProperties === "object") {
|
|
1102
|
-
additionalProperties = jsonSchemaToTypeBox(schema.additionalProperties);
|
|
1103
|
-
} else if (schema.additionalProperties === false) {
|
|
1104
|
-
additionalProperties = false;
|
|
1105
|
-
}
|
|
1106
|
-
return Type.Object(properties, {
|
|
1107
|
-
description: schema.description,
|
|
1108
|
-
additionalProperties
|
|
1109
|
-
});
|
|
1110
|
-
}
|
|
1111
|
-
function applyPassthrough(schema) {
|
|
1112
|
-
const kind = schema[/* @__PURE__ */ Symbol.for("TypeBox.Kind")];
|
|
1113
|
-
if (kind === "Object") {
|
|
1114
|
-
const shape = { ...schema.properties };
|
|
1115
|
-
for (const key of Object.keys(shape)) {
|
|
1116
|
-
shape[key] = applyPassthrough(shape[key]);
|
|
1117
|
-
}
|
|
1118
|
-
return Type.Object(shape, {
|
|
1119
|
-
description: schema.description,
|
|
1120
|
-
additionalProperties: true
|
|
1121
|
-
});
|
|
1122
|
-
}
|
|
1123
|
-
if (kind === "Array") {
|
|
1124
|
-
return Type.Array(applyPassthrough(schema.items), {
|
|
1125
|
-
description: schema.description,
|
|
1126
|
-
minItems: schema.minItems,
|
|
1127
|
-
maxItems: schema.maxItems
|
|
1128
|
-
});
|
|
1129
|
-
}
|
|
1130
|
-
if (kind === "Union") {
|
|
1131
|
-
return Type.Union(
|
|
1132
|
-
schema.anyOf.map((s) => applyPassthrough(s)),
|
|
1133
|
-
{ description: schema.description }
|
|
1134
|
-
);
|
|
1135
|
-
}
|
|
1136
|
-
if (kind === "Intersect") {
|
|
1137
|
-
return Type.Intersect(
|
|
1138
|
-
schema.allOf.map((s) => applyPassthrough(s)),
|
|
1139
|
-
{ description: schema.description }
|
|
1140
|
-
);
|
|
1141
|
-
}
|
|
1142
|
-
if (kind === "Optional") {
|
|
1143
|
-
return Type.Optional(applyPassthrough(schema.schema ?? schema.type));
|
|
1144
|
-
}
|
|
1145
|
-
return schema;
|
|
1146
|
-
}
|
|
1147
|
-
function convertMCPInputSchema(inputSchema) {
|
|
1148
|
-
const typeboxSchema = jsonSchemaToTypeBox(inputSchema);
|
|
1149
|
-
return applyPassthrough(typeboxSchema);
|
|
1150
|
-
}
|
|
1151
|
-
function convertMCPOutputSchema(outputSchema) {
|
|
1152
|
-
if (!outputSchema) return void 0;
|
|
1153
|
-
const typeboxSchema = jsonSchemaToTypeBox(outputSchema);
|
|
1154
|
-
return applyPassthrough(typeboxSchema);
|
|
1155
|
-
}
|
|
1156
|
-
|
|
1157
|
-
// src/facade/mcp-core/tool-factory.ts
|
|
1158
|
-
function createMCPAgentToolFactory(mcpTool, client) {
|
|
1159
|
-
return () => {
|
|
1160
|
-
const namespacedName = `${client.serverName}_${mcpTool.name}`;
|
|
1161
|
-
const parameters = convertMCPInputSchema(mcpTool.inputSchema);
|
|
1162
|
-
return {
|
|
1163
|
-
name: namespacedName,
|
|
1164
|
-
label: mcpTool.name,
|
|
1165
|
-
description: `[${client.serverName}] ${mcpTool.description || ""}`,
|
|
1166
|
-
category: "mcp",
|
|
1167
|
-
parameters,
|
|
1168
|
-
execute: async (toolCallId, params, signal, onUpdate) => {
|
|
1169
|
-
const typedParams = params;
|
|
1170
|
-
try {
|
|
1171
|
-
if (!client.connected) {
|
|
1172
|
-
throw new MCPError(
|
|
1173
|
-
`MCP server ${client.serverName} not connected`,
|
|
1174
|
-
"NOT_CONNECTED" /* NOT_CONNECTED */,
|
|
1175
|
-
void 0,
|
|
1176
|
-
{ serverName: client.serverName, toolName: mcpTool.name }
|
|
1177
|
-
);
|
|
1178
|
-
}
|
|
1179
|
-
if (signal?.aborted) {
|
|
1180
|
-
throw new MCPError(
|
|
1181
|
-
"Tool execution aborted",
|
|
1182
|
-
"TIMEOUT" /* TIMEOUT */,
|
|
1183
|
-
void 0,
|
|
1184
|
-
{ serverName: client.serverName, toolName: mcpTool.name }
|
|
1185
|
-
);
|
|
1186
|
-
}
|
|
1187
|
-
const result = await client.callTool(mcpTool.name, typedParams);
|
|
1188
|
-
return convertMCPResultToAgentResult(result, client.serverName, mcpTool.name);
|
|
1189
|
-
} catch (error) {
|
|
1190
|
-
if (error instanceof MCPError) {
|
|
1191
|
-
return {
|
|
1192
|
-
content: [
|
|
1193
|
-
{
|
|
1194
|
-
type: "text",
|
|
1195
|
-
text: `MCP Error: ${error.message}`
|
|
1196
|
-
}
|
|
1197
|
-
],
|
|
1198
|
-
details: {
|
|
1199
|
-
error: error.message,
|
|
1200
|
-
code: error.code,
|
|
1201
|
-
serverName: error.serverName,
|
|
1202
|
-
toolName: error.toolName
|
|
1203
|
-
},
|
|
1204
|
-
isError: true
|
|
1205
|
-
};
|
|
1206
|
-
}
|
|
1207
|
-
if (error instanceof Error && error.name === "AbortError") {
|
|
1208
|
-
return {
|
|
1209
|
-
content: [
|
|
1210
|
-
{
|
|
1211
|
-
type: "text",
|
|
1212
|
-
text: `Tool execution aborted`
|
|
1213
|
-
}
|
|
1214
|
-
],
|
|
1215
|
-
details: {
|
|
1216
|
-
error: "Aborted"
|
|
1217
|
-
},
|
|
1218
|
-
isError: true
|
|
1219
|
-
};
|
|
1220
|
-
}
|
|
1221
|
-
return {
|
|
1222
|
-
content: [
|
|
1223
|
-
{
|
|
1224
|
-
type: "text",
|
|
1225
|
-
text: `Error: ${error instanceof Error ? error.message : String(error)}`
|
|
1226
|
-
}
|
|
1227
|
-
],
|
|
1228
|
-
details: {
|
|
1229
|
-
error: String(error)
|
|
1230
|
-
},
|
|
1231
|
-
isError: true
|
|
1232
|
-
};
|
|
1233
|
-
}
|
|
1234
|
-
}
|
|
1235
|
-
};
|
|
1236
|
-
};
|
|
1237
|
-
}
|
|
1238
|
-
function truncateTextForDisplay(text, maxLines = 4, maxChars = 500) {
|
|
1239
|
-
const lines = text.split("\n");
|
|
1240
|
-
if (lines.length <= maxLines && text.length <= maxChars) {
|
|
1241
|
-
return text;
|
|
1242
|
-
}
|
|
1243
|
-
let truncated = lines.slice(0, maxLines).join("\n");
|
|
1244
|
-
if (truncated.length > maxChars) {
|
|
1245
|
-
truncated = truncated.slice(0, maxChars);
|
|
1246
|
-
}
|
|
1247
|
-
const remaining = lines.length - maxLines;
|
|
1248
|
-
if (remaining > 0) {
|
|
1249
|
-
truncated += `
|
|
1250
|
-
... (${remaining} more lines)`;
|
|
1251
|
-
} else if (text.length > maxChars) {
|
|
1252
|
-
truncated += "...";
|
|
1253
|
-
}
|
|
1254
|
-
return truncated;
|
|
1255
|
-
}
|
|
1256
|
-
function convertMCPResultToAgentResult(result, serverName, toolName) {
|
|
1257
|
-
const content = [];
|
|
1258
|
-
if (result.content && Array.isArray(result.content)) {
|
|
1259
|
-
for (const item of result.content) {
|
|
1260
|
-
if (item.type === "text") {
|
|
1261
|
-
const truncatedText = truncateTextForDisplay(item.text);
|
|
1262
|
-
content.push({ type: "text", text: truncatedText });
|
|
1263
|
-
} else if (item.type === "image") {
|
|
1264
|
-
content.push({
|
|
1265
|
-
type: "image",
|
|
1266
|
-
data: item.data,
|
|
1267
|
-
mimeType: item.mimeType
|
|
1268
|
-
});
|
|
1269
|
-
}
|
|
1270
|
-
}
|
|
1271
|
-
} else if (typeof result === "string") {
|
|
1272
|
-
const truncatedText = truncateTextForDisplay(result);
|
|
1273
|
-
content.push({ type: "text", text: truncatedText });
|
|
1274
|
-
} else {
|
|
1275
|
-
const jsonStr = JSON.stringify(result, null, 2);
|
|
1276
|
-
const truncatedText = truncateTextForDisplay(jsonStr);
|
|
1277
|
-
content.push({ type: "text", text: truncatedText });
|
|
1278
|
-
}
|
|
1279
|
-
return {
|
|
1280
|
-
content,
|
|
1281
|
-
details: result,
|
|
1282
|
-
isError: result.isError || false
|
|
1283
|
-
};
|
|
1284
|
-
}
|
|
1285
|
-
async function registerMCPToolsInRegistry(registry, client, tools) {
|
|
1286
|
-
let registeredCount = 0;
|
|
1287
|
-
for (const tool of tools) {
|
|
1288
|
-
try {
|
|
1289
|
-
const factory = createMCPAgentToolFactory(tool, client);
|
|
1290
|
-
registry.register(
|
|
1291
|
-
{
|
|
1292
|
-
name: `${client.serverName}_${tool.name}`,
|
|
1293
|
-
label: tool.name,
|
|
1294
|
-
category: "mcp",
|
|
1295
|
-
description: `[${client.serverName}] ${tool.description || ""}`
|
|
1296
|
-
},
|
|
1297
|
-
factory
|
|
1298
|
-
);
|
|
1299
|
-
registeredCount++;
|
|
1300
|
-
} catch (error) {
|
|
1301
|
-
console.error(`Failed to register MCP tool ${tool.name}:`, error);
|
|
1302
|
-
}
|
|
1303
|
-
}
|
|
1304
|
-
return registeredCount;
|
|
1305
|
-
}
|
|
1306
|
-
function createMCPToolsMap(tools, client) {
|
|
1307
|
-
const toolMap = /* @__PURE__ */ new Map();
|
|
1308
|
-
for (const tool of tools) {
|
|
1309
|
-
const factory = createMCPAgentToolFactory(tool, client);
|
|
1310
|
-
const namespacedName = `${client.serverName}_${tool.name}`;
|
|
1311
|
-
toolMap.set(namespacedName, factory());
|
|
1312
|
-
}
|
|
1313
|
-
return toolMap;
|
|
1314
|
-
}
|
|
1315
|
-
function createMCPToolsRecord(tools, client) {
|
|
1316
|
-
const toolRecord = {};
|
|
1317
|
-
for (const tool of tools) {
|
|
1318
|
-
const factory = createMCPAgentToolFactory(tool, client);
|
|
1319
|
-
const namespacedName = `${client.serverName}_${tool.name}`;
|
|
1320
|
-
toolRecord[namespacedName] = factory();
|
|
1321
|
-
}
|
|
1322
|
-
return toolRecord;
|
|
1323
|
-
}
|
|
1324
|
-
|
|
1325
|
-
// src/facade/mcp-core/server.ts
|
|
1326
|
-
var MCPServer = class {
|
|
1327
|
-
constructor(options) {
|
|
1328
|
-
this.options = options;
|
|
1329
|
-
this.name = options.name;
|
|
1330
|
-
this.version = options.version || "1.0.0";
|
|
1331
|
-
for (const tool of options.tools) {
|
|
1332
|
-
const converted = this.convertTool(tool);
|
|
1333
|
-
this.tools.set(converted.name, converted);
|
|
1334
|
-
}
|
|
1335
|
-
console.error(`[MCP Server] Initialized "${this.name}" v${this.version} with ${this.tools.size} tools`);
|
|
1336
|
-
}
|
|
1337
|
-
options;
|
|
1338
|
-
tools = /* @__PURE__ */ new Map();
|
|
1339
|
-
buffer = "";
|
|
1340
|
-
isConnected = false;
|
|
1341
|
-
/** Server name */
|
|
1342
|
-
name;
|
|
1343
|
-
/** Server version */
|
|
1344
|
-
version;
|
|
1345
|
-
// ========================================================================
|
|
1346
|
-
// Lifecycle
|
|
1347
|
-
// ========================================================================
|
|
1348
|
-
/**
|
|
1349
|
-
* Start the server using stdio transport.
|
|
1350
|
-
*
|
|
1351
|
-
* This is typically used when running the server as a subprocess
|
|
1352
|
-
* that MCP clients (like Claude Desktop) spawn.
|
|
1353
|
-
*/
|
|
1354
|
-
async startStdio() {
|
|
1355
|
-
this.isConnected = true;
|
|
1356
|
-
console.error(`[MCP Server] Starting stdio transport`);
|
|
1357
|
-
process.stdin.setEncoding("utf8");
|
|
1358
|
-
process.stdin.on("data", (chunk) => {
|
|
1359
|
-
this.buffer += chunk;
|
|
1360
|
-
this.processBuffer();
|
|
1361
|
-
});
|
|
1362
|
-
process.stdin.on("end", () => {
|
|
1363
|
-
console.error(`[MCP Server] Stdin closed, shutting down`);
|
|
1364
|
-
this.isConnected = false;
|
|
1365
|
-
process.exit(0);
|
|
1366
|
-
});
|
|
1367
|
-
return new Promise(() => {
|
|
1368
|
-
});
|
|
1369
|
-
}
|
|
1370
|
-
/**
|
|
1371
|
-
* Stop the server.
|
|
1372
|
-
*/
|
|
1373
|
-
async stop() {
|
|
1374
|
-
this.isConnected = false;
|
|
1375
|
-
console.error(`[MCP Server] Stopped`);
|
|
1376
|
-
}
|
|
1377
|
-
// ========================================================================
|
|
1378
|
-
// Tool Management
|
|
1379
|
-
// ========================================================================
|
|
1380
|
-
/**
|
|
1381
|
-
* Add a tool to the server.
|
|
1382
|
-
*/
|
|
1383
|
-
addTool(tool) {
|
|
1384
|
-
const converted = this.convertTool(tool);
|
|
1385
|
-
this.tools.set(converted.name, converted);
|
|
1386
|
-
console.error(`[MCP Server] Added tool: ${converted.name}`);
|
|
1387
|
-
}
|
|
1388
|
-
/**
|
|
1389
|
-
* Remove a tool from the server.
|
|
1390
|
-
*/
|
|
1391
|
-
removeTool(name) {
|
|
1392
|
-
const result = this.tools.delete(name);
|
|
1393
|
-
if (result) {
|
|
1394
|
-
console.error(`[MCP Server] Removed tool: ${name}`);
|
|
1395
|
-
}
|
|
1396
|
-
return result;
|
|
1397
|
-
}
|
|
1398
|
-
/**
|
|
1399
|
-
* List all available tools.
|
|
1400
|
-
*/
|
|
1401
|
-
listTools() {
|
|
1402
|
-
return Array.from(this.tools.values());
|
|
1403
|
-
}
|
|
1404
|
-
// ========================================================================
|
|
1405
|
-
// Private Methods
|
|
1406
|
-
// ========================================================================
|
|
1407
|
-
convertTool(tool) {
|
|
1408
|
-
const inputSchema = this.typeBoxToJsonSchema(tool.parameters);
|
|
1409
|
-
return {
|
|
1410
|
-
name: tool.name,
|
|
1411
|
-
description: tool.description || tool.label,
|
|
1412
|
-
inputSchema,
|
|
1413
|
-
execute: async (args) => {
|
|
1414
|
-
const result = await tool.execute(
|
|
1415
|
-
`mcp_${Date.now()}`,
|
|
1416
|
-
args,
|
|
1417
|
-
void 0,
|
|
1418
|
-
void 0
|
|
1419
|
-
);
|
|
1420
|
-
return result;
|
|
1421
|
-
}
|
|
1422
|
-
};
|
|
1423
|
-
}
|
|
1424
|
-
typeBoxToJsonSchema(schema) {
|
|
1425
|
-
if (!schema) {
|
|
1426
|
-
return { type: "object", properties: {} };
|
|
1427
|
-
}
|
|
1428
|
-
if (schema.type || schema.properties || schema.$schema) {
|
|
1429
|
-
return schema;
|
|
1430
|
-
}
|
|
1431
|
-
const jsonSchema = schema.toJSONSchema?.() || schema;
|
|
1432
|
-
return {
|
|
1433
|
-
type: "object",
|
|
1434
|
-
properties: jsonSchema.properties || {},
|
|
1435
|
-
required: jsonSchema.required || []
|
|
1436
|
-
};
|
|
1437
|
-
}
|
|
1438
|
-
processBuffer() {
|
|
1439
|
-
const lines = this.buffer.split("\n");
|
|
1440
|
-
this.buffer = lines.pop() || "";
|
|
1441
|
-
for (const line of lines) {
|
|
1442
|
-
const trimmed = line.trim();
|
|
1443
|
-
if (!trimmed) continue;
|
|
1444
|
-
try {
|
|
1445
|
-
const message = JSON.parse(trimmed);
|
|
1446
|
-
this.handleMessage(message);
|
|
1447
|
-
} catch (error) {
|
|
1448
|
-
console.error(`[MCP Server] Failed to parse message: ${trimmed}`);
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
async handleMessage(message) {
|
|
1453
|
-
console.error(`[MCP Server] Received: ${message.method || `response to ${message.id}`}`);
|
|
1454
|
-
try {
|
|
1455
|
-
if (message.method) {
|
|
1456
|
-
const response = await this.handleRequest(message);
|
|
1457
|
-
this.sendResponse(message.id, response);
|
|
1458
|
-
}
|
|
1459
|
-
} catch (error) {
|
|
1460
|
-
console.error(`[MCP Server] Error handling message:`, error);
|
|
1461
|
-
if (message.id !== void 0) {
|
|
1462
|
-
this.sendError(message.id, error);
|
|
1463
|
-
}
|
|
1464
|
-
}
|
|
1465
|
-
}
|
|
1466
|
-
async handleRequest(message) {
|
|
1467
|
-
switch (message.method) {
|
|
1468
|
-
case "initialize":
|
|
1469
|
-
return this.handleInitialize(message.params);
|
|
1470
|
-
case "tools/list":
|
|
1471
|
-
return this.handleToolsList();
|
|
1472
|
-
case "tools/call":
|
|
1473
|
-
return this.handleToolsCall(message.params);
|
|
1474
|
-
case "resources/list":
|
|
1475
|
-
return { resources: [] };
|
|
1476
|
-
case "prompts/list":
|
|
1477
|
-
return { prompts: [] };
|
|
1478
|
-
default:
|
|
1479
|
-
throw new MCPError(
|
|
1480
|
-
`Unknown method: ${message.method}`,
|
|
1481
|
-
"PROTOCOL_ERROR" /* PROTOCOL_ERROR */
|
|
1482
|
-
);
|
|
1483
|
-
}
|
|
1484
|
-
}
|
|
1485
|
-
handleInitialize(params) {
|
|
1486
|
-
console.error(`[MCP Server] Initialize from client: ${params?.clientInfo?.name || "unknown"}`);
|
|
1487
|
-
return {
|
|
1488
|
-
protocolVersion: "2024-11-05",
|
|
1489
|
-
serverInfo: {
|
|
1490
|
-
name: this.name,
|
|
1491
|
-
version: this.version
|
|
1492
|
-
},
|
|
1493
|
-
capabilities: {
|
|
1494
|
-
tools: {}
|
|
1495
|
-
}
|
|
1496
|
-
};
|
|
1497
|
-
}
|
|
1498
|
-
handleToolsList() {
|
|
1499
|
-
const tools = Array.from(this.tools.values()).map((tool) => ({
|
|
1500
|
-
name: tool.name,
|
|
1501
|
-
description: tool.description,
|
|
1502
|
-
inputSchema: tool.inputSchema
|
|
1503
|
-
}));
|
|
1504
|
-
return { tools };
|
|
1505
|
-
}
|
|
1506
|
-
async handleToolsCall(params) {
|
|
1507
|
-
const { name, arguments: args } = params;
|
|
1508
|
-
const tool = this.tools.get(name);
|
|
1509
|
-
if (!tool) {
|
|
1510
|
-
return {
|
|
1511
|
-
content: [{ type: "text", text: `Unknown tool: ${name}` }],
|
|
1512
|
-
isError: true
|
|
1513
|
-
};
|
|
1514
|
-
}
|
|
1515
|
-
try {
|
|
1516
|
-
console.error(`[MCP Server] Executing tool: ${name}`);
|
|
1517
|
-
const result = await tool.execute(args || {});
|
|
1518
|
-
if (result && typeof result === "object" && "content" in result) {
|
|
1519
|
-
const agentResult = result;
|
|
1520
|
-
const content = [];
|
|
1521
|
-
for (const item of agentResult.content || []) {
|
|
1522
|
-
if (item.type === "text") {
|
|
1523
|
-
content.push({ type: "text", text: item.text });
|
|
1524
|
-
} else if (item.type === "image") {
|
|
1525
|
-
content.push({
|
|
1526
|
-
type: "text",
|
|
1527
|
-
text: `[Image: ${item.mimeType}, ${item.data.length} bytes]`
|
|
1528
|
-
});
|
|
1529
|
-
}
|
|
1530
|
-
}
|
|
1531
|
-
return {
|
|
1532
|
-
content,
|
|
1533
|
-
isError: agentResult.isError || false
|
|
1534
|
-
};
|
|
1535
|
-
}
|
|
1536
|
-
return {
|
|
1537
|
-
content: [
|
|
1538
|
-
{
|
|
1539
|
-
type: "text",
|
|
1540
|
-
text: typeof result === "string" ? result : JSON.stringify(result, null, 2)
|
|
1541
|
-
}
|
|
1542
|
-
]
|
|
1543
|
-
};
|
|
1544
|
-
} catch (error) {
|
|
1545
|
-
console.error(`[MCP Server] Tool execution failed:`, error);
|
|
1546
|
-
return {
|
|
1547
|
-
content: [
|
|
1548
|
-
{
|
|
1549
|
-
type: "text",
|
|
1550
|
-
text: `Error: ${error instanceof Error ? error.message : String(error)}`
|
|
1551
|
-
}
|
|
1552
|
-
],
|
|
1553
|
-
isError: true
|
|
1554
|
-
};
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1557
|
-
sendResponse(id, result) {
|
|
1558
|
-
const response = {
|
|
1559
|
-
jsonrpc: "2.0",
|
|
1560
|
-
id,
|
|
1561
|
-
result
|
|
1562
|
-
};
|
|
1563
|
-
process.stdout.write(JSON.stringify(response) + "\n");
|
|
1564
|
-
}
|
|
1565
|
-
sendError(id, error) {
|
|
1566
|
-
const response = {
|
|
1567
|
-
jsonrpc: "2.0",
|
|
1568
|
-
id,
|
|
1569
|
-
error: {
|
|
1570
|
-
code: -32e3,
|
|
1571
|
-
message: error instanceof Error ? error.message : String(error)
|
|
1572
|
-
}
|
|
1573
|
-
};
|
|
1574
|
-
process.stdout.write(JSON.stringify(response) + "\n");
|
|
1575
|
-
}
|
|
1576
|
-
};
|
|
1577
|
-
function createMCPServer(options) {
|
|
1578
|
-
return new MCPServer(options);
|
|
1579
|
-
}
|
|
1580
|
-
|
|
1581
|
-
// src/facade/mcp-core/index.ts
|
|
1582
|
-
async function initializeMCP(registry, cwd = process.cwd()) {
|
|
1583
|
-
const configs = loadMCPConfig(cwd);
|
|
1584
|
-
if (configs.length === 0) {
|
|
1585
|
-
console.log("[MCP] No servers configured");
|
|
1586
|
-
return { pool: new MCPClientPool({ servers: [] }), toolCount: 0 };
|
|
1587
|
-
}
|
|
1588
|
-
const pool = new MCPClientPool({ servers: configs });
|
|
1589
|
-
await pool.connectAll();
|
|
1590
|
-
let totalTools = 0;
|
|
1591
|
-
for (const client of pool.getAllClients()) {
|
|
1592
|
-
try {
|
|
1593
|
-
const tools = await client.listTools();
|
|
1594
|
-
const count = await registerMCPToolsInRegistry(registry, client, tools);
|
|
1595
|
-
totalTools += count;
|
|
1596
|
-
console.log(`[MCP] Registered ${count} tools from ${client.serverName}`);
|
|
1597
|
-
} catch (error) {
|
|
1598
|
-
console.error(`[MCP] Failed to register tools from ${client.serverName}:`, error);
|
|
1599
|
-
}
|
|
1600
|
-
}
|
|
1601
|
-
return { pool, toolCount: totalTools };
|
|
1602
|
-
}
|
|
1603
|
-
export {
|
|
1604
|
-
EXAMPLE_CONFIG,
|
|
1605
|
-
MCPClient,
|
|
1606
|
-
MCPClientPool,
|
|
1607
|
-
MCPError,
|
|
1608
|
-
MCPErrorCode,
|
|
1609
|
-
MCPServer,
|
|
1610
|
-
applyPassthrough,
|
|
1611
|
-
convertMCPInputSchema,
|
|
1612
|
-
convertMCPOutputSchema,
|
|
1613
|
-
createConfigError,
|
|
1614
|
-
createConnectionError,
|
|
1615
|
-
createDefaultConfig,
|
|
1616
|
-
createInvalidParametersError,
|
|
1617
|
-
createMCPAgentToolFactory,
|
|
1618
|
-
createMCPServer,
|
|
1619
|
-
createMCPToolsMap,
|
|
1620
|
-
createMCPToolsRecord,
|
|
1621
|
-
createNotConnectedError,
|
|
1622
|
-
createSchemaConversionError,
|
|
1623
|
-
createServerError,
|
|
1624
|
-
createTimeoutError,
|
|
1625
|
-
createToolNotFoundError,
|
|
1626
|
-
ensureProjectConfigDir,
|
|
1627
|
-
ensureUserConfigDir,
|
|
1628
|
-
getProjectConfigPath,
|
|
1629
|
-
getUserConfigPath,
|
|
1630
|
-
initializeMCP,
|
|
1631
|
-
isMCPError,
|
|
1632
|
-
isSessionError,
|
|
1633
|
-
jsonSchemaToTypeBox,
|
|
1634
|
-
loadMCPConfig,
|
|
1635
|
-
registerMCPToolsInRegistry,
|
|
1636
|
-
saveConfig,
|
|
1637
|
-
saveProjectConfig,
|
|
1638
|
-
saveUserConfig
|
|
1639
|
-
};
|