dbatools-mcp-server 0.1.0 → 0.2.0
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 +21 -21
- package/README.md +160 -160
- package/generated/.gitkeep +3 -3
- package/package.json +66 -66
- package/scripts/refresh-help.ps1 +192 -192
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 DataPlat 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.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DataPlat 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
CHANGED
|
@@ -1,160 +1,160 @@
|
|
|
1
|
-
# dbatools-mcp-server
|
|
2
|
-
|
|
3
|
-
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server for the [dbatools](https://dbatools.io) PowerShell module.
|
|
4
|
-
|
|
5
|
-
Exposes dbatools commands as MCP tools so AI assistants (GitHub Copilot, Claude, etc.) can discover, explain, and execute dbatools commands directly — with all metadata sourced from dbatools' own **comment-based help**.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Features
|
|
10
|
-
|
|
11
|
-
- **`list_dbatools_commands`** — search commands by verb, noun, keyword, or risk level
|
|
12
|
-
- **`get_dbatools_command_help`** — full normalized help (synopsis, parameters, examples) from `Get-Help -Full`
|
|
13
|
-
- **`invoke_dbatools_command`** — execute any dbatools command with safe parameter validation, risk gating, and structured JSON output
|
|
14
|
-
- **`check_dbatools_environment`** — verify PowerShell + dbatools installation, index freshness, and version alignment
|
|
15
|
-
- **Version mismatch detection** — warns when installed dbatools version differs from the indexed version
|
|
16
|
-
- **Safe mode** — non-readonly commands require explicit `confirm: true` to execute
|
|
17
|
-
- **SQL Authentication support** — pass `SqlCredential: { username, password }` for SQL auth instances
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Prerequisites
|
|
22
|
-
|
|
23
|
-
- [Node.js](https://nodejs.org/) 20+
|
|
24
|
-
- [PowerShell 7+](https://github.com/PowerShell/PowerShell/releases) (`pwsh`)
|
|
25
|
-
- [dbatools](https://dbatools.io/download) PowerShell module
|
|
26
|
-
|
|
27
|
-
```powershell
|
|
28
|
-
Install-Module dbatools -Scope CurrentUser
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## Quick Start
|
|
34
|
-
|
|
35
|
-
```powershell
|
|
36
|
-
# 1. Clone the repo
|
|
37
|
-
git clone https://github.com/Dataplat/dbatools-mcp-server.git
|
|
38
|
-
cd dbatools-mcp-server
|
|
39
|
-
|
|
40
|
-
# 2. Install Node dependencies
|
|
41
|
-
npm install
|
|
42
|
-
|
|
43
|
-
# 3. Generate the help index from your local dbatools installation
|
|
44
|
-
npm run refresh-help
|
|
45
|
-
|
|
46
|
-
# 4. Build
|
|
47
|
-
npm run build
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
Then open the folder in VS Code — the `.vscode/mcp.json` file automatically registers the MCP server.
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
## Connecting to VS Code
|
|
55
|
-
|
|
56
|
-
The included [`.vscode/mcp.json`](.vscode/mcp.json) registers the server as a local STDIO MCP server.
|
|
57
|
-
Open this folder in VS Code and the server will appear in the GitHub Copilot MCP panel.
|
|
58
|
-
|
|
59
|
-
```json
|
|
60
|
-
{
|
|
61
|
-
"servers": {
|
|
62
|
-
"dbatools": {
|
|
63
|
-
"type": "stdio",
|
|
64
|
-
"command": "node",
|
|
65
|
-
"args": ["${workspaceFolder}/dist/server.js"],
|
|
66
|
-
"env": {
|
|
67
|
-
"DBATOOLS_SAFE_MODE": "true",
|
|
68
|
-
"MAX_OUTPUT_ROWS": "100",
|
|
69
|
-
"COMMAND_TIMEOUT_SECONDS": "60"
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## Configuration
|
|
79
|
-
|
|
80
|
-
All settings are controlled via environment variables (set in `.vscode/mcp.json` or your shell):
|
|
81
|
-
|
|
82
|
-
| Variable | Default | Description |
|
|
83
|
-
|---|---|---|
|
|
84
|
-
| `PWSH_EXE` | `pwsh` | Path to PowerShell executable |
|
|
85
|
-
| `DBATOOLS_SAFE_MODE` | `true` | When `true`, non-readonly commands require `confirm: true` |
|
|
86
|
-
| `MAX_OUTPUT_ROWS` | `100` | Maximum rows returned per command execution |
|
|
87
|
-
| `COMMAND_TIMEOUT_SECONDS` | `60` | Seconds before PowerShell process is killed |
|
|
88
|
-
|
|
89
|
-
---
|
|
90
|
-
|
|
91
|
-
## Refreshing the Help Index
|
|
92
|
-
|
|
93
|
-
The help index (`generated/dbatools-help.json`) is generated from your locally installed dbatools module.
|
|
94
|
-
Re-run whenever dbatools is updated:
|
|
95
|
-
|
|
96
|
-
```powershell
|
|
97
|
-
Update-Module dbatools -Scope CurrentUser
|
|
98
|
-
npm run refresh-help
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
The server detects version mismatches at runtime and warns you when the index is stale.
|
|
102
|
-
|
|
103
|
-
---
|
|
104
|
-
|
|
105
|
-
## Risk Levels
|
|
106
|
-
|
|
107
|
-
Commands are automatically classified by verb:
|
|
108
|
-
|
|
109
|
-
| Risk Level | Verbs | Behavior |
|
|
110
|
-
|---|---|---|
|
|
111
|
-
| `readonly` | Get, Test, Find, Compare, … | Always allowed |
|
|
112
|
-
| `change` | Set, New, Add, Copy, Enable, … | Requires `confirm: true` in safe mode |
|
|
113
|
-
| `destructive` | Remove, Drop, Disable, Reset, … | Requires `confirm: true` in safe mode |
|
|
114
|
-
|
|
115
|
-
---
|
|
116
|
-
|
|
117
|
-
## SQL Authentication
|
|
118
|
-
|
|
119
|
-
For SQL-auth-only instances (e.g. Docker), pass credentials via the `SqlCredential` parameter:
|
|
120
|
-
|
|
121
|
-
```json
|
|
122
|
-
{
|
|
123
|
-
"SqlInstance": "localhost,1433",
|
|
124
|
-
"SqlCredential": { "username": "<SqlLogin>", "password": "YourPassword" }
|
|
125
|
-
}
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
## Project Structure
|
|
131
|
-
|
|
132
|
-
```
|
|
133
|
-
dbatools-mcp-server/
|
|
134
|
-
├── src/
|
|
135
|
-
│ ├── server.ts # MCP server entry point, tool definitions
|
|
136
|
-
│ ├── powershell.ts # PowerShell process runner, health checks, version detection
|
|
137
|
-
│ ├── help-indexer.ts # Help manifest loader and command search
|
|
138
|
-
│ ├── tool-registry.ts # Risk classification, safe argument builder
|
|
139
|
-
│ └── types.ts # Shared TypeScript interfaces
|
|
140
|
-
├── scripts/
|
|
141
|
-
│ └── refresh-help.ps1 # Generates generated/dbatools-help.json
|
|
142
|
-
├── generated/ # Help index (gitignored, generated locally)
|
|
143
|
-
├── .vscode/
|
|
144
|
-
│ └── mcp.json # VS Code MCP local server registration
|
|
145
|
-
└── dist/ # Compiled output (gitignored)
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
## Contributing
|
|
151
|
-
|
|
152
|
-
Contributions are welcome! Please open an issue first for significant changes.
|
|
153
|
-
|
|
154
|
-
This project follows the same community spirit as [dbatools](https://github.com/dataplat/dbatools).
|
|
155
|
-
|
|
156
|
-
---
|
|
157
|
-
|
|
158
|
-
## License
|
|
159
|
-
|
|
160
|
-
[MIT](LICENSE) — © 2026 DataPlat contributors
|
|
1
|
+
# dbatools-mcp-server
|
|
2
|
+
|
|
3
|
+
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server for the [dbatools](https://dbatools.io) PowerShell module.
|
|
4
|
+
|
|
5
|
+
Exposes dbatools commands as MCP tools so AI assistants (GitHub Copilot, Claude, etc.) can discover, explain, and execute dbatools commands directly — with all metadata sourced from dbatools' own **comment-based help**.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **`list_dbatools_commands`** — search commands by verb, noun, keyword, or risk level
|
|
12
|
+
- **`get_dbatools_command_help`** — full normalized help (synopsis, parameters, examples) from `Get-Help -Full`
|
|
13
|
+
- **`invoke_dbatools_command`** — execute any dbatools command with safe parameter validation, risk gating, and structured JSON output
|
|
14
|
+
- **`check_dbatools_environment`** — verify PowerShell + dbatools installation, index freshness, and version alignment
|
|
15
|
+
- **Version mismatch detection** — warns when installed dbatools version differs from the indexed version
|
|
16
|
+
- **Safe mode** — non-readonly commands require explicit `confirm: true` to execute
|
|
17
|
+
- **SQL Authentication support** — pass `SqlCredential: { username, password }` for SQL auth instances
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Prerequisites
|
|
22
|
+
|
|
23
|
+
- [Node.js](https://nodejs.org/) 20+
|
|
24
|
+
- [PowerShell 7+](https://github.com/PowerShell/PowerShell/releases) (`pwsh`)
|
|
25
|
+
- [dbatools](https://dbatools.io/download) PowerShell module
|
|
26
|
+
|
|
27
|
+
```powershell
|
|
28
|
+
Install-Module dbatools -Scope CurrentUser
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```powershell
|
|
36
|
+
# 1. Clone the repo
|
|
37
|
+
git clone https://github.com/Dataplat/dbatools-mcp-server.git
|
|
38
|
+
cd dbatools-mcp-server
|
|
39
|
+
|
|
40
|
+
# 2. Install Node dependencies
|
|
41
|
+
npm install
|
|
42
|
+
|
|
43
|
+
# 3. Generate the help index from your local dbatools installation
|
|
44
|
+
npm run refresh-help
|
|
45
|
+
|
|
46
|
+
# 4. Build
|
|
47
|
+
npm run build
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Then open the folder in VS Code — the `.vscode/mcp.json` file automatically registers the MCP server.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Connecting to VS Code
|
|
55
|
+
|
|
56
|
+
The included [`.vscode/mcp.json`](.vscode/mcp.json) registers the server as a local STDIO MCP server.
|
|
57
|
+
Open this folder in VS Code and the server will appear in the GitHub Copilot MCP panel.
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"servers": {
|
|
62
|
+
"dbatools": {
|
|
63
|
+
"type": "stdio",
|
|
64
|
+
"command": "node",
|
|
65
|
+
"args": ["${workspaceFolder}/dist/server.js"],
|
|
66
|
+
"env": {
|
|
67
|
+
"DBATOOLS_SAFE_MODE": "true",
|
|
68
|
+
"MAX_OUTPUT_ROWS": "100",
|
|
69
|
+
"COMMAND_TIMEOUT_SECONDS": "60"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Configuration
|
|
79
|
+
|
|
80
|
+
All settings are controlled via environment variables (set in `.vscode/mcp.json` or your shell):
|
|
81
|
+
|
|
82
|
+
| Variable | Default | Description |
|
|
83
|
+
|---|---|---|
|
|
84
|
+
| `PWSH_EXE` | `pwsh` | Path to PowerShell executable |
|
|
85
|
+
| `DBATOOLS_SAFE_MODE` | `true` | When `true`, non-readonly commands require `confirm: true` |
|
|
86
|
+
| `MAX_OUTPUT_ROWS` | `100` | Maximum rows returned per command execution |
|
|
87
|
+
| `COMMAND_TIMEOUT_SECONDS` | `60` | Seconds before PowerShell process is killed |
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Refreshing the Help Index
|
|
92
|
+
|
|
93
|
+
The help index (`generated/dbatools-help.json`) is generated from your locally installed dbatools module.
|
|
94
|
+
Re-run whenever dbatools is updated:
|
|
95
|
+
|
|
96
|
+
```powershell
|
|
97
|
+
Update-Module dbatools -Scope CurrentUser
|
|
98
|
+
npm run refresh-help
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The server detects version mismatches at runtime and warns you when the index is stale.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Risk Levels
|
|
106
|
+
|
|
107
|
+
Commands are automatically classified by verb:
|
|
108
|
+
|
|
109
|
+
| Risk Level | Verbs | Behavior |
|
|
110
|
+
|---|---|---|
|
|
111
|
+
| `readonly` | Get, Test, Find, Compare, … | Always allowed |
|
|
112
|
+
| `change` | Set, New, Add, Copy, Enable, … | Requires `confirm: true` in safe mode |
|
|
113
|
+
| `destructive` | Remove, Drop, Disable, Reset, … | Requires `confirm: true` in safe mode |
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## SQL Authentication
|
|
118
|
+
|
|
119
|
+
For SQL-auth-only instances (e.g. Docker), pass credentials via the `SqlCredential` parameter:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"SqlInstance": "localhost,1433",
|
|
124
|
+
"SqlCredential": { "username": "<SqlLogin>", "password": "YourPassword" }
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Project Structure
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
dbatools-mcp-server/
|
|
134
|
+
├── src/
|
|
135
|
+
│ ├── server.ts # MCP server entry point, tool definitions
|
|
136
|
+
│ ├── powershell.ts # PowerShell process runner, health checks, version detection
|
|
137
|
+
│ ├── help-indexer.ts # Help manifest loader and command search
|
|
138
|
+
│ ├── tool-registry.ts # Risk classification, safe argument builder
|
|
139
|
+
│ └── types.ts # Shared TypeScript interfaces
|
|
140
|
+
├── scripts/
|
|
141
|
+
│ └── refresh-help.ps1 # Generates generated/dbatools-help.json
|
|
142
|
+
├── generated/ # Help index (gitignored, generated locally)
|
|
143
|
+
├── .vscode/
|
|
144
|
+
│ └── mcp.json # VS Code MCP local server registration
|
|
145
|
+
└── dist/ # Compiled output (gitignored)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Contributing
|
|
151
|
+
|
|
152
|
+
Contributions are welcome! Please open an issue first for significant changes.
|
|
153
|
+
|
|
154
|
+
This project follows the same community spirit as [dbatools](https://github.com/dataplat/dbatools).
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## License
|
|
159
|
+
|
|
160
|
+
[MIT](LICENSE) — © 2026 DataPlat contributors
|
package/generated/.gitkeep
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
# This directory is created by scripts/refresh-help.ps1
|
|
2
|
-
# dbatools-help.json is generated locally and is intentionally gitignored.
|
|
3
|
-
# Run: npm run refresh-help
|
|
1
|
+
# This directory is created by scripts/refresh-help.ps1
|
|
2
|
+
# dbatools-help.json is generated locally and is intentionally gitignored.
|
|
3
|
+
# Run: npm run refresh-help
|
package/package.json
CHANGED
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dbatools-mcp-server",
|
|
3
|
-
"mcpName": "io.github.dataplat/dbatools-mcp-server",
|
|
4
|
-
"version": "0.
|
|
5
|
-
"description": "MCP server for
|
|
6
|
-
"keywords": [
|
|
7
|
-
"dbatools",
|
|
8
|
-
"mcp",
|
|
9
|
-
"sql server",
|
|
10
|
-
"powershell",
|
|
11
|
-
"database"
|
|
12
|
-
],
|
|
13
|
-
"repository": {
|
|
14
|
-
"type": "git",
|
|
15
|
-
"url": "https://github.com/dataplat/dbatools-mcp-server.git"
|
|
16
|
-
},
|
|
17
|
-
"license": "MIT",
|
|
18
|
-
"type": "module",
|
|
19
|
-
"files": [
|
|
20
|
-
"dist",
|
|
21
|
-
"generated/.gitkeep",
|
|
22
|
-
"scripts/refresh-help.ps1"
|
|
23
|
-
],
|
|
24
|
-
"bin": {
|
|
25
|
-
"dbatools-mcp-server": "./dist/server.js"
|
|
26
|
-
},
|
|
27
|
-
"scripts": {
|
|
28
|
-
"build": "tsc",
|
|
29
|
-
"dev": "tsx src/server.ts",
|
|
30
|
-
"start": "node dist/server.js",
|
|
31
|
-
"refresh-help": "pwsh -NonInteractive -File scripts/refresh-help.ps1",
|
|
32
|
-
"test": "node --experimental-vm-modules node_modules/.bin/jest --passWithNoTests"
|
|
33
|
-
},
|
|
34
|
-
"dependencies": {
|
|
35
|
-
"@modelcontextprotocol/sdk": "^1.10.0",
|
|
36
|
-
"zod": "^3.24.0"
|
|
37
|
-
},
|
|
38
|
-
"devDependencies": {
|
|
39
|
-
"@types/jest": "^29.5.0",
|
|
40
|
-
"@types/node": "^22.0.0",
|
|
41
|
-
"jest": "^29.7.0",
|
|
42
|
-
"ts-jest": "^29.2.0",
|
|
43
|
-
"tsx": "^4.19.0",
|
|
44
|
-
"typescript": "^5.7.0"
|
|
45
|
-
},
|
|
46
|
-
"jest": {
|
|
47
|
-
"preset": "ts-jest/presets/default-esm",
|
|
48
|
-
"extensionsToTreatAsEsm": [
|
|
49
|
-
".ts"
|
|
50
|
-
],
|
|
51
|
-
"moduleNameMapper": {
|
|
52
|
-
"^(\\.{1,2}/.*)\\.js$": "$1"
|
|
53
|
-
},
|
|
54
|
-
"transform": {
|
|
55
|
-
"^.+\\.tsx?$": [
|
|
56
|
-
"ts-jest",
|
|
57
|
-
{
|
|
58
|
-
"useESM": true
|
|
59
|
-
}
|
|
60
|
-
]
|
|
61
|
-
}
|
|
62
|
-
},
|
|
63
|
-
"engines": {
|
|
64
|
-
"node": ">=20.0.0"
|
|
65
|
-
}
|
|
66
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "dbatools-mcp-server",
|
|
3
|
+
"mcpName": "io.github.dataplat/dbatools-mcp-server",
|
|
4
|
+
"version": "0.2.0",
|
|
5
|
+
"description": "MCP server for dbatools — exposes SQL Server management commands as MCP tools",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"dbatools",
|
|
8
|
+
"mcp",
|
|
9
|
+
"sql server",
|
|
10
|
+
"powershell",
|
|
11
|
+
"database"
|
|
12
|
+
],
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/dataplat/dbatools-mcp-server.git"
|
|
16
|
+
},
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"type": "module",
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"generated/.gitkeep",
|
|
22
|
+
"scripts/refresh-help.ps1"
|
|
23
|
+
],
|
|
24
|
+
"bin": {
|
|
25
|
+
"dbatools-mcp-server": "./dist/server.js"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc",
|
|
29
|
+
"dev": "tsx src/server.ts",
|
|
30
|
+
"start": "node dist/server.js",
|
|
31
|
+
"refresh-help": "pwsh -NonInteractive -File scripts/refresh-help.ps1",
|
|
32
|
+
"test": "node --experimental-vm-modules node_modules/.bin/jest --passWithNoTests"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@modelcontextprotocol/sdk": "^1.10.0",
|
|
36
|
+
"zod": "^3.24.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/jest": "^29.5.0",
|
|
40
|
+
"@types/node": "^22.0.0",
|
|
41
|
+
"jest": "^29.7.0",
|
|
42
|
+
"ts-jest": "^29.2.0",
|
|
43
|
+
"tsx": "^4.19.0",
|
|
44
|
+
"typescript": "^5.7.0"
|
|
45
|
+
},
|
|
46
|
+
"jest": {
|
|
47
|
+
"preset": "ts-jest/presets/default-esm",
|
|
48
|
+
"extensionsToTreatAsEsm": [
|
|
49
|
+
".ts"
|
|
50
|
+
],
|
|
51
|
+
"moduleNameMapper": {
|
|
52
|
+
"^(\\.{1,2}/.*)\\.js$": "$1"
|
|
53
|
+
},
|
|
54
|
+
"transform": {
|
|
55
|
+
"^.+\\.tsx?$": [
|
|
56
|
+
"ts-jest",
|
|
57
|
+
{
|
|
58
|
+
"useESM": true
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"engines": {
|
|
64
|
+
"node": ">=20.0.0"
|
|
65
|
+
}
|
|
66
|
+
}
|
package/scripts/refresh-help.ps1
CHANGED
|
@@ -1,192 +1,192 @@
|
|
|
1
|
-
<#
|
|
2
|
-
.SYNOPSIS
|
|
3
|
-
Generates generated/dbatools-help.json by extracting comment-based help from
|
|
4
|
-
every command in the locally installed dbatools module.
|
|
5
|
-
|
|
6
|
-
.DESCRIPTION
|
|
7
|
-
Run this script whenever dbatools is installed or updated.
|
|
8
|
-
Output is consumed by the MCP server at startup and cached for the session.
|
|
9
|
-
|
|
10
|
-
Usage: npm run refresh-help
|
|
11
|
-
pwsh -File scripts/refresh-help.ps1
|
|
12
|
-
|
|
13
|
-
.PARAMETER OutputPath
|
|
14
|
-
Override the output file path (default: <repo-root>/generated/dbatools-help.json)
|
|
15
|
-
|
|
16
|
-
.PARAMETER MaxCommands
|
|
17
|
-
Limit to N commands for quick development iterations (0 = all commands)
|
|
18
|
-
#>
|
|
19
|
-
[CmdletBinding()]
|
|
20
|
-
param(
|
|
21
|
-
[string]$OutputPath = "",
|
|
22
|
-
[int]$MaxCommands = 0
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
$ErrorActionPreference = 'Stop'
|
|
26
|
-
$InformationPreference = 'Continue'
|
|
27
|
-
|
|
28
|
-
# ---------------------------------------------------------------------------
|
|
29
|
-
# Resolve paths
|
|
30
|
-
# ---------------------------------------------------------------------------
|
|
31
|
-
$ScriptDir = Split-Path -Parent $PSCommandPath
|
|
32
|
-
$RepoRoot = Split-Path -Parent $ScriptDir
|
|
33
|
-
$OutputDir = Join-Path $RepoRoot 'generated'
|
|
34
|
-
$DefaultOut = Join-Path $OutputDir 'dbatools-help.json'
|
|
35
|
-
|
|
36
|
-
if ($OutputPath -eq "") { $OutputPath = $DefaultOut }
|
|
37
|
-
|
|
38
|
-
if (-not (Test-Path $OutputDir)) {
|
|
39
|
-
New-Item -ItemType Directory -Path $OutputDir | Out-Null
|
|
40
|
-
Write-Information "Created directory: $OutputDir"
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
# ---------------------------------------------------------------------------
|
|
44
|
-
# Verify dbatools
|
|
45
|
-
# ---------------------------------------------------------------------------
|
|
46
|
-
$module = Get-Module -ListAvailable -Name dbatools |
|
|
47
|
-
Sort-Object Version -Descending |
|
|
48
|
-
Select-Object -First 1
|
|
49
|
-
|
|
50
|
-
if (-not $module) {
|
|
51
|
-
Write-Error "dbatools is not installed.`nRun: Install-Module dbatools -Scope CurrentUser"
|
|
52
|
-
exit 1
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
Write-Information "Found dbatools $($module.Version) at $($module.ModuleBase)"
|
|
56
|
-
Write-Information "Importing module..."
|
|
57
|
-
Import-Module dbatools -ErrorAction Stop
|
|
58
|
-
|
|
59
|
-
# ---------------------------------------------------------------------------
|
|
60
|
-
# Enumerate commands
|
|
61
|
-
# ---------------------------------------------------------------------------
|
|
62
|
-
$commands = Get-Command -Module dbatools | Sort-Object Name
|
|
63
|
-
|
|
64
|
-
if ($MaxCommands -gt 0) {
|
|
65
|
-
$commands = $commands | Select-Object -First $MaxCommands
|
|
66
|
-
Write-Warning "MaxCommands=$MaxCommands — indexing a subset only."
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
$total = $commands.Count
|
|
70
|
-
Write-Information "Indexing $total commands..."
|
|
71
|
-
|
|
72
|
-
# ---------------------------------------------------------------------------
|
|
73
|
-
# Risk classification helpers
|
|
74
|
-
# ---------------------------------------------------------------------------
|
|
75
|
-
$ReadonlyVerbs = @('Get','Test','Find','Measure','Select','Show','Watch','Compare','Search','Resolve')
|
|
76
|
-
$DestructiveVerbs = @('Remove','Drop','Delete','Uninstall','Revoke','Disable','Reset')
|
|
77
|
-
|
|
78
|
-
function Get-RiskLevel([string]$verb) {
|
|
79
|
-
if ($ReadonlyVerbs -contains $verb) { return 'readonly' }
|
|
80
|
-
if ($DestructiveVerbs -contains $verb) { return 'destructive' }
|
|
81
|
-
return 'change'
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
# ---------------------------------------------------------------------------
|
|
85
|
-
# Help extraction loop
|
|
86
|
-
# ---------------------------------------------------------------------------
|
|
87
|
-
$index = [System.Collections.Specialized.OrderedDictionary]::new()
|
|
88
|
-
$failures = 0
|
|
89
|
-
$counter = 0
|
|
90
|
-
|
|
91
|
-
foreach ($cmd in $commands) {
|
|
92
|
-
$counter++
|
|
93
|
-
if ($counter % 100 -eq 0) {
|
|
94
|
-
Write-Information " $counter / $total ($([Math]::Round($counter/$total*100))%)"
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
try {
|
|
98
|
-
$help = Get-Help $cmd.Name -Full -ErrorAction SilentlyContinue
|
|
99
|
-
|
|
100
|
-
# --- Parameters ---------------------------------------------------
|
|
101
|
-
$params = [System.Collections.Generic.List[hashtable]]::new()
|
|
102
|
-
if ($help.parameters -and $help.parameters.parameter) {
|
|
103
|
-
foreach ($p in $help.parameters.parameter) {
|
|
104
|
-
$desc = if ($p.description) {
|
|
105
|
-
($p.description | ForEach-Object { $_.Text }) -join ' '
|
|
106
|
-
} else { '' }
|
|
107
|
-
|
|
108
|
-
$aliasArr = if ($p.aliases -and $p.aliases -ne 'None') {
|
|
109
|
-
@($p.aliases -split ',\s*' | Where-Object { $_ -ne '' })
|
|
110
|
-
} else { @() }
|
|
111
|
-
|
|
112
|
-
$params.Add([ordered]@{
|
|
113
|
-
name = [string]$p.name
|
|
114
|
-
type = if ($p.type -and $p.type.name) { [string]$p.type.name } else { 'Object' }
|
|
115
|
-
required = ($p.required -eq 'true')
|
|
116
|
-
aliases = $aliasArr
|
|
117
|
-
pipelineInput = ($p.pipelineInput -and $p.pipelineInput -ne 'false')
|
|
118
|
-
description = $desc.Trim()
|
|
119
|
-
defaultValue = if ($p.defaultValue) { [string]$p.defaultValue } else { $null }
|
|
120
|
-
})
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
# --- Examples -----------------------------------------------------
|
|
125
|
-
$examples = [System.Collections.Generic.List[hashtable]]::new()
|
|
126
|
-
if ($help.examples -and $help.examples.example) {
|
|
127
|
-
foreach ($ex in $help.examples.example) {
|
|
128
|
-
$remarks = if ($ex.remarks) {
|
|
129
|
-
($ex.remarks | ForEach-Object { $_.Text }) -join ' '
|
|
130
|
-
} else { '' }
|
|
131
|
-
|
|
132
|
-
$examples.Add([ordered]@{
|
|
133
|
-
title = ([string]($ex.title ?? '')).TrimStart('-').Trim()
|
|
134
|
-
code = ([string]($ex.code ?? '')).Trim()
|
|
135
|
-
remarks = $remarks.Trim()
|
|
136
|
-
})
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
# --- Related links ------------------------------------------------
|
|
141
|
-
$links = @()
|
|
142
|
-
if ($help.relatedLinks -and $help.relatedLinks.navigationLink) {
|
|
143
|
-
$links = @(
|
|
144
|
-
$help.relatedLinks.navigationLink |
|
|
145
|
-
ForEach-Object { if ($_.uri) { $_.uri } elseif ($_.linkText) { $_.linkText } } |
|
|
146
|
-
Where-Object { $_ -and $_ -ne '' }
|
|
147
|
-
)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
# --- Synopsis / Description ---------------------------------------
|
|
151
|
-
$synopsis = if ($help.Synopsis) { $help.Synopsis.Trim() } else { '' }
|
|
152
|
-
|
|
153
|
-
$description = if ($help.description) {
|
|
154
|
-
($help.description | ForEach-Object { $_.Text }) -join ' '
|
|
155
|
-
} else { '' }
|
|
156
|
-
|
|
157
|
-
$index[$cmd.Name] = [ordered]@{
|
|
158
|
-
name = $cmd.Name
|
|
159
|
-
verb = $cmd.Verb
|
|
160
|
-
noun = $cmd.Noun
|
|
161
|
-
synopsis = $synopsis
|
|
162
|
-
description = $description.Trim()
|
|
163
|
-
parameters = $params.ToArray()
|
|
164
|
-
examples = $examples.ToArray()
|
|
165
|
-
relatedLinks = $links
|
|
166
|
-
tags = @()
|
|
167
|
-
riskLevel = Get-RiskLevel $cmd.Verb
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
catch {
|
|
171
|
-
$failures++
|
|
172
|
-
Write-Warning "[$counter/$total] Failed to get help for $($cmd.Name): $_"
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
# ---------------------------------------------------------------------------
|
|
177
|
-
# Write manifest
|
|
178
|
-
# ---------------------------------------------------------------------------
|
|
179
|
-
$manifest = [ordered]@{
|
|
180
|
-
generatedAt = (Get-Date -Format 'o')
|
|
181
|
-
dbatoolsVersion = $module.Version.ToString()
|
|
182
|
-
commandCount = $index.Count
|
|
183
|
-
commands = $index
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
$manifest | ConvertTo-Json -Depth 12 | Set-Content -Path $OutputPath -Encoding UTF8
|
|
187
|
-
|
|
188
|
-
Write-Information ""
|
|
189
|
-
Write-Information "Done! Indexed $($index.Count) commands -> $OutputPath"
|
|
190
|
-
if ($failures -gt 0) {
|
|
191
|
-
Write-Warning "$failures command(s) failed to index (see warnings above)."
|
|
192
|
-
}
|
|
1
|
+
<#
|
|
2
|
+
.SYNOPSIS
|
|
3
|
+
Generates generated/dbatools-help.json by extracting comment-based help from
|
|
4
|
+
every command in the locally installed dbatools module.
|
|
5
|
+
|
|
6
|
+
.DESCRIPTION
|
|
7
|
+
Run this script whenever dbatools is installed or updated.
|
|
8
|
+
Output is consumed by the MCP server at startup and cached for the session.
|
|
9
|
+
|
|
10
|
+
Usage: npm run refresh-help
|
|
11
|
+
pwsh -File scripts/refresh-help.ps1
|
|
12
|
+
|
|
13
|
+
.PARAMETER OutputPath
|
|
14
|
+
Override the output file path (default: <repo-root>/generated/dbatools-help.json)
|
|
15
|
+
|
|
16
|
+
.PARAMETER MaxCommands
|
|
17
|
+
Limit to N commands for quick development iterations (0 = all commands)
|
|
18
|
+
#>
|
|
19
|
+
[CmdletBinding()]
|
|
20
|
+
param(
|
|
21
|
+
[string]$OutputPath = "",
|
|
22
|
+
[int]$MaxCommands = 0
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
$ErrorActionPreference = 'Stop'
|
|
26
|
+
$InformationPreference = 'Continue'
|
|
27
|
+
|
|
28
|
+
# ---------------------------------------------------------------------------
|
|
29
|
+
# Resolve paths
|
|
30
|
+
# ---------------------------------------------------------------------------
|
|
31
|
+
$ScriptDir = Split-Path -Parent $PSCommandPath
|
|
32
|
+
$RepoRoot = Split-Path -Parent $ScriptDir
|
|
33
|
+
$OutputDir = Join-Path $RepoRoot 'generated'
|
|
34
|
+
$DefaultOut = Join-Path $OutputDir 'dbatools-help.json'
|
|
35
|
+
|
|
36
|
+
if ($OutputPath -eq "") { $OutputPath = $DefaultOut }
|
|
37
|
+
|
|
38
|
+
if (-not (Test-Path $OutputDir)) {
|
|
39
|
+
New-Item -ItemType Directory -Path $OutputDir | Out-Null
|
|
40
|
+
Write-Information "Created directory: $OutputDir"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# ---------------------------------------------------------------------------
|
|
44
|
+
# Verify dbatools
|
|
45
|
+
# ---------------------------------------------------------------------------
|
|
46
|
+
$module = Get-Module -ListAvailable -Name dbatools |
|
|
47
|
+
Sort-Object Version -Descending |
|
|
48
|
+
Select-Object -First 1
|
|
49
|
+
|
|
50
|
+
if (-not $module) {
|
|
51
|
+
Write-Error "dbatools is not installed.`nRun: Install-Module dbatools -Scope CurrentUser"
|
|
52
|
+
exit 1
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
Write-Information "Found dbatools $($module.Version) at $($module.ModuleBase)"
|
|
56
|
+
Write-Information "Importing module..."
|
|
57
|
+
Import-Module dbatools -ErrorAction Stop
|
|
58
|
+
|
|
59
|
+
# ---------------------------------------------------------------------------
|
|
60
|
+
# Enumerate commands
|
|
61
|
+
# ---------------------------------------------------------------------------
|
|
62
|
+
$commands = Get-Command -Module dbatools | Sort-Object Name
|
|
63
|
+
|
|
64
|
+
if ($MaxCommands -gt 0) {
|
|
65
|
+
$commands = $commands | Select-Object -First $MaxCommands
|
|
66
|
+
Write-Warning "MaxCommands=$MaxCommands — indexing a subset only."
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
$total = $commands.Count
|
|
70
|
+
Write-Information "Indexing $total commands..."
|
|
71
|
+
|
|
72
|
+
# ---------------------------------------------------------------------------
|
|
73
|
+
# Risk classification helpers
|
|
74
|
+
# ---------------------------------------------------------------------------
|
|
75
|
+
$ReadonlyVerbs = @('Get','Test','Find','Measure','Select','Show','Watch','Compare','Search','Resolve')
|
|
76
|
+
$DestructiveVerbs = @('Remove','Drop','Delete','Uninstall','Revoke','Disable','Reset')
|
|
77
|
+
|
|
78
|
+
function Get-RiskLevel([string]$verb) {
|
|
79
|
+
if ($ReadonlyVerbs -contains $verb) { return 'readonly' }
|
|
80
|
+
if ($DestructiveVerbs -contains $verb) { return 'destructive' }
|
|
81
|
+
return 'change'
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
# ---------------------------------------------------------------------------
|
|
85
|
+
# Help extraction loop
|
|
86
|
+
# ---------------------------------------------------------------------------
|
|
87
|
+
$index = [System.Collections.Specialized.OrderedDictionary]::new()
|
|
88
|
+
$failures = 0
|
|
89
|
+
$counter = 0
|
|
90
|
+
|
|
91
|
+
foreach ($cmd in $commands) {
|
|
92
|
+
$counter++
|
|
93
|
+
if ($counter % 100 -eq 0) {
|
|
94
|
+
Write-Information " $counter / $total ($([Math]::Round($counter/$total*100))%)"
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
$help = Get-Help $cmd.Name -Full -ErrorAction SilentlyContinue
|
|
99
|
+
|
|
100
|
+
# --- Parameters ---------------------------------------------------
|
|
101
|
+
$params = [System.Collections.Generic.List[hashtable]]::new()
|
|
102
|
+
if ($help.parameters -and $help.parameters.parameter) {
|
|
103
|
+
foreach ($p in $help.parameters.parameter) {
|
|
104
|
+
$desc = if ($p.description) {
|
|
105
|
+
($p.description | ForEach-Object { $_.Text }) -join ' '
|
|
106
|
+
} else { '' }
|
|
107
|
+
|
|
108
|
+
$aliasArr = if ($p.aliases -and $p.aliases -ne 'None') {
|
|
109
|
+
@($p.aliases -split ',\s*' | Where-Object { $_ -ne '' })
|
|
110
|
+
} else { @() }
|
|
111
|
+
|
|
112
|
+
$params.Add([ordered]@{
|
|
113
|
+
name = [string]$p.name
|
|
114
|
+
type = if ($p.type -and $p.type.name) { [string]$p.type.name } else { 'Object' }
|
|
115
|
+
required = ($p.required -eq 'true')
|
|
116
|
+
aliases = $aliasArr
|
|
117
|
+
pipelineInput = ($p.pipelineInput -and $p.pipelineInput -ne 'false')
|
|
118
|
+
description = $desc.Trim()
|
|
119
|
+
defaultValue = if ($p.defaultValue) { [string]$p.defaultValue } else { $null }
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
# --- Examples -----------------------------------------------------
|
|
125
|
+
$examples = [System.Collections.Generic.List[hashtable]]::new()
|
|
126
|
+
if ($help.examples -and $help.examples.example) {
|
|
127
|
+
foreach ($ex in $help.examples.example) {
|
|
128
|
+
$remarks = if ($ex.remarks) {
|
|
129
|
+
($ex.remarks | ForEach-Object { $_.Text }) -join ' '
|
|
130
|
+
} else { '' }
|
|
131
|
+
|
|
132
|
+
$examples.Add([ordered]@{
|
|
133
|
+
title = ([string]($ex.title ?? '')).TrimStart('-').Trim()
|
|
134
|
+
code = ([string]($ex.code ?? '')).Trim()
|
|
135
|
+
remarks = $remarks.Trim()
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
# --- Related links ------------------------------------------------
|
|
141
|
+
$links = @()
|
|
142
|
+
if ($help.relatedLinks -and $help.relatedLinks.navigationLink) {
|
|
143
|
+
$links = @(
|
|
144
|
+
$help.relatedLinks.navigationLink |
|
|
145
|
+
ForEach-Object { if ($_.uri) { $_.uri } elseif ($_.linkText) { $_.linkText } } |
|
|
146
|
+
Where-Object { $_ -and $_ -ne '' }
|
|
147
|
+
)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
# --- Synopsis / Description ---------------------------------------
|
|
151
|
+
$synopsis = if ($help.Synopsis) { $help.Synopsis.Trim() } else { '' }
|
|
152
|
+
|
|
153
|
+
$description = if ($help.description) {
|
|
154
|
+
($help.description | ForEach-Object { $_.Text }) -join ' '
|
|
155
|
+
} else { '' }
|
|
156
|
+
|
|
157
|
+
$index[$cmd.Name] = [ordered]@{
|
|
158
|
+
name = $cmd.Name
|
|
159
|
+
verb = $cmd.Verb
|
|
160
|
+
noun = $cmd.Noun
|
|
161
|
+
synopsis = $synopsis
|
|
162
|
+
description = $description.Trim()
|
|
163
|
+
parameters = $params.ToArray()
|
|
164
|
+
examples = $examples.ToArray()
|
|
165
|
+
relatedLinks = $links
|
|
166
|
+
tags = @()
|
|
167
|
+
riskLevel = Get-RiskLevel $cmd.Verb
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
$failures++
|
|
172
|
+
Write-Warning "[$counter/$total] Failed to get help for $($cmd.Name): $_"
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
# ---------------------------------------------------------------------------
|
|
177
|
+
# Write manifest
|
|
178
|
+
# ---------------------------------------------------------------------------
|
|
179
|
+
$manifest = [ordered]@{
|
|
180
|
+
generatedAt = (Get-Date -Format 'o')
|
|
181
|
+
dbatoolsVersion = $module.Version.ToString()
|
|
182
|
+
commandCount = $index.Count
|
|
183
|
+
commands = $index
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
$manifest | ConvertTo-Json -Depth 12 | Set-Content -Path $OutputPath -Encoding UTF8
|
|
187
|
+
|
|
188
|
+
Write-Information ""
|
|
189
|
+
Write-Information "Done! Indexed $($index.Count) commands -> $OutputPath"
|
|
190
|
+
if ($failures -gt 0) {
|
|
191
|
+
Write-Warning "$failures command(s) failed to index (see warnings above)."
|
|
192
|
+
}
|