feat: Komodo MCP server — 7 tools, full API coverage
- komodo_list, komodo_get, komodo_create, komodo_update, komodo_delete, komodo_execute, komodo_logs with resource_type routing - JWT auth with token caching and auto-refresh on 401 - HTTP/SSE transport on port 9800 - TypeScript, @modelcontextprotocol/sdk, zod schemas - README.md with setup instructions - references/api.md with full endpoint mapping
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
dist/
|
||||
node_modules/
|
||||
.DS_Store
|
||||
*.log
|
||||
@@ -0,0 +1,204 @@
|
||||
# Komodo MCP Server
|
||||
|
||||
MCP server for the [Komodo](https://komo.do) build/deploy platform. Exposes 7 tools that map to Komodo's full RPC API surface — list, get, create, update, delete, execute, and logs — via the Model Context Protocol.
|
||||
|
||||
## Setup
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node.js 22+
|
||||
- A running Komodo instance with API access
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Required | Default | Description |
|
||||
|----------|----------|---------|-------------|
|
||||
| `KOMODO_BASE_URL` | Yes | `http://10.10.2.114:9120` | Base URL of your Komodo instance |
|
||||
| `KOMODO_USERNAME` | Yes | — | Komodo login username |
|
||||
| `KOMODO_PASSWORD` | Yes | — | Komodo login password |
|
||||
| `PORT` | No | `9800` | Port for the HTTP/SSE transport |
|
||||
|
||||
`KOMODO_URL` is accepted as a legacy alias for `KOMODO_BASE_URL`.
|
||||
|
||||
### Install & Build
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Run
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
Or for development with live reload:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
The server starts on `http://0.0.0.0:9800/mcp` with a health check at `/health`.
|
||||
|
||||
### MCP Client Configuration
|
||||
|
||||
Add to your MCP client config (e.g. `mcp.json` or equivalent):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"komodo": {
|
||||
"url": "http://localhost:9800/mcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Tools
|
||||
|
||||
### `komodo_list`
|
||||
|
||||
List or search Komodo resources.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `resource_type` | enum | Yes | Resource type (see below) |
|
||||
| `search` | string | No | Search query — uses Search* endpoint instead of List* |
|
||||
| `project` | string | No | Filter by project name or ID |
|
||||
|
||||
Returns a JSON array of matching resources.
|
||||
|
||||
### `komodo_get`
|
||||
|
||||
Get a single resource by ID or name.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `resource_type` | enum | Yes | Resource type |
|
||||
| `id` | string | Yes | Resource ID or name |
|
||||
|
||||
### `komodo_create`
|
||||
|
||||
Create a new resource.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `resource_type` | enum | Yes | Resource type |
|
||||
| `params` | object | No | Fields for the corresponding Create* endpoint |
|
||||
|
||||
Available for: stack, build, server, procedure, deployment, alerter, image_registry_account, sync_resource, tag.
|
||||
|
||||
### `komodo_update`
|
||||
|
||||
Update an existing resource by ID.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `resource_type` | enum | Yes | Resource type |
|
||||
| `id` | string | Yes | Resource ID or name |
|
||||
| `params` | object | No | Fields to update |
|
||||
|
||||
### `komodo_delete`
|
||||
|
||||
Delete a resource by ID or name.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `resource_type` | enum | Yes | Resource type |
|
||||
| `id` | string | Yes | Resource ID or name |
|
||||
|
||||
Available for: stack, build, server, procedure, deployment, alerter, sync_resource, tag.
|
||||
|
||||
### `komodo_execute`
|
||||
|
||||
Execute a Komodo operation (build, deploy, procedure run, server actions, etc.).
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `operation` | enum | Yes | Operation to run (see below) |
|
||||
| `id` | string | No | Resource ID or name |
|
||||
| `params` | object | No | Additional operation parameters |
|
||||
|
||||
**Operations:**
|
||||
|
||||
| Operation | Description |
|
||||
|-----------|-------------|
|
||||
| `run_build` | Trigger a build |
|
||||
| `deploy_stack` | Deploy a stack |
|
||||
| `deploy_stack_service` | Deploy a single stack service |
|
||||
| `run_procedure` | Run a procedure |
|
||||
| `run_procedure_stage` | Run a specific procedure stage |
|
||||
| `run_deployment_action` | Run a deployment action |
|
||||
| `run_deployment_sync` | Sync a deployment |
|
||||
| `run_resource_sync` | Run a resource sync |
|
||||
| `run_stack_refresh_cache` | Refresh stack cache |
|
||||
| `run_stack_refresh_content` | Refresh stack content |
|
||||
| `run_stack_pull` | Pull stack (git pull) |
|
||||
| `run_stack_pull_deployment` | Pull and deploy stack |
|
||||
| `run_stack_stop` | Stop a stack |
|
||||
| `run_stack_restart` | Restart a stack |
|
||||
| `run_stack_pause` | Pause a stack |
|
||||
| `run_stack_unpause` | Unpause a stack |
|
||||
| `run_stack_remove_orphan_containers` | Remove orphan containers |
|
||||
| `run_stack_toggle_service_dependencies` | Toggle service dependencies |
|
||||
| `run_stack_auto_update` | Trigger auto-update |
|
||||
| `run_stack_commit` | Commit stack changes |
|
||||
| `run_server_refresh` | Refresh server state |
|
||||
| `run_server_refresh_containers` | Refresh server containers |
|
||||
| `run_server_update_periphery` | Update periphery |
|
||||
| `run_server_prune_images` | Prune server images |
|
||||
| `run_server_prune_containers` | Prune server containers |
|
||||
| `run_server_prune_networks` | Prune server networks |
|
||||
| `run_server_stats` | Get server stats |
|
||||
| `run_server_run_command` | Run a command on server |
|
||||
| `run_server_scripts` | Run server scripts |
|
||||
| `run_server_copy` | Copy between servers |
|
||||
| `run_server_move` | Move between servers |
|
||||
| `run_deployment_execute` | Execute a deployment |
|
||||
| `run_deployment_redeploy` | Redeploy a deployment |
|
||||
| `run_deployment_destroy` | Destroy a deployment |
|
||||
| `run_deployment_stop` | Stop a deployment |
|
||||
| `run_deployment_logs` | Get deployment logs via execute |
|
||||
| `run_sync_deployment` | Sync a deployment |
|
||||
| `get_mcp_token` | Get an MCP token |
|
||||
|
||||
### `komodo_logs`
|
||||
|
||||
Get logs for a deployment or stack.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `resource_type` | enum | Yes | `deployment` or `stack` |
|
||||
| `id` | string | Yes | Resource ID or name |
|
||||
| `tail` | number | No | Number of recent log lines |
|
||||
|
||||
## Resource Types
|
||||
|
||||
All tools that accept `resource_type` support these values:
|
||||
|
||||
| Value | Komodo Resource |
|
||||
|-------|----------------|
|
||||
| `stack` | Docker Compose stacks |
|
||||
| `build` | Build configurations |
|
||||
| `server` | Managed servers |
|
||||
| `procedure` | Automation procedures |
|
||||
| `deployment` | Deployments |
|
||||
| `alerter` | Alert configurations |
|
||||
| `image_registry_account` | Container registry accounts |
|
||||
| `sync_resource` | Sync resources |
|
||||
| `user` | Users |
|
||||
| `tag` | Tags |
|
||||
| `execution` | Execution history |
|
||||
| `access_request` | Access requests |
|
||||
|
||||
## Architecture
|
||||
|
||||
- **Transport:** HTTP/SSE via `StreamableHTTPServerTransport` (MCP protocol)
|
||||
- **Auth:** JWT login via `POST /auth/login`, token cached in memory, auto-refreshed on 401
|
||||
- **API:** Komodo RPC-style — all calls are `POST /{read|write|execute}/{RequestName}`
|
||||
- **No REST paths:** The server does not use REST-style paths (`/servers`, `/api/servers`) which serve SPA HTML
|
||||
|
||||
## License
|
||||
|
||||
Private — BuzzbeeSCD
|
||||
Generated
+1753
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,196 @@
|
||||
# Komodo API — Endpoint-to-Tool Mapping
|
||||
|
||||
Full reference of Komodo RPC endpoints and which MCP tool handles them.
|
||||
|
||||
## Auth
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
|----------|--------|-------------|
|
||||
| `POST /auth/login` | — | JWT login (handled internally by `komodo-client.ts`) |
|
||||
|
||||
---
|
||||
|
||||
## Read Endpoints → `komodo_list` / `komodo_get`
|
||||
|
||||
### List Endpoints → `komodo_list`
|
||||
|
||||
| Komodo RPC | MCP Tool | Resource Type |
|
||||
|------------|----------|---------------|
|
||||
| `read/ListStacks` | `komodo_list` | stack |
|
||||
| `read/ListBuilds` | `komodo_list` | build |
|
||||
| `read/ListServers` | `komodo_list` | server |
|
||||
| `read/ListProcedures` | `komodo_list` | procedure |
|
||||
| `read/ListDeployments` | `komodo_list` | deployment |
|
||||
| `read/ListAlerters` | `komodo_list` | alerter |
|
||||
| `read/ListImageRegistryAccounts` | `komodo_list` | image_registry_account |
|
||||
| `read/ListSyncResources` | `komodo_list` | sync_resource |
|
||||
| `read/ListUsers` | `komodo_list` | user |
|
||||
| `read/ListTags` | `komodo_list` | tag |
|
||||
| `read/ListExecutions` | `komodo_list` | execution |
|
||||
| `read/ListAccessRequests` | `komodo_list` | access_request |
|
||||
|
||||
### Search Endpoints → `komodo_list` (with `search` param)
|
||||
|
||||
| Komodo RPC | MCP Tool | Resource Type |
|
||||
|------------|----------|---------------|
|
||||
| `read/SearchStacks` | `komodo_list` | stack |
|
||||
| `read/SearchBuilds` | `komodo_list` | build |
|
||||
| `read/SearchServers` | `komodo_list` | server |
|
||||
| `read/SearchProcedures` | `komodo_list` | procedure |
|
||||
| `read/SearchDeployments` | `komodo_list` | deployment |
|
||||
| `read/SearchAlerters` | `komodo_list` | alerter |
|
||||
| `read/SearchImageRegistryAccounts` | `komodo_list` | image_registry_account |
|
||||
| `read/SearchSyncResources` | `komodo_list` | sync_resource |
|
||||
|
||||
### Get Endpoints → `komodo_get`
|
||||
|
||||
| Komodo RPC | MCP Tool | Resource Type |
|
||||
|------------|----------|---------------|
|
||||
| `read/GetStack` | `komodo_get` | stack |
|
||||
| `read/GetBuild` | `komodo_get` | build |
|
||||
| `read/GetServer` | `komodo_get` | server |
|
||||
| `read/GetProcedure` | `komodo_get` | procedure |
|
||||
| `read/GetDeployment` | `komodo_get` | deployment |
|
||||
| `read/GetAlerter` | `komodo_get` | alerter |
|
||||
| `read/GetImageRegistryAccount` | `komodo_get` | image_registry_account |
|
||||
| `read/GetSyncResource` | `komodo_get` | sync_resource |
|
||||
| `read/GetUser` | `komodo_get` | user |
|
||||
| `read/GetTag` | `komodo_get` | tag |
|
||||
| `read/GetAccessRequest` | `komodo_get` | access_request |
|
||||
|
||||
### Other Read Endpoints → `komodo_get` or `komodo_list`
|
||||
|
||||
| Komodo RPC | MCP Tool | Notes |
|
||||
|------------|----------|-------|
|
||||
| `read/GetStackServices` | `komodo_list` | List stack services |
|
||||
| `read/ListStackServices` | `komodo_list` | List stack services |
|
||||
| `read/GetDeploymentLogs` | `komodo_logs` | Use `komodo_logs` |
|
||||
| `read/GetBuildAggregatedStatus` | `komodo_get` | Use with build resource |
|
||||
| `read/GetGlobalStats` | `komodo_list` | Use `komodo_list` |
|
||||
| `read/GetResourceStats` | `komodo_list` | Use `komodo_list` |
|
||||
| `read/GetLicenseInfo` | `komodo_get` | Use `komodo_get` |
|
||||
| `read/ListTagMappings` | `komodo_list` | Use `komodo_list` |
|
||||
| `read/ListBinding` | `komodo_list` | Use `komodo_list` |
|
||||
| `read/GetBinding` | `komodo_get` | Use `komodo_get` |
|
||||
| `read/GetConcurrencyLimitUsage` | `komodo_get` | Use `komodo_get` |
|
||||
| `read/GetResourceSyncDifferences` | `komodo_get` | Use `komodo_get` |
|
||||
| `read/ListResources` | `komodo_list` | Use `komodo_list` |
|
||||
| `read/GetResource` | `komodo_get` | Use `komodo_get` |
|
||||
| `read/ListResourceSyncContents` | `komodo_list` | Use `komodo_list` |
|
||||
| `read/ListServerStats` | `komodo_list` | Use `komodo_list` |
|
||||
| `read/GetMcpToken` | `komodo_execute` | Use `komodo_execute` |
|
||||
|
||||
---
|
||||
|
||||
## Write Endpoints → `komodo_create` / `komodo_update` / `komodo_delete`
|
||||
|
||||
### Create Endpoints → `komodo_create`
|
||||
|
||||
| Komodo RPC | MCP Tool | Resource Type |
|
||||
|------------|----------|---------------|
|
||||
| `write/CreateStack` | `komodo_create` | stack |
|
||||
| `write/CreateBuild` | `komodo_create` | build |
|
||||
| `write/CreateServer` | `komodo_create` | server |
|
||||
| `write/CreateProcedure` | `komodo_create` | procedure |
|
||||
| `write/CreateDeployment` | `komodo_create` | deployment |
|
||||
| `write/CreateAlerter` | `komodo_create` | alerter |
|
||||
| `write/CreateImageRegistryAccount` | `komodo_create` | image_registry_account |
|
||||
| `write/CreateSyncResource` | `komodo_create` | sync_resource |
|
||||
| `write/AddTag` | `komodo_create` | tag |
|
||||
|
||||
### Update Endpoints → `komodo_update`
|
||||
|
||||
| Komodo RPC | MCP Tool | Resource Type |
|
||||
|------------|----------|---------------|
|
||||
| `write/UpdateStack` | `komodo_update` | stack |
|
||||
| `write/UpdateBuild` | `komodo_update` | build |
|
||||
| `write/UpdateServer` | `komodo_update` | server |
|
||||
| `write/UpdateProcedure` | `komodo_update` | procedure |
|
||||
| `write/UpdateDeployment` | `komodo_update` | deployment |
|
||||
| `write/UpdateAlerter` | `komodo_update` | alerter |
|
||||
| `write/UpdateImageRegistryAccount` | `komodo_update` | image_registry_account |
|
||||
| `write/UpdateSyncResource` | `komodo_update` | sync_resource |
|
||||
| `write/UpdateUser` | `komodo_update` | user |
|
||||
| `write/UpdateTag` | `komodo_update` | tag |
|
||||
|
||||
### Delete Endpoints → `komodo_delete`
|
||||
|
||||
| Komodo RPC | MCP Tool | Resource Type |
|
||||
|------------|----------|---------------|
|
||||
| `write/DeleteStack` | `komodo_delete` | stack |
|
||||
| `write/DeleteBuild` | `komodo_delete` | build |
|
||||
| `write/DeleteServer` | `komodo_delete` | server |
|
||||
| `write/DeleteProcedure` | `komodo_delete` | procedure |
|
||||
| `write/DeleteDeployment` | `komodo_delete` | deployment |
|
||||
| `write/DeleteAlerter` | `komodo_delete` | alerter |
|
||||
| `write/DeleteSyncResource` | `komodo_delete` | sync_resource |
|
||||
| `write/DeleteTag` | `komodo_delete` | tag |
|
||||
|
||||
### Other Write Endpoints → `komodo_update`
|
||||
|
||||
| Komodo RPC | MCP Tool | Notes |
|
||||
|------------|----------|-------|
|
||||
| `write/UpdateStackServiceNames` | `komodo_update` | Use with stack resource |
|
||||
| `write/UpdateServerTemplate` | `komodo_update` | Use with server resource |
|
||||
| `write/UpdateServerTemplateInstances` | `komodo_update` | Use with server resource |
|
||||
| `write/BindStack` | `komodo_update` | Use with stack resource |
|
||||
| `write/BindServer` | `komodo_update` | Use with server resource |
|
||||
| `write/UpdateBinding` | `komodo_update` | Use `komodo_update` |
|
||||
| `write/UpdateAllBindings` | `komodo_update` | Use `komodo_update` |
|
||||
| `write/MarkResourceSyncDeployed` | `komodo_update` | Use with sync_resource |
|
||||
| `write/UpdateUserPermissions` | `komodo_update` | Use with user resource |
|
||||
| `write/UpdateConcurrencyLimit` | `komodo_update` | Use `komodo_update` |
|
||||
| `write/AcknowledgeAccessRequest` | `komodo_update` | Use with access_request |
|
||||
| `write/CreateTagMapping` | `komodo_create` | Use `komodo_create` |
|
||||
| `write/DeleteTagMapping` | `komodo_delete` | Use `komodo_delete` |
|
||||
| `write/UpdateTagMapping` | `komodo_update` | Use `komodo_update` |
|
||||
| `write/UpdateProcedureSchedule` | `komodo_update` | Use with procedure resource |
|
||||
| `write/CreateCustomPermission` | `komodo_create` | Use `komodo_create` |
|
||||
| `write/UpdateCustomPermission` | `komodo_update` | Use `komodo_update` |
|
||||
| `write/DeleteCustomPermission` | `komodo_delete` | Use `komodo_delete` |
|
||||
| `write/UpdateCustomPermissionTagBindings` | `komodo_update` | Use `komodo_update` |
|
||||
|
||||
---
|
||||
|
||||
## Execute Endpoints → `komodo_execute`
|
||||
|
||||
| Komodo RPC | MCP `operation` | Notes |
|
||||
|------------|-----------------|-------|
|
||||
| `execute/RunBuild` | `run_build` | |
|
||||
| `execute/DeployStack` | `deploy_stack` | |
|
||||
| `execute/DeployStackService` | `deploy_stack_service` | |
|
||||
| `execute/RunProcedure` | `run_procedure` | |
|
||||
| `execute/RunProcedureStage` | `run_procedure_stage` | |
|
||||
| `execute/RunDeploymentAction` | `run_deployment_action` | |
|
||||
| `execute/RunDeploymentSync` | `run_deployment_sync` | |
|
||||
| `execute/RunResourceSync` | `run_resource_sync` | |
|
||||
| `execute/RunStackRefreshCache` | `run_stack_refresh_cache` | |
|
||||
| `execute/RunStackRefreshContent` | `run_stack_refresh_content` | |
|
||||
| `execute/RunStackPull` | `run_stack_pull` | |
|
||||
| `execute/RunStackPullDeployment` | `run_stack_pull_deployment` | |
|
||||
| `execute/RunStackStop` | `run_stack_stop` | |
|
||||
| `execute/RunStackRestart` | `run_stack_restart` | |
|
||||
| `execute/RunStackPause` | `run_stack_pause` | |
|
||||
| `execute/RunStackUnpause` | `run_stack_unpause` | |
|
||||
| `execute/RunStackRemoveOrphanContainers` | `run_stack_remove_orphan_containers` | |
|
||||
| `execute/RunStackToggleServiceDependencies` | `run_stack_toggle_service_dependencies` | |
|
||||
| `execute/RunStackAutoUpdate` | `run_stack_auto_update` | |
|
||||
| `execute/RunStackCommit` | `run_stack_commit` | |
|
||||
| `execute/RunServerRefresh` | `run_server_refresh` | |
|
||||
| `execute/RunServerRefreshContainers` | `run_server_refresh_containers` | |
|
||||
| `execute/RunServerUpdatePeriphery` | `run_server_update_periphery` | |
|
||||
| `execute/RunServerPruneImages` | `run_server_prune_images` | |
|
||||
| `execute/RunServerPruneContainers` | `run_server_prune_containers` | |
|
||||
| `execute/RunServerPruneNetworks` | `run_server_prune_networks` | |
|
||||
| `execute/RunServerStats` | `run_server_stats` | |
|
||||
| `execute/RunServerRunCommand` | `run_server_run_command` | |
|
||||
| `execute/RunServerScripts` | `run_server_scripts` | |
|
||||
| `execute/RunServerCopy` | `run_server_copy` | |
|
||||
| `execute/RunServerMove` | `run_server_move` | |
|
||||
| `execute/RunDeploymentExecute` | `run_deployment_execute` | |
|
||||
| `execute/RunDeploymentRedeploy` | `run_deployment_redeploy` | |
|
||||
| `execute/RunDeploymentDestroy` | `run_deployment_destroy` | |
|
||||
| `execute/RunDeploymentStop` | `run_deployment_stop` | |
|
||||
| `execute/RunDeploymentLogs` | `run_deployment_logs` | Prefer `komodo_logs` |
|
||||
| `execute/RunSyncDeployment` | `run_sync_deployment` | |
|
||||
| `execute/GetMcpToken` | `get_mcp_token` | |
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { createServer, type IncomingMessage, type ServerResponse } from "node:http";
|
||||
import { KomodoClient } from "./komodo-client.js";
|
||||
import { listInputSchema, handleList } from "./tools/list.js";
|
||||
import { getInputSchema, handleGet } from "./tools/get.js";
|
||||
import { createInputSchema, handleCreate } from "./tools/create.js";
|
||||
import { updateInputSchema, handleUpdate } from "./tools/update.js";
|
||||
import { deleteInputSchema, handleDelete } from "./tools/delete.js";
|
||||
import { executeInputSchema, handleExecute } from "./tools/execute.js";
|
||||
import { logsInputSchema, handleLogs } from "./tools/logs.js";
|
||||
|
||||
const PORT = parseInt(process.env.PORT || "9800", 10);
|
||||
const client = new KomodoClient();
|
||||
const transports: Record<string, StreamableHTTPServerTransport> = {};
|
||||
|
||||
function createServerInstance(): McpServer {
|
||||
const server = new McpServer({
|
||||
name: "komodo-mcp-server",
|
||||
version: "1.0.0",
|
||||
});
|
||||
|
||||
server.registerTool("komodo_list", {
|
||||
description:
|
||||
"List or search Komodo resources (stacks, builds, servers, procedures, deployments, alerters, image_registry_accounts, sync_resources, users, tags, executions, access_requests). Returns a JSON array of matching resources.",
|
||||
inputSchema: listInputSchema,
|
||||
}, async (args) => handleList(args, client));
|
||||
|
||||
server.registerTool("komodo_get", {
|
||||
description:
|
||||
"Get a single Komodo resource by ID or name. Returns the full resource object as JSON.",
|
||||
inputSchema: getInputSchema,
|
||||
}, async (args) => handleGet(args, client));
|
||||
|
||||
server.registerTool("komodo_create", {
|
||||
description:
|
||||
"Create a new Komodo resource. Provide the resource_type and a params object with the fields required by the corresponding Komodo Create* endpoint.",
|
||||
inputSchema: createInputSchema,
|
||||
}, async (args) => handleCreate(args, client));
|
||||
|
||||
server.registerTool("komodo_update", {
|
||||
description:
|
||||
"Update an existing Komodo resource by ID. Provide the resource_type, id, and params with the fields to update.",
|
||||
inputSchema: updateInputSchema,
|
||||
}, async (args) => handleUpdate(args, client));
|
||||
|
||||
server.registerTool("komodo_delete", {
|
||||
description:
|
||||
"Delete a Komodo resource by ID or name.",
|
||||
inputSchema: deleteInputSchema,
|
||||
}, async (args) => handleDelete(args, client));
|
||||
|
||||
server.registerTool("komodo_execute", {
|
||||
description:
|
||||
"Execute a Komodo operation (build, deploy, procedure run, server refresh, stack lifecycle actions, etc.). Provide the operation name, an optional resource id, and optional params.",
|
||||
inputSchema: executeInputSchema,
|
||||
}, async (args) => handleExecute(args, client));
|
||||
|
||||
server.registerTool("komodo_logs", {
|
||||
description:
|
||||
"Get logs for a Komodo deployment or stack. Returns log lines as text.",
|
||||
inputSchema: logsInputSchema,
|
||||
}, async (args) => handleLogs(args, client));
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
function parseBody(req: IncomingMessage): Promise<unknown> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const chunks: Buffer[] = [];
|
||||
req.on("data", (chunk) => chunks.push(chunk));
|
||||
req.on("end", () => {
|
||||
const body = Buffer.concat(chunks).toString("utf-8");
|
||||
try {
|
||||
resolve(body ? JSON.parse(body) : null);
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
req.on("error", reject);
|
||||
});
|
||||
}
|
||||
|
||||
const httpServer = createServer(async (req, res) => {
|
||||
// CORS headers
|
||||
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||
res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
|
||||
res.setHeader(
|
||||
"Access-Control-Allow-Headers",
|
||||
"Content-Type, Authorization, mcp-session-id",
|
||||
);
|
||||
|
||||
if (req.method === "OPTIONS") {
|
||||
res.writeHead(204);
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
// Health check
|
||||
if (req.method === "GET" && req.url === "/health") {
|
||||
res.writeHead(200, { "Content-Type": "application/json" });
|
||||
res.end(JSON.stringify({ status: "ok", name: "komodo-mcp-server" }));
|
||||
return;
|
||||
}
|
||||
|
||||
// MCP endpoint
|
||||
if (req.url === "/mcp" || req.url?.startsWith("/mcp?")) {
|
||||
const sessionId = req.headers["mcp-session-id"] as string | undefined;
|
||||
|
||||
if (req.method === "POST") {
|
||||
const body = await parseBody(req);
|
||||
|
||||
// Check if this is an initialize request (no existing session)
|
||||
const isInitialize =
|
||||
!sessionId ||
|
||||
!transports[sessionId] ||
|
||||
(body && typeof body === "object" && "method" in body && body.method === "initialize");
|
||||
|
||||
if (isInitialize && (!sessionId || !transports[sessionId])) {
|
||||
const transport = new StreamableHTTPServerTransport({
|
||||
sessionIdGenerator: () => randomUUID(),
|
||||
onsessioninitialized: (sid) => {
|
||||
transports[sid] = transport;
|
||||
},
|
||||
});
|
||||
|
||||
transport.onclose = () => {
|
||||
const sid = transport.sessionId;
|
||||
if (sid) delete transports[sid];
|
||||
};
|
||||
|
||||
const server = createServerInstance();
|
||||
await server.connect(transport);
|
||||
await transport.handleRequest(req, res, body);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sessionId && transports[sessionId]) {
|
||||
const transport = transports[sessionId];
|
||||
await transport.handleRequest(req, res, body);
|
||||
return;
|
||||
}
|
||||
|
||||
res.writeHead(400, { "Content-Type": "application/json" });
|
||||
res.end(
|
||||
JSON.stringify({
|
||||
jsonrpc: "2.0",
|
||||
error: { code: -32000, message: "Bad Request: No valid session" },
|
||||
id: null,
|
||||
}),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.method === "GET" && sessionId && transports[sessionId]) {
|
||||
await transports[sessionId].handleRequest(req, res);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.method === "DELETE" && sessionId && transports[sessionId]) {
|
||||
await transports[sessionId].handleRequest(req, res);
|
||||
return;
|
||||
}
|
||||
|
||||
res.writeHead(405, { "Content-Type": "application/json" });
|
||||
res.end(
|
||||
JSON.stringify({
|
||||
jsonrpc: "2.0",
|
||||
error: { code: -32000, message: "Method not allowed" },
|
||||
id: null,
|
||||
}),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
res.writeHead(404, { "Content-Type": "application/json" });
|
||||
res.end(JSON.stringify({ error: "Not found" }));
|
||||
});
|
||||
|
||||
httpServer.listen(PORT, "0.0.0.0", () => {
|
||||
console.log(`Komodo MCP Server listening on http://0.0.0.0:${PORT}/mcp`);
|
||||
console.log(`Health check: http://0.0.0.0:${PORT}/health`);
|
||||
console.log(`Komodo URL: ${process.env.KOMODO_BASE_URL || process.env.KOMODO_URL || "http://10.10.2.114:9120"}`);
|
||||
});
|
||||
|
||||
process.on("SIGINT", async () => {
|
||||
console.log("\nShutting down...");
|
||||
for (const sid of Object.keys(transports)) {
|
||||
try {
|
||||
await transports[sid].close();
|
||||
delete transports[sid];
|
||||
} catch {}
|
||||
}
|
||||
httpServer.close();
|
||||
process.exit(0);
|
||||
});
|
||||
@@ -0,0 +1,79 @@
|
||||
export class KomodoClient {
|
||||
private baseUrl: string;
|
||||
private username: string;
|
||||
private password: string;
|
||||
private token: string | null = null;
|
||||
|
||||
constructor() {
|
||||
this.baseUrl = process.env.KOMODO_BASE_URL || process.env.KOMODO_URL || "http://10.10.2.114:9120";
|
||||
this.username = process.env.KOMODO_USERNAME || "";
|
||||
this.password = process.env.KOMODO_PASSWORD || "";
|
||||
}
|
||||
|
||||
private async ensureAuth(): Promise<void> {
|
||||
if (this.token) return;
|
||||
await this.login();
|
||||
}
|
||||
|
||||
private async login(): Promise<void> {
|
||||
const res = await fetch(`${this.baseUrl}/auth/login`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
username: this.username,
|
||||
password: this.password,
|
||||
}),
|
||||
});
|
||||
if (!res.ok) {
|
||||
const text = await res.text().catch(() => "");
|
||||
throw new Error(`Komodo login failed (${res.status}): ${text}`);
|
||||
}
|
||||
this.token = await res.text();
|
||||
}
|
||||
|
||||
async rpc(
|
||||
route: "read" | "write" | "execute",
|
||||
requestName: string,
|
||||
params: Record<string, unknown> = {},
|
||||
): Promise<unknown> {
|
||||
await this.ensureAuth();
|
||||
|
||||
const url = `${this.baseUrl}/${route}/${requestName}`;
|
||||
|
||||
const attempt = async (token: string): Promise<Response> => {
|
||||
return fetch(url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
body: JSON.stringify(params),
|
||||
});
|
||||
};
|
||||
|
||||
let res = await attempt(this.token!);
|
||||
|
||||
// Auto-refresh on 401
|
||||
if (res.status === 401) {
|
||||
this.token = null;
|
||||
await this.login();
|
||||
res = await attempt(this.token!);
|
||||
}
|
||||
|
||||
if (!res.ok) {
|
||||
const text = await res.text().catch(() => "");
|
||||
throw new Error(
|
||||
`Komodo RPC ${route}/${requestName} failed (${res.status}): ${text}`,
|
||||
);
|
||||
}
|
||||
|
||||
const text = await res.text();
|
||||
if (!text) return null;
|
||||
|
||||
try {
|
||||
return JSON.parse(text);
|
||||
} catch {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import { z } from "zod";
|
||||
import { KomodoClient } from "../komodo-client.js";
|
||||
import { ResourceType, CREATE_REQUEST_MAP } from "../types.js";
|
||||
|
||||
export const createInputSchema = {
|
||||
resource_type: ResourceType.describe(
|
||||
"Resource type to create (stack, build, server, procedure, deployment, alerter, image_registry_account, sync_resource, tag)",
|
||||
),
|
||||
params: z
|
||||
.record(z.string(), z.unknown())
|
||||
.optional()
|
||||
.describe(
|
||||
"Resource-specific parameters passed directly to the Komodo Create* endpoint",
|
||||
),
|
||||
};
|
||||
|
||||
export async function handleCreate(
|
||||
args: {
|
||||
resource_type: z.infer<typeof ResourceType>;
|
||||
params?: Record<string, unknown>;
|
||||
},
|
||||
client: KomodoClient,
|
||||
): Promise<{ content: { type: "text"; text: string }[] }> {
|
||||
const { resource_type, params } = args;
|
||||
|
||||
const requestName = CREATE_REQUEST_MAP[resource_type];
|
||||
if (!requestName) {
|
||||
throw new Error(
|
||||
`No CREATE endpoint available for resource type: ${resource_type}`,
|
||||
);
|
||||
}
|
||||
|
||||
const result = await client.rpc("write", requestName, params ?? {});
|
||||
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify(result, null, 2),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { z } from "zod";
|
||||
import { KomodoClient } from "../komodo-client.js";
|
||||
import { ResourceType, DELETE_REQUEST_MAP } from "../types.js";
|
||||
|
||||
export const deleteInputSchema = {
|
||||
resource_type: ResourceType.describe(
|
||||
"Resource type to delete (stack, build, server, procedure, deployment, alerter, sync_resource, tag)",
|
||||
),
|
||||
id: z.string().describe("Resource ID or name to delete"),
|
||||
};
|
||||
|
||||
export async function handleDelete(
|
||||
args: { resource_type: z.infer<typeof ResourceType>; id: string },
|
||||
client: KomodoClient,
|
||||
): Promise<{ content: { type: "text"; text: string }[] }> {
|
||||
const { resource_type, id } = args;
|
||||
|
||||
const requestName = DELETE_REQUEST_MAP[resource_type];
|
||||
if (!requestName) {
|
||||
throw new Error(
|
||||
`No DELETE endpoint available for resource type: ${resource_type}`,
|
||||
);
|
||||
}
|
||||
|
||||
const result = await client.rpc("write", requestName, { id });
|
||||
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify(result, null, 2),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import { z } from "zod";
|
||||
import { KomodoClient } from "../komodo-client.js";
|
||||
import { ExecuteOperation, EXECUTE_REQUEST_MAP } from "../types.js";
|
||||
|
||||
export const executeInputSchema = {
|
||||
operation: ExecuteOperation.describe(
|
||||
"Execute operation (run_build, deploy_stack, deploy_stack_service, run_procedure, run_procedure_stage, run_deployment_action, run_deployment_sync, run_resource_sync, run_stack_refresh_cache, run_stack_refresh_content, run_stack_pull, run_stack_pull_deployment, run_stack_stop, run_stack_restart, run_stack_pause, run_stack_unpause, run_stack_remove_orphan_containers, run_stack_toggle_service_dependencies, run_stack_auto_update, run_stack_commit, run_server_refresh, run_server_refresh_containers, run_server_update_periphery, run_server_prune_images, run_server_prune_containers, run_server_prune_networks, run_server_stats, run_server_run_command, run_server_scripts, run_server_copy, run_server_move, run_deployment_execute, run_deployment_redeploy, run_deployment_destroy, run_deployment_stop, run_deployment_logs, run_sync_deployment, get_mcp_token)",
|
||||
),
|
||||
id: z.string().optional().describe("Resource ID or name for the operation"),
|
||||
params: z
|
||||
.record(z.string(), z.unknown())
|
||||
.optional()
|
||||
.describe("Additional parameters for the operation"),
|
||||
};
|
||||
|
||||
export async function handleExecute(
|
||||
args: {
|
||||
operation: z.infer<typeof ExecuteOperation>;
|
||||
id?: string;
|
||||
params?: Record<string, unknown>;
|
||||
},
|
||||
client: KomodoClient,
|
||||
): Promise<{ content: { type: "text"; text: string }[] }> {
|
||||
const { operation, id, params } = args;
|
||||
|
||||
const mapping = EXECUTE_REQUEST_MAP[operation];
|
||||
if (!mapping) {
|
||||
throw new Error(`Unknown execute operation: ${operation}`);
|
||||
}
|
||||
|
||||
const requestParams: Record<string, unknown> = { ...params };
|
||||
if (id) requestParams.id = id;
|
||||
|
||||
const result = await client.rpc(mapping.route, mapping.name, requestParams);
|
||||
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify(result, null, 2),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { z } from "zod";
|
||||
import { KomodoClient } from "../komodo-client.js";
|
||||
import { ResourceType, GET_REQUEST_MAP } from "../types.js";
|
||||
|
||||
export const getInputSchema = {
|
||||
resource_type: ResourceType.describe(
|
||||
"Resource type to get (stack, build, server, procedure, deployment, alerter, image_registry_account, sync_resource, user, tag, execution, access_request)",
|
||||
),
|
||||
id: z.string().describe("Resource ID or name"),
|
||||
};
|
||||
|
||||
export async function handleGet(
|
||||
args: { resource_type: z.infer<typeof ResourceType>; id: string },
|
||||
client: KomodoClient,
|
||||
): Promise<{ content: { type: "text"; text: string }[] }> {
|
||||
const { resource_type, id } = args;
|
||||
|
||||
const requestName = GET_REQUEST_MAP[resource_type];
|
||||
if (!requestName) {
|
||||
throw new Error(
|
||||
`No GET endpoint available for resource type: ${resource_type}`,
|
||||
);
|
||||
}
|
||||
|
||||
const result = await client.rpc("read", requestName, { id });
|
||||
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify(result, null, 2),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import { z } from "zod";
|
||||
import { KomodoClient } from "../komodo-client.js";
|
||||
import {
|
||||
ResourceType,
|
||||
LIST_REQUEST_MAP,
|
||||
SEARCH_REQUEST_MAP,
|
||||
} from "../types.js";
|
||||
|
||||
export const listInputSchema = {
|
||||
resource_type: ResourceType.describe(
|
||||
"Resource type to list (stack, build, server, procedure, deployment, alerter, image_registry_account, sync_resource, user, tag, execution, access_request)",
|
||||
),
|
||||
search: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe("Optional search/filter query — uses the Search* endpoint instead of List*"),
|
||||
project: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe("Filter by project name or ID"),
|
||||
};
|
||||
|
||||
export async function handleList(
|
||||
args: { resource_type: z.infer<typeof ResourceType>; search?: string; project?: string },
|
||||
client: KomodoClient,
|
||||
): Promise<{ content: { type: "text"; text: string }[] }> {
|
||||
const { resource_type, search, project } = args;
|
||||
|
||||
const params: Record<string, unknown> = {};
|
||||
if (search) params.filter = search;
|
||||
if (project) params.project = project;
|
||||
|
||||
let route: "read" | "write" | "execute" = "read";
|
||||
let requestName: string;
|
||||
|
||||
if (search && SEARCH_REQUEST_MAP[resource_type]) {
|
||||
requestName = SEARCH_REQUEST_MAP[resource_type];
|
||||
} else {
|
||||
requestName = LIST_REQUEST_MAP[resource_type];
|
||||
}
|
||||
|
||||
const result = await client.rpc(route, requestName, params);
|
||||
|
||||
// Komodo list endpoints return bare arrays
|
||||
const items = Array.isArray(result) ? result : [result];
|
||||
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify(items, null, 2),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { z } from "zod";
|
||||
import { KomodoClient } from "../komodo-client.js";
|
||||
|
||||
export const logsInputSchema = {
|
||||
resource_type: z
|
||||
.enum(["deployment", "stack"])
|
||||
.describe("Resource type to get logs for"),
|
||||
id: z.string().describe("Resource ID or name"),
|
||||
tail: z
|
||||
.number()
|
||||
.optional()
|
||||
.describe("Number of recent log lines to return"),
|
||||
};
|
||||
|
||||
export async function handleLogs(
|
||||
args: {
|
||||
resource_type: "deployment" | "stack";
|
||||
id: string;
|
||||
tail?: number;
|
||||
},
|
||||
client: KomodoClient,
|
||||
): Promise<{ content: { type: "text"; text: string }[] }> {
|
||||
const { resource_type, id, tail } = args;
|
||||
|
||||
const params: Record<string, unknown> = { id };
|
||||
if (tail !== undefined) params.tail = tail;
|
||||
|
||||
let result: unknown;
|
||||
|
||||
if (resource_type === "deployment") {
|
||||
result = await client.rpc("read", "GetDeploymentLogs", params);
|
||||
} else {
|
||||
// stack — GetStack returns full stack state including logs
|
||||
result = await client.rpc("read", "GetStack", { id });
|
||||
}
|
||||
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text:
|
||||
typeof result === "string"
|
||||
? result
|
||||
: JSON.stringify(result, null, 2),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { z } from "zod";
|
||||
import { KomodoClient } from "../komodo-client.js";
|
||||
import { ResourceType, UPDATE_REQUEST_MAP } from "../types.js";
|
||||
|
||||
export const updateInputSchema = {
|
||||
resource_type: ResourceType.describe(
|
||||
"Resource type to update (stack, build, server, procedure, deployment, alerter, image_registry_account, sync_resource, user, tag)",
|
||||
),
|
||||
id: z.string().describe("Resource ID or name to update"),
|
||||
params: z
|
||||
.record(z.string(), z.unknown())
|
||||
.optional()
|
||||
.describe(
|
||||
"Update fields passed directly to the Komodo Update* endpoint",
|
||||
),
|
||||
};
|
||||
|
||||
export async function handleUpdate(
|
||||
args: {
|
||||
resource_type: z.infer<typeof ResourceType>;
|
||||
id: string;
|
||||
params?: Record<string, unknown>;
|
||||
},
|
||||
client: KomodoClient,
|
||||
): Promise<{ content: { type: "text"; text: string }[] }> {
|
||||
const { resource_type, id, params } = args;
|
||||
|
||||
const requestName = UPDATE_REQUEST_MAP[resource_type];
|
||||
if (!requestName) {
|
||||
throw new Error(
|
||||
`No UPDATE endpoint available for resource type: ${resource_type}`,
|
||||
);
|
||||
}
|
||||
|
||||
const result = await client.rpc("write", requestName, { id, ...params });
|
||||
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify(result, null, 2),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
+233
@@ -0,0 +1,233 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const ResourceType = z.enum([
|
||||
"stack",
|
||||
"build",
|
||||
"server",
|
||||
"procedure",
|
||||
"deployment",
|
||||
"alerter",
|
||||
"image_registry_account",
|
||||
"sync_resource",
|
||||
"user",
|
||||
"tag",
|
||||
"execution",
|
||||
"access_request",
|
||||
]);
|
||||
export type ResourceType = z.infer<typeof ResourceType>;
|
||||
|
||||
export const ExecuteOperation = z.enum([
|
||||
"run_build",
|
||||
"deploy_stack",
|
||||
"deploy_stack_service",
|
||||
"run_procedure",
|
||||
"run_procedure_stage",
|
||||
"run_deployment_action",
|
||||
"run_deployment_sync",
|
||||
"run_resource_sync",
|
||||
"run_stack_refresh_cache",
|
||||
"run_stack_refresh_content",
|
||||
"run_stack_pull",
|
||||
"run_stack_pull_deployment",
|
||||
"run_stack_stop",
|
||||
"run_stack_restart",
|
||||
"run_stack_pause",
|
||||
"run_stack_unpause",
|
||||
"run_stack_remove_orphan_containers",
|
||||
"run_stack_toggle_service_dependencies",
|
||||
"run_stack_auto_update",
|
||||
"run_stack_commit",
|
||||
"run_server_refresh",
|
||||
"run_server_refresh_containers",
|
||||
"run_server_update_periphery",
|
||||
"run_server_prune_images",
|
||||
"run_server_prune_containers",
|
||||
"run_server_prune_networks",
|
||||
"run_server_stats",
|
||||
"run_server_run_command",
|
||||
"run_server_scripts",
|
||||
"run_server_copy",
|
||||
"run_server_move",
|
||||
"run_deployment_execute",
|
||||
"run_deployment_redeploy",
|
||||
"run_deployment_destroy",
|
||||
"run_deployment_stop",
|
||||
"run_deployment_logs",
|
||||
"run_sync_deployment",
|
||||
"get_mcp_token",
|
||||
]);
|
||||
export type ExecuteOperation = z.infer<typeof ExecuteOperation>;
|
||||
|
||||
// Maps resource_type to the list/search RPC request name
|
||||
export const LIST_REQUEST_MAP: Record<ResourceType, string> = {
|
||||
stack: "ListStacks",
|
||||
build: "ListBuilds",
|
||||
server: "ListServers",
|
||||
procedure: "ListProcedures",
|
||||
deployment: "ListDeployments",
|
||||
alerter: "ListAlerters",
|
||||
image_registry_account: "ListImageRegistryAccounts",
|
||||
sync_resource: "ListSyncResources",
|
||||
user: "ListUsers",
|
||||
tag: "ListTags",
|
||||
execution: "ListExecutions",
|
||||
access_request: "ListAccessRequests",
|
||||
};
|
||||
|
||||
// Maps resource_type to the search RPC request name
|
||||
export const SEARCH_REQUEST_MAP: Record<ResourceType, string> = {
|
||||
stack: "SearchStacks",
|
||||
build: "SearchBuilds",
|
||||
server: "SearchServers",
|
||||
procedure: "SearchProcedures",
|
||||
deployment: "SearchDeployments",
|
||||
alerter: "SearchAlerters",
|
||||
image_registry_account: "SearchImageRegistryAccounts",
|
||||
sync_resource: "SearchSyncResources",
|
||||
user: "ListUsers",
|
||||
tag: "ListTags",
|
||||
execution: "ListExecutions",
|
||||
access_request: "ListAccessRequests",
|
||||
};
|
||||
|
||||
// Maps resource_type to the get RPC request name
|
||||
export const GET_REQUEST_MAP: Record<ResourceType, string> = {
|
||||
stack: "GetStack",
|
||||
build: "GetBuild",
|
||||
server: "GetServer",
|
||||
procedure: "GetProcedure",
|
||||
deployment: "GetDeployment",
|
||||
alerter: "GetAlerter",
|
||||
image_registry_account: "GetImageRegistryAccount",
|
||||
sync_resource: "GetSyncResource",
|
||||
user: "GetUser",
|
||||
tag: "GetTag",
|
||||
execution: "GetExecution",
|
||||
access_request: "GetAccessRequest",
|
||||
};
|
||||
|
||||
// Maps resource_type to the create RPC request name
|
||||
export const CREATE_REQUEST_MAP: Partial<Record<ResourceType, string>> = {
|
||||
stack: "CreateStack",
|
||||
build: "CreateBuild",
|
||||
server: "CreateServer",
|
||||
procedure: "CreateProcedure",
|
||||
deployment: "CreateDeployment",
|
||||
alerter: "CreateAlerter",
|
||||
image_registry_account: "CreateImageRegistryAccount",
|
||||
sync_resource: "CreateSyncResource",
|
||||
tag: "AddTag",
|
||||
};
|
||||
|
||||
// Maps resource_type to the update RPC request name
|
||||
export const UPDATE_REQUEST_MAP: Partial<Record<ResourceType, string>> = {
|
||||
stack: "UpdateStack",
|
||||
build: "UpdateBuild",
|
||||
server: "UpdateServer",
|
||||
procedure: "UpdateProcedure",
|
||||
deployment: "UpdateDeployment",
|
||||
alerter: "UpdateAlerter",
|
||||
image_registry_account: "UpdateImageRegistryAccount",
|
||||
sync_resource: "UpdateSyncResource",
|
||||
user: "UpdateUser",
|
||||
tag: "UpdateTag",
|
||||
};
|
||||
|
||||
// Maps resource_type to the delete RPC request name
|
||||
export const DELETE_REQUEST_MAP: Partial<Record<ResourceType, string>> = {
|
||||
stack: "DeleteStack",
|
||||
build: "DeleteBuild",
|
||||
server: "DeleteServer",
|
||||
procedure: "DeleteProcedure",
|
||||
deployment: "DeleteDeployment",
|
||||
alerter: "DeleteAlerter",
|
||||
sync_resource: "DeleteSyncResource",
|
||||
tag: "DeleteTag",
|
||||
};
|
||||
|
||||
// Maps execute operation to the RPC request name and the route
|
||||
export const EXECUTE_REQUEST_MAP: Record<
|
||||
ExecuteOperation,
|
||||
{ route: "execute" | "read" | "write"; name: string }
|
||||
> = {
|
||||
run_build: { route: "execute", name: "RunBuild" },
|
||||
deploy_stack: { route: "execute", name: "DeployStack" },
|
||||
deploy_stack_service: { route: "execute", name: "DeployStackService" },
|
||||
run_procedure: { route: "execute", name: "RunProcedure" },
|
||||
run_procedure_stage: { route: "execute", name: "RunProcedureStage" },
|
||||
run_deployment_action: { route: "execute", name: "RunDeploymentAction" },
|
||||
run_deployment_sync: { route: "execute", name: "RunDeploymentSync" },
|
||||
run_resource_sync: { route: "execute", name: "RunResourceSync" },
|
||||
run_stack_refresh_cache: {
|
||||
route: "execute",
|
||||
name: "RunStackRefreshCache",
|
||||
},
|
||||
run_stack_refresh_content: {
|
||||
route: "execute",
|
||||
name: "RunStackRefreshContent",
|
||||
},
|
||||
run_stack_pull: { route: "execute", name: "RunStackPull" },
|
||||
run_stack_pull_deployment: {
|
||||
route: "execute",
|
||||
name: "RunStackPullDeployment",
|
||||
},
|
||||
run_stack_stop: { route: "execute", name: "RunStackStop" },
|
||||
run_stack_restart: { route: "execute", name: "RunStackRestart" },
|
||||
run_stack_pause: { route: "execute", name: "RunStackPause" },
|
||||
run_stack_unpause: { route: "execute", name: "RunStackUnpause" },
|
||||
run_stack_remove_orphan_containers: {
|
||||
route: "execute",
|
||||
name: "RunStackRemoveOrphanContainers",
|
||||
},
|
||||
run_stack_toggle_service_dependencies: {
|
||||
route: "execute",
|
||||
name: "RunStackToggleServiceDependencies",
|
||||
},
|
||||
run_stack_auto_update: { route: "execute", name: "RunStackAutoUpdate" },
|
||||
run_stack_commit: { route: "execute", name: "RunStackCommit" },
|
||||
run_server_refresh: { route: "execute", name: "RunServerRefresh" },
|
||||
run_server_refresh_containers: {
|
||||
route: "execute",
|
||||
name: "RunServerRefreshContainers",
|
||||
},
|
||||
run_server_update_periphery: {
|
||||
route: "execute",
|
||||
name: "RunServerUpdatePeriphery",
|
||||
},
|
||||
run_server_prune_images: {
|
||||
route: "execute",
|
||||
name: "RunServerPruneImages",
|
||||
},
|
||||
run_server_prune_containers: {
|
||||
route: "execute",
|
||||
name: "RunServerPruneContainers",
|
||||
},
|
||||
run_server_prune_networks: {
|
||||
route: "execute",
|
||||
name: "RunServerPruneNetworks",
|
||||
},
|
||||
run_server_stats: { route: "execute", name: "RunServerStats" },
|
||||
run_server_run_command: {
|
||||
route: "execute",
|
||||
name: "RunServerRunCommand",
|
||||
},
|
||||
run_server_scripts: { route: "execute", name: "RunServerScripts" },
|
||||
run_server_copy: { route: "execute", name: "RunServerCopy" },
|
||||
run_server_move: { route: "execute", name: "RunServerMove" },
|
||||
run_deployment_execute: {
|
||||
route: "execute",
|
||||
name: "RunDeploymentExecute",
|
||||
},
|
||||
run_deployment_redeploy: {
|
||||
route: "execute",
|
||||
name: "RunDeploymentRedeploy",
|
||||
},
|
||||
run_deployment_destroy: {
|
||||
route: "execute",
|
||||
name: "RunDeploymentDestroy",
|
||||
},
|
||||
run_deployment_stop: { route: "execute", name: "RunDeploymentStop" },
|
||||
run_deployment_logs: { route: "execute", name: "RunDeploymentLogs" },
|
||||
run_sync_deployment: { route: "execute", name: "RunSyncDeployment" },
|
||||
get_mcp_token: { route: "execute", name: "GetMcpToken" },
|
||||
};
|
||||
Reference in New Issue
Block a user