tdoms-mcp 0.6.1

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 TD/OMS MCP contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,164 @@
1
+ # TD/OMS MCP
2
+
3
+ Standalone TD/OMS change-management MCP for IBM Bob, Codex, Claude-compatible clients, and other agents that can launch a local stdio MCP server. It talks directly to TD/OMS REST APIs and does not require or control the Octo VS Code extension.
4
+
5
+ This is an independent community project. It is not affiliated with, maintained by, or endorsed by Remain Software, IBM, or their affiliates. TD/OMS, Octo, IBM, IBM i, and IBM Bob are trademarks of their respective owners.
6
+
7
+ ## Setup
8
+
9
+ Install the published command-line package:
10
+
11
+ ```shell
12
+ npm install --global tdoms-mcp
13
+ tdoms-mcp ui
14
+ ```
15
+
16
+ Or run it from a source checkout:
17
+
18
+ ```powershell
19
+ npm install
20
+ npm run ui
21
+ ```
22
+
23
+ Open `http://127.0.0.1:3737`, add the TD/OMS connection, and test it. Credentials and tokens stay in the local TD/OMS MCP data directory and are never returned to agents.
24
+
25
+ The Agent setup view detects supported MCP clients and can install or update this server after confirmation. Known configuration files are backed up before each change and restored automatically when a client command fails.
26
+
27
+ Keep TLS verification enabled. Publicly trusted certificates work without configuration. For an internal certificate authority, set the optional CA certificate file in the connection manager or set `TDOMS_MCP_CA_FILE` to an approved PEM file supplied by the organization.
28
+
29
+ Start the compact agent-neutral profile:
30
+
31
+ ```powershell
32
+ npm run mcp
33
+ ```
34
+
35
+ Start the complete named-tool profile:
36
+
37
+ ```powershell
38
+ npm run mcp:full
39
+ ```
40
+
41
+ The equivalent environment setting is `TDOMS_MCP_PROFILE=core` or `TDOMS_MCP_PROFILE=full`. `core` is the default.
42
+
43
+ ## Agent Configuration
44
+
45
+ Use the same local stdio definition in Bob and JSON-based MCP clients after a global npm installation:
46
+
47
+ ```json
48
+ {
49
+ "command": "tdoms-mcp",
50
+ "args": ["mcp"],
51
+ "env": {
52
+ "TDOMS_MCP_PROFILE": "core"
53
+ }
54
+ }
55
+ ```
56
+
57
+ Codex TOML:
58
+
59
+ ```toml
60
+ [mcp_servers.tdoms]
61
+ command = "tdoms-mcp"
62
+ args = ["mcp"]
63
+ env = { TDOMS_MCP_PROFILE = "core" }
64
+ startup_timeout_sec = 20
65
+ tool_timeout_sec = 60
66
+ ```
67
+
68
+ Restart or reload the agent's MCP servers after changing the configuration.
69
+
70
+ Detect supported local clients from the command line:
71
+
72
+ ```powershell
73
+ npm run clients
74
+ ```
75
+
76
+ Install or update one detected client:
77
+
78
+ ```powershell
79
+ node src/index.js install-client ibm-bob --confirm
80
+ node src/index.js install-client codex --confirm
81
+ node src/index.js install-client claude-code --confirm
82
+ node src/index.js install-client vscode --confirm
83
+ ```
84
+
85
+ Configure every detected client that is not already configured:
86
+
87
+ ```powershell
88
+ npm run clients:install
89
+ ```
90
+
91
+ Documented adapters are included for IBM Bob, Codex, Claude Code sessions, Claude Desktop chat, VS Code, Cursor, Windsurf, Kiro, Gemini CLI, Zed, and OpenCode. Microsoft Store Claude installations use the app's virtualized configuration directory automatically.
92
+
93
+ IBM Bob uses its own global MCP store at `~/.bob/settings/mcp.json`; it does not use VS Code's user-level `mcp.json`. The installer preserves servers from Bob's older `~/.bob/settings/mcp_settings.json` file when creating the current configuration. Bob hot-reloads MCP changes when a workspace folder is open; manage the resulting servers from the MCP tab in the Bob panel settings menu.
94
+
95
+ Detection and installation are environment-local. Running the installer on Windows configures Windows agents; running it inside WSL configures only that WSL distribution; running it on macOS or Linux uses that platform's native paths. This prevents a Windows client from receiving an unusable WSL command, or the reverse. Claude has two targets: **Claude Code sessions** configures Code sessions opened from Claude Desktop or VS Code, while **Claude Desktop chat** configures regular Desktop chats.
96
+
97
+ Client installation never copies TD/OMS passwords or tokens into agent configuration. It registers only the local stdio command and the `core` tool profile. Existing files are backed up, writes are atomic, invalid JSON is rejected, and failed client updates are restored.
98
+
99
+ ## Core Workflow
100
+
101
+ The default profile exposes seven tools:
102
+
103
+ - `tdoms_list_connections`
104
+ - `tdoms_get_current_context`
105
+ - `tdoms_list_capabilities`
106
+ - `tdoms_discover_options`
107
+ - `tdoms_plan_workflow`
108
+ - `tdoms_execute_workflow`
109
+ - `tdoms_get_workflow_status`
110
+
111
+ Call `tdoms_get_current_context` first. When one connection exists, it is selected automatically and the saved TD/OMS username becomes the default programmer ID. Octo sign-in context is not required.
112
+
113
+ Use `tdoms_discover_options` for both site-specific choices and structured reads. It supports workflow choices such as environments, programmers, paths, transfer targets, templates, reasons, conflicts, and user options. It also replaces extension views with task, request, component, source, queue, compile, history, log, spool, tracker, dependency, and dashboard reads. Task reads default to the current programmer; pass `context.allUsers: true` only when a broader search is intended.
114
+
115
+ For a mutation:
116
+
117
+ 1. Discover the valid choices.
118
+ 2. Call `tdoms_plan_workflow` with the chosen context, exact request body, and `optionSelections` keyed by option-set name. Those choices are validated now and before execution.
119
+ 3. Review its endpoint/body preview and obtain user approval.
120
+ 4. Call `tdoms_execute_workflow` with the returned `planId` and `confirm: true`.
121
+ 5. Call `tdoms_get_workflow_status` when the operation is asynchronous.
122
+
123
+ Plans expire after ten minutes. Execution re-reads relevant TD/OMS state and rejects stale plans. A plan can execute only once.
124
+
125
+ ## Full Profile
126
+
127
+ The `full` profile exposes 226 tools: the seven universal tools plus the existing task, request, solution, source, object, connection-list, compile, transfer, checkout, promote, branch, spool, log, remote-job, comment, label, user-option, analysis, dashboard, tracker, and administration tools.
128
+
129
+ All tools that can change TD/OMS require explicit confirmation. `tdoms_call_api` remains available in `full` as an advanced escape hatch for documented endpoints.
130
+
131
+ ## Validation
132
+
133
+ ```powershell
134
+ npm test
135
+ npm run smoke
136
+ ```
137
+
138
+ Tests use mocked TD/OMS clients and do not mutate a real environment. Live mutation tests must be enabled deliberately against a dedicated test system.
139
+
140
+ Local profiles are stored under `%APPDATA%/tdoms-mcp` on Windows, `~/Library/Application Support/tdoms-mcp` on macOS, and `~/.config/tdoms-mcp` on Linux. Override this with `TDOMS_MCP_DATA_DIR`.
141
+
142
+ ## Credential Storage
143
+
144
+ Connection metadata is stored in `connections.json`. Passwords and refreshed JWTs are encrypted with AES-256-GCM in `secrets.json`. By default, a random key is stored in `local.key`. All three files use atomic replacement and cross-process locking, and POSIX systems enforce `0700` on the directory and `0600` on files.
145
+
146
+ For stronger key separation, set `TDOMS_MCP_MASTER_KEY` to 32 random bytes encoded as base64 or 64 hexadecimal characters before adding connections. Keep the same value available to every MCP process that uses that data directory. Changing or losing it makes existing encrypted secrets unreadable.
147
+
148
+ Generate a base64 key:
149
+
150
+ ```shell
151
+ node -e "console.log(require('node:crypto').randomBytes(32).toString('base64'))"
152
+ ```
153
+
154
+ On Windows, restrict an existing data directory to the current user, SYSTEM, and local Administrators:
155
+
156
+ ```powershell
157
+ npm run secure-storage
158
+ ```
159
+
160
+ Native WSL uses its own Linux data directory and requires Node.js 18 or newer. To reuse the Windows installation and Windows credentials from WSL, launch Windows `node.exe`; otherwise configure the connection separately inside WSL. Avoid sharing credential files through `/mnt/c` unless the Windows ACL has been hardened.
161
+
162
+ ## License
163
+
164
+ Released under the MIT License. See `LICENSE`.
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "tdoms-mcp",
3
+ "version": "0.6.1",
4
+ "description": "Agent-neutral MCP server for TD/OMS change-management workflows.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/ashishthomas2202/tdoms-mcp.git"
10
+ },
11
+ "homepage": "https://github.com/ashishthomas2202/tdoms-mcp#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/ashishthomas2202/tdoms-mcp/issues"
14
+ },
15
+ "keywords": [
16
+ "mcp",
17
+ "model-context-protocol",
18
+ "tdoms",
19
+ "change-management",
20
+ "ibm-i"
21
+ ],
22
+ "files": [
23
+ "src/",
24
+ "skills/",
25
+ "README.md",
26
+ "LICENSE"
27
+ ],
28
+ "bin": {
29
+ "tdoms-mcp": "./src/index.js"
30
+ },
31
+ "scripts": {
32
+ "mcp": "node src/index.js mcp",
33
+ "mcp:full": "node src/index.js mcp --profile full",
34
+ "ui": "node src/index.js ui",
35
+ "dev": "node src/index.js dev",
36
+ "smoke": "node src/index.js smoke",
37
+ "secure-storage": "node src/index.js secure-storage",
38
+ "clients": "node src/index.js clients",
39
+ "clients:install": "node src/index.js install-detected --confirm",
40
+ "test": "node --test"
41
+ },
42
+ "dependencies": {
43
+ "@modelcontextprotocol/sdk": "^1.18.2",
44
+ "express": "^4.19.2",
45
+ "jsonc-parser": "^3.3.1",
46
+ "lucide-static": "^1.24.0",
47
+ "zod": "^4.1.12"
48
+ },
49
+ "engines": {
50
+ "node": ">=18"
51
+ }
52
+ }
@@ -0,0 +1,48 @@
1
+ ---
2
+ name: tdoms-mcp-routing
3
+ description: Use TD/OMS change management through the standalone TD/OMS MCP or Octo MCP tools. Trigger for tasks, requests, source, objects, checkout, promote, transfer, compile, branches, connection lists, logs, spool files, conflicts, labels, and other TD/OMS workflows, especially when an agent incorrectly asks for Octo sign-in or a programmer ID.
4
+ ---
5
+
6
+ # TD/OMS MCP Routing
7
+
8
+ Prefer the standalone TD/OMS MCP when available. It works independently of the Octo VS Code UI.
9
+
10
+ ## Standalone Core Flow
11
+
12
+ 1. Call `tdoms_get_current_context`. Let it select the only connection and derive the TD/OMS programmer ID from the saved profile.
13
+ 2. Call `tdoms_list_capabilities` when the requested workflow or required choices are unclear.
14
+ 3. Call `tdoms_discover_options` before choosing application, environment, programmer, path, reason, target, object, template, conflict resolution, or any site-specific value.
15
+ 4. Use `tdoms_discover_options` for structured task, request, component, source, queue, compile, history, log, spool, tracker, dependency, and dashboard reads.
16
+ 5. For changes, call `tdoms_plan_workflow` with the exact context, selections, and `optionSelections` for values returned by discovery. Show the user its action, target, endpoint/body preview, warnings, and blockers.
17
+ 6. Call `tdoms_execute_workflow` with the returned `planId` and `confirm: true` only after the user approves that exact preview.
18
+ 7. Call `tdoms_get_workflow_status` for asynchronous work.
19
+
20
+ Never guess a value when discovery returns no choices or `supported: false`. Ask one concise question instead.
21
+
22
+ For "my tasks," use option set `tasks` without supplying a programmer. The MCP uses the saved TD/OMS username automatically. Set `context.allUsers: true` only when the user requests tasks for everyone.
23
+
24
+ ## Mutation Rules
25
+
26
+ - Read current state before planning.
27
+ - Treat source saves, checkout, promote, transfer, compile, complete, delete, process, queue, release, close, and configuration changes as mutations.
28
+ - Never set `confirm: true` without explicit approval of the current plan.
29
+ - Stop when TD/OMS reports warnings, locks, conflicts, authority failures, or changed state. Summarize the result and replan if needed.
30
+ - Never ask the user to paste TD/OMS credentials into chat.
31
+
32
+ ## Full Profile
33
+
34
+ When `TDOMS_MCP_PROFILE=full`, prefer a specific named read tool when it is clearer than generic discovery. Named mutation tools still require explicit approval and `confirm: true`.
35
+
36
+ Use typed transfer tools in this sequence: select targets, prepare, inspect warnings, execute, then monitor progress. Use typed source tools to read the latest source and last-change marker before saving. Use compile-and-check to retrieve diagnostics instead of asking the user to paste spool output.
37
+
38
+ ## Octo MCP Fallback
39
+
40
+ If only the extension MCP is available:
41
+
42
+ - Use `OMS-Database-REST-API.getRecords` for reads and task lists.
43
+ - Use `TD-OMS-Task-API` only for task mutations.
44
+ - Use `TD-OMS-Branch-Service-API` for branch mutations.
45
+ - Treat `Octo-Views` and `Octo-Wizards` as UI launchers, not proof that an action completed.
46
+ - Do not require `Octo-User-Context` before direct TD/OMS reads.
47
+
48
+ If Octo user context says sign-in is required but a direct TD/OMS read succeeds, continue with the direct tool and report that the Octo UI context is stale. Retry programmer filters in uppercase before reporting that no tasks exist.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "TD/OMS MCP Routing"
3
+ short_description: "Route TD/OMS change-management workflows"
4
+ default_prompt: "Use $tdoms-mcp-routing to handle this TD/OMS request safely through MCP."
@@ -0,0 +1,124 @@
1
+ export const OPTION_SETS = [
2
+ "applications",
3
+ "environments",
4
+ "programmers",
5
+ "userClasses",
6
+ "taskStatuses",
7
+ "taskTypes",
8
+ "releases",
9
+ "priorities",
10
+ "branchesPaths",
11
+ "taskObjects",
12
+ "solutions",
13
+ "transferTargets",
14
+ "subEnvironments",
15
+ "completionReasons",
16
+ "ratificationReasons",
17
+ "memberAttributes",
18
+ "solutionTypes",
19
+ "compileOverrides",
20
+ "labels",
21
+ "objectTemplates",
22
+ "objectLocations",
23
+ "revisions",
24
+ "conflicts",
25
+ "remoteJobs",
26
+ "schedules",
27
+ "trackerLinks",
28
+ "userOptions",
29
+ "tasks",
30
+ "requests",
31
+ "components",
32
+ "connectionLists",
33
+ "buildQueue",
34
+ "compileResults",
35
+ "transferHistory",
36
+ "logs",
37
+ "spoolFiles",
38
+ "trackerRecords",
39
+ "source",
40
+ "dependencies",
41
+ "dashboards"
42
+ ];
43
+
44
+ const capabilities = [
45
+ mutation("change-member-attribute", "Change Member Attribute", "openChangeMemberAttributeWizard", "OMQROB", "/change", ["memberAttributes"], ["applicationCode", "objectCode", "memberCode"], "OMXObjectDetailExtended"),
46
+ mutation("change-programmer", "Change Programmer", "openChangeProgrammerWizard", "OMQRTA", "/change", ["programmers", "userClasses"], ["applicationCode", "taskNumber"], "OMXFixExtended"),
47
+ mutation("change-solution-type", "Change Solution Type", "openChangeSolutionTypeWizard", "OMQRSO", "/change", ["solutions", "solutionTypes"], ["applicationCode", "taskNumber"], "OMXSolutionExtended"),
48
+ mutation("change-task-transfer-path", "Change Task Transfer Path", "openChangeTaskTransferPathWizard", "OMQRTA", "/change", ["branchesPaths"], ["applicationCode", "taskNumber"], "OMXFixExtended"),
49
+ mutation("compile-override", "Compile Override", "openCompileOverrideWizard", "OMQRCO", "/change", ["compileOverrides", "taskObjects"], ["applicationCode", "taskNumber"], "OMXCompileOverrideExtended"),
50
+ mutation("complete-task", "Complete Task", "openCompleteTaskWizard", "OMQRTA", "/complete", ["completionReasons"], ["applicationCode", "taskNumber"], "OMXFixExtended"),
51
+ mutation("delete-objects", "Delete Objects", "openDeleteObjectsWizard", "OMQROB", "/delete", ["taskObjects"], ["applicationCode"], "OMXObjectExtended"),
52
+ mutation("disconnect-solutions", "Disconnect Solutions", "openDisconnectSolutionsWizard", "OMQRSO", "/disconnect", ["solutions"], ["applicationCode", "taskNumber"], "OMXSolutionExtended"),
53
+ readOnly("display-message", "Display TD/OMS Message", "openDisplayMessageWizard", [], [], undefined, "Messages are returned directly in MCP responses; no UI window is required."),
54
+ mutation("edit-branch", "Edit Branch", "openEditBranchWizard", "OMQRBR", "/change", ["branchesPaths"], ["applicationCode", "pathCode"], "OMXTransferPath"),
55
+ mutation("fill-object-file", "Fill Object File", "openFillObjectFileWizard", "OMQRFO", "/fillObject", ["taskObjects"], ["applicationCode", "objectCode"], "OMXObjectExtended"),
56
+ mutation("manage-label", "Manage Label", "openLabelWizard", "OMQRLB", "/label", ["labels"], ["applicationCode"], "OMXLabel"),
57
+ mutation("link-issue-to-task", "Link Issue To Task", "openLinkIssueToTaskWizard", "OMQRTA", "/link/ticket", ["trackerLinks"], ["applicationCode", "taskNumber"], "OMXRemoteIssueInformation"),
58
+ mutation("link-task-to-issue", "Link Task To Issue", "openLinkTaskToIssueWizard", "OMQRTA", "/link/ticket", ["trackerLinks"], ["applicationCode", "taskNumber"], "OMXRemoteIssueInformation"),
59
+ mutation("move-solutions", "Move Solutions", "openMoveSolutionsWizard", "OMQRSO", "/move", ["solutions", "branchesPaths"], ["applicationCode", "taskNumber"], "OMXSolutionExtended"),
60
+ mutation("new-object", "New Object From Template", "openNewObjectTemplatesWizard", "OMQRNO", "/add", ["objectTemplates", "objectLocations"], ["applicationCode", "taskNumber", "environmentCode"], "OMXObjectExtended"),
61
+ mutation("new-task-branch", "New Task Branch", "openNewTaskBranchWizard", "OMQRBR", "/add", ["branchesPaths"], ["applicationCode", "taskNumber"], "OMXTransferPath"),
62
+ mutation("close-remote-job", "Close Remote Job", "openCloseRemoteJobWizard", "OMQRRJ", "/close", ["remoteJobs", "completionReasons"], ["applicationCode"], "OMXRemoteJobMonitorExtended"),
63
+ mutation("reopen-remote-job", "Reopen Remote Job", "openReopenRemoteJobWizard", "OMQRRJ", "/reopen", ["remoteJobs"], ["applicationCode"], "OMXRemoteJobMonitorExtended"),
64
+ mutation("schedule-remote-job", "Schedule Remote Job", "openScheduleRemoteJobWizard", "OMQRMD", "/schedule", ["remoteJobs", "schedules"], ["applicationCode"], "OMXRemoteJobMonitorExtended"),
65
+ readOnly("revision-compare", "Revision Compare", "openRevisionCompareWizard", ["revisions"], ["applicationCode"], "OMXObjectTransferHistory"),
66
+ readOnly("solution-conflict", "Solution Conflict", "openSolutionConflictWizard", ["solutions", "conflicts"], ["applicationCode", "taskNumber"], "OMXObjectVersionConflict", "Conflict resolution is site-specific; discovery is supported and mutation requires a documented site endpoint."),
67
+ mutation("task-ratification", "Task Ratification", "openTaskRatificationWizard", "OMQRTA", "/ratify", ["ratificationReasons", "programmers"], ["applicationCode", "taskNumber"], "OMXFixExtended"),
68
+ unsupported("tracker-server-manager", "Tracker Server Manager", "openTrackerServerManagerWizard", "Tracker server administration belongs to Octo configuration and has no known TD/OMS REST endpoint."),
69
+ mutation("transfer", "Transfer, Checkout, Or Promote", "openTransferWizard", "OMQRTO", "/prepare", ["taskObjects", "transferTargets", "subEnvironments"], ["applicationCode", "taskNumber"], "OMXSolutionExtended"),
70
+ mutation("unlink-task-from-issue", "Unlink Task From Issue", "openUnlinkTaskFromIssueWizard", "OMQRTA", "/unlink/ticket", ["trackerLinks"], ["applicationCode", "taskNumber"], "OMXRemoteIssueInformation"),
71
+ mutation("execute-user-option", "Execute User Option", "openUserOptionWizard", "OMQRUO", "/execute", ["userOptions"], ["applicationCode", "taskNumber"], "OMXUserOption"),
72
+ mutation("resolve-version-conflict", "Resolve Version Conflict", "openVersionConflictsWizard", "OMQRVC", "/confirm", ["conflicts"], ["applicationCode", "taskNumber"], "OMXObjectVersionConflict")
73
+ ];
74
+
75
+ export const CAPABILITIES = Object.freeze(capabilities.map((capability) => Object.freeze(capability)));
76
+ export const CAPABILITY_IDS = CAPABILITIES.map((capability) => capability.id);
77
+
78
+ export function getCapability(id) {
79
+ return CAPABILITIES.find((capability) => capability.id === id);
80
+ }
81
+
82
+ function mutation(id, title, octoWizard, service, path, optionSets, requiredContext, stateTable) {
83
+ return {
84
+ id,
85
+ title,
86
+ octoWizard,
87
+ category: "change-management",
88
+ support: "supported",
89
+ mode: "mutation",
90
+ optionSets,
91
+ requiredContext,
92
+ stateTable,
93
+ execution: { method: "POST", service, path }
94
+ };
95
+ }
96
+
97
+ function readOnly(id, title, octoWizard, optionSets, requiredContext, stateTable, note) {
98
+ return {
99
+ id,
100
+ title,
101
+ octoWizard,
102
+ category: "change-management",
103
+ support: "supported",
104
+ mode: "read-only",
105
+ optionSets,
106
+ requiredContext,
107
+ stateTable,
108
+ note
109
+ };
110
+ }
111
+
112
+ function unsupported(id, title, octoWizard, note) {
113
+ return {
114
+ id,
115
+ title,
116
+ octoWizard,
117
+ category: "octo-only",
118
+ support: "unsupported",
119
+ mode: "read-only",
120
+ optionSets: [],
121
+ requiredContext: [],
122
+ note
123
+ };
124
+ }