mcp-for-i 0.1.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/README.md +53 -0
- package/dist/config/store.js +365 -0
- package/dist/controlplane/autostart.js +93 -0
- package/dist/controlplane/connectionService.js +79 -0
- package/dist/controlplane/index.js +120 -0
- package/dist/controlplane/runtimeService.js +263 -0
- package/dist/controlplane/server.js +180 -0
- package/dist/controlplane/ui.js +741 -0
- package/dist/ibmi/CompileTools.js +91 -0
- package/dist/ibmi/IBMiContent.js +386 -0
- package/dist/ibmi/LocalLanguageActions.js +183 -0
- package/dist/ibmi/Search.js +135 -0
- package/dist/ibmi/Tools.js +188 -0
- package/dist/ibmi/client.js +213 -0
- package/dist/ibmi/sourceDates.js +60 -0
- package/dist/ibmi/types.js +1 -0
- package/dist/ibmi/variables.js +53 -0
- package/dist/index.js +59 -0
- package/dist/mcp/context.js +235 -0
- package/dist/mcp/logger.js +73 -0
- package/dist/mcp/tools.js +1335 -0
- package/dist/mcp/validation.js +74 -0
- package/dist/security/credentialStore.js +42 -0
- package/docs/configuration.md +57 -0
- package/docs/examples.md +73 -0
- package/docs/installation.md +61 -0
- package/docs/overview.md +14 -0
- package/docs/security.md +8 -0
- package/docs/tools.md +105 -0
- package/package.json +49 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export function validateToolInput(schema, value) {
|
|
2
|
+
const errors = [];
|
|
3
|
+
validateNode(schema, value, "$", errors);
|
|
4
|
+
return errors;
|
|
5
|
+
}
|
|
6
|
+
function validateNode(schema, value, path, errors) {
|
|
7
|
+
if (!matchesType(schema.type, value)) {
|
|
8
|
+
const typeText = Array.isArray(schema.type) ? schema.type.join("|") : schema.type || "unknown";
|
|
9
|
+
errors.push(`${path} must be ${typeText}`);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
if (schema.enum && !schema.enum.includes(value)) {
|
|
13
|
+
errors.push(`${path} must be one of: ${schema.enum.map(v => JSON.stringify(v)).join(", ")}`);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (isObjectSchema(schema, value)) {
|
|
17
|
+
const obj = value;
|
|
18
|
+
for (const key of schema.required || []) {
|
|
19
|
+
if (!(key in obj) || obj[key] === undefined) {
|
|
20
|
+
errors.push(`${path}.${key} is required`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (schema.additionalProperties === false && schema.properties) {
|
|
24
|
+
for (const key of Object.keys(obj)) {
|
|
25
|
+
if (!(key in schema.properties)) {
|
|
26
|
+
errors.push(`${path}.${key} is not allowed`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (schema.properties) {
|
|
31
|
+
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
32
|
+
if (obj[key] !== undefined) {
|
|
33
|
+
validateNode(propSchema, obj[key], `${path}.${key}`, errors);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (Array.isArray(value) && schema.items) {
|
|
39
|
+
value.forEach((entry, idx) => validateNode(schema.items, entry, `${path}[${idx}]`, errors));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function isObjectSchema(schema, value) {
|
|
43
|
+
const types = toTypes(schema.type);
|
|
44
|
+
return types.includes("object") && isPlainObject(value);
|
|
45
|
+
}
|
|
46
|
+
function matchesType(type, value) {
|
|
47
|
+
if (!type)
|
|
48
|
+
return true;
|
|
49
|
+
const accepted = toTypes(type);
|
|
50
|
+
return accepted.some(t => isType(t, value));
|
|
51
|
+
}
|
|
52
|
+
function toTypes(type) {
|
|
53
|
+
if (!type)
|
|
54
|
+
return [];
|
|
55
|
+
return Array.isArray(type) ? type : [type];
|
|
56
|
+
}
|
|
57
|
+
function isType(type, value) {
|
|
58
|
+
if (type === "string")
|
|
59
|
+
return typeof value === "string";
|
|
60
|
+
if (type === "number")
|
|
61
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
62
|
+
if (type === "boolean")
|
|
63
|
+
return typeof value === "boolean";
|
|
64
|
+
if (type === "array")
|
|
65
|
+
return Array.isArray(value);
|
|
66
|
+
if (type === "object")
|
|
67
|
+
return isPlainObject(value);
|
|
68
|
+
if (type === "null")
|
|
69
|
+
return value === null;
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
function isPlainObject(value) {
|
|
73
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
74
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const SERVICE = "mcp-for-i";
|
|
2
|
+
const sessionStore = new Map();
|
|
3
|
+
let keytar;
|
|
4
|
+
async function getKeytar() {
|
|
5
|
+
if (keytar !== undefined)
|
|
6
|
+
return keytar;
|
|
7
|
+
try {
|
|
8
|
+
const mod = await import("keytar");
|
|
9
|
+
keytar = mod.default || mod;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
keytar = null;
|
|
13
|
+
}
|
|
14
|
+
return keytar;
|
|
15
|
+
}
|
|
16
|
+
export async function setPassword(connectionName, password) {
|
|
17
|
+
const kt = await getKeytar();
|
|
18
|
+
if (kt) {
|
|
19
|
+
await kt.setPassword(SERVICE, connectionName, password);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
sessionStore.set(connectionName, password);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export async function getPassword(connectionName) {
|
|
26
|
+
const kt = await getKeytar();
|
|
27
|
+
if (kt) {
|
|
28
|
+
return kt.getPassword(SERVICE, connectionName);
|
|
29
|
+
}
|
|
30
|
+
return sessionStore.get(connectionName);
|
|
31
|
+
}
|
|
32
|
+
export async function deletePassword(connectionName) {
|
|
33
|
+
const kt = await getKeytar();
|
|
34
|
+
if (kt) {
|
|
35
|
+
await kt.deletePassword(SERVICE, connectionName);
|
|
36
|
+
}
|
|
37
|
+
sessionStore.delete(connectionName);
|
|
38
|
+
}
|
|
39
|
+
export async function isKeychainAvailable() {
|
|
40
|
+
const kt = await getKeytar();
|
|
41
|
+
return Boolean(kt);
|
|
42
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
Config file is stored under the user config directory:
|
|
4
|
+
- Windows: `%APPDATA%\mcp-for-i\config.json`
|
|
5
|
+
- macOS: `~/Library/Application Support/mcp-for-i/config.json`
|
|
6
|
+
- Linux: `${XDG_CONFIG_HOME:-~/.config}/mcp-for-i/config.json`
|
|
7
|
+
|
|
8
|
+
## Settings
|
|
9
|
+
Default settings (editable in the config file):
|
|
10
|
+
- `readOnlyMode`: boolean
|
|
11
|
+
- `tempLibrary`: string
|
|
12
|
+
- `tempDir`: string
|
|
13
|
+
- `autoClearTempData`: boolean
|
|
14
|
+
- `sourceFileCCSID`: string (default `*FILE`)
|
|
15
|
+
- `enableSourceDates`: boolean (Phase 2+)
|
|
16
|
+
- `homeDirectory`: string
|
|
17
|
+
- `libraryList`: string[]
|
|
18
|
+
- `currentLibrary`: string
|
|
19
|
+
- `customVariables`: list of `{ name, value }`
|
|
20
|
+
|
|
21
|
+
## Connections
|
|
22
|
+
Connections are stored without passwords. Passwords are stored in OS keychain (or in-session fallback). Each connection can include optional `settings` overrides.
|
|
23
|
+
Connections can also define policy, for example:
|
|
24
|
+
- `read-only`
|
|
25
|
+
- `guarded` (default; approvals required for risky operations)
|
|
26
|
+
- `power-user`
|
|
27
|
+
|
|
28
|
+
Example:
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"connections": [
|
|
32
|
+
{
|
|
33
|
+
"name": "DEV400",
|
|
34
|
+
"host": "dev400.myco.com",
|
|
35
|
+
"port": 22,
|
|
36
|
+
"username": "DEVUSER",
|
|
37
|
+
"privateKeyPath": "C:/keys/id_rsa",
|
|
38
|
+
"settings": {
|
|
39
|
+
"readOnlyMode": false
|
|
40
|
+
},
|
|
41
|
+
"policy": {
|
|
42
|
+
"profile": "guarded",
|
|
43
|
+
"requireApprovalFor": ["sql.write", "cl.run", "deploy.sync"]
|
|
44
|
+
},
|
|
45
|
+
"profiles": [
|
|
46
|
+
{
|
|
47
|
+
"name": "projectA",
|
|
48
|
+
"currentLibrary": "PROJALIB",
|
|
49
|
+
"libraryList": ["QSYS", "QGPL", "PROJALIB"],
|
|
50
|
+
"customVariables": [{ "name": "ENV", "value": "DEV" }]
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"currentProfile": "projectA"
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
```
|
package/docs/examples.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
## Add connection profile
|
|
4
|
+
```json
|
|
5
|
+
{
|
|
6
|
+
"tool": "ibmi.connections.add",
|
|
7
|
+
"arguments": {
|
|
8
|
+
"name": "DEV400",
|
|
9
|
+
"host": "dev400.myco.com",
|
|
10
|
+
"port": 22,
|
|
11
|
+
"username": "DEVUSER",
|
|
12
|
+
"password": "*****",
|
|
13
|
+
"storePassword": true,
|
|
14
|
+
"policy": { "profile": "guarded" }
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Connect by saved name
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"tool": "ibmi.connect",
|
|
23
|
+
"arguments": { "name": "DEV400" }
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## List libraries
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"tool": "ibmi.qsys.libraries.list",
|
|
31
|
+
"arguments": { "filter": "*ALL" }
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Read a member
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"tool": "ibmi.qsys.members.read",
|
|
39
|
+
"arguments": {
|
|
40
|
+
"library": "MYLIB",
|
|
41
|
+
"sourceFile": "QRPGLESRC",
|
|
42
|
+
"member": "MYPGM"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Run an action
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"tool": "ibmi.actions.run",
|
|
51
|
+
"arguments": {
|
|
52
|
+
"actionName": "Create RPGLE Program",
|
|
53
|
+
"targetType": "member",
|
|
54
|
+
"targetPath": "MYLIB/QRPGLESRC/MYPGM",
|
|
55
|
+
"library": "MYLIB",
|
|
56
|
+
"sourceFile": "QRPGLESRC",
|
|
57
|
+
"member": "MYPGM",
|
|
58
|
+
"extension": "RPGLE"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Activate a profile
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"tool": "ibmi.profiles.activate",
|
|
67
|
+
"arguments": {
|
|
68
|
+
"connectionName": "DEV400",
|
|
69
|
+
"name": "projectA",
|
|
70
|
+
"applyToJob": true
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Installation
|
|
2
|
+
|
|
3
|
+
## Prerequisites
|
|
4
|
+
- Node.js 18+ recommended
|
|
5
|
+
- IBM i SSH access (22)
|
|
6
|
+
- On Linux: `libsecret` (for keychain via `keytar`)
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
1. Clone or copy this repo
|
|
10
|
+
2. Install dependencies:
|
|
11
|
+
- `npm install`
|
|
12
|
+
3. Build:
|
|
13
|
+
- `npm run build`
|
|
14
|
+
4. Run:
|
|
15
|
+
- `node dist/index.js`
|
|
16
|
+
|
|
17
|
+
## Control Plane UI (Onboarding + Updates)
|
|
18
|
+
Run local control plane:
|
|
19
|
+
|
|
20
|
+
- `npm run start:controlplane`
|
|
21
|
+
|
|
22
|
+
Open:
|
|
23
|
+
|
|
24
|
+
- `http://127.0.0.1:3980`
|
|
25
|
+
|
|
26
|
+
Use the UI to add/edit/delete/rename connections, manage keychain passwords, and run MCP/skills update actions.
|
|
27
|
+
|
|
28
|
+
## MCP (stdio) usage
|
|
29
|
+
Configure your MCP client (e.g., Codex CLI) to run `mcp-for-i` via stdio. Example (pseudo-config):
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"mcpServers": {
|
|
34
|
+
"mcp-for-i": {
|
|
35
|
+
"command": "mcp-for-i"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
If you run from source, use:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"command": "node",
|
|
46
|
+
"args": ["C:/Users/pgmashish/projects/mcp/mcp-for-i/dist/index.js"]
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Logging (opt‑in)
|
|
51
|
+
Logging is **disabled by default**. Enable it via env vars or CLI flags:
|
|
52
|
+
|
|
53
|
+
- Env flags:
|
|
54
|
+
- `MCP_FOR_I_LOG_ENABLED=1`
|
|
55
|
+
- `MCP_FOR_I_LOG` = path to log file
|
|
56
|
+
- `MCP_FOR_I_LOG_LEVEL` = `error|warn|info|debug` (default `info`)
|
|
57
|
+
- `MCP_FOR_I_LOG_STDERR=1` to log to stderr (set `0` to disable)
|
|
58
|
+
- CLI flags (when running `node dist/index.js` directly):
|
|
59
|
+
- `--log` (stderr, info level)
|
|
60
|
+
- `--log-level=debug`
|
|
61
|
+
- `--log-file=C:/path/to/log.txt`
|
package/docs/overview.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# MCP-for-i Overview
|
|
2
|
+
|
|
3
|
+
MCP-for-i is a local MCP server that exposes IBM i operations as MCP tools. It mirrors the core capabilities of the Code for IBM i VS Code extension but is designed for agent-driven workflows (e.g., Codex CLI) over MCP stdio.
|
|
4
|
+
|
|
5
|
+
Key capabilities (Phase 1):
|
|
6
|
+
- Connect/disconnect to IBM i
|
|
7
|
+
- Keep multiple sessions warm with inactivity timeout
|
|
8
|
+
- Browse libraries/objects/members
|
|
9
|
+
- Read/write members and IFS files
|
|
10
|
+
- Run compile actions (RPG/COBOL/C/CL/SQL)
|
|
11
|
+
- Search members and IFS
|
|
12
|
+
- Run guarded SQL and CL tools
|
|
13
|
+
|
|
14
|
+
The server runs locally and connects to IBM i via SSH + QSH/PASE + SQL (QZDFMDB2).
|
package/docs/security.md
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Security
|
|
2
|
+
|
|
3
|
+
- Credentials are stored in OS keychain via `keytar` (Windows Credential Manager, macOS Keychain, Linux libsecret).
|
|
4
|
+
- If keychain is unavailable, credentials are stored in memory for the current session only.
|
|
5
|
+
- Passwords are never written to the config file.
|
|
6
|
+
- `readOnlyMode` prevents write operations on members/IFS.
|
|
7
|
+
- Connection policies support `read-only`, `guarded`, and `power-user` modes.
|
|
8
|
+
- Guarded mode requires `approve: true` for configured risky operations.
|
package/docs/tools.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Tools
|
|
2
|
+
|
|
3
|
+
## Connection
|
|
4
|
+
- `ibmi.connect`
|
|
5
|
+
- `ibmi.disconnect`
|
|
6
|
+
- `ibmi.session.list`
|
|
7
|
+
- `ibmi.session.status`
|
|
8
|
+
- `ibmi.session.keepalive`
|
|
9
|
+
- `ibmi.session.terminate`
|
|
10
|
+
- `ibmi.connections.list`
|
|
11
|
+
- `ibmi.connections.add`
|
|
12
|
+
- `ibmi.connections.update`
|
|
13
|
+
- `ibmi.connections.delete`
|
|
14
|
+
|
|
15
|
+
## QSYS / Members
|
|
16
|
+
- `ibmi.qsys.libraries.list`
|
|
17
|
+
- `ibmi.qsys.objects.list`
|
|
18
|
+
- `ibmi.qsys.sourcefiles.list`
|
|
19
|
+
- `ibmi.qsys.members.list`
|
|
20
|
+
- `ibmi.qsys.members.read`
|
|
21
|
+
- `ibmi.qsys.members.write`
|
|
22
|
+
- `ibmi.qsys.members.create`
|
|
23
|
+
- `ibmi.qsys.members.rename`
|
|
24
|
+
- `ibmi.qsys.members.delete`
|
|
25
|
+
- `ibmi.qsys.sourcefiles.create`
|
|
26
|
+
- `ibmi.qsys.libraries.create`
|
|
27
|
+
|
|
28
|
+
## IFS
|
|
29
|
+
- `ibmi.ifs.list`
|
|
30
|
+
- `ibmi.ifs.read`
|
|
31
|
+
- `ibmi.ifs.write`
|
|
32
|
+
- `ibmi.ifs.mkdir`
|
|
33
|
+
- `ibmi.ifs.delete`
|
|
34
|
+
- `ibmi.ifs.upload`
|
|
35
|
+
- `ibmi.ifs.download`
|
|
36
|
+
|
|
37
|
+
## Search
|
|
38
|
+
- `ibmi.search.members`
|
|
39
|
+
- `ibmi.search.ifs`
|
|
40
|
+
- `ibmi.find.ifs`
|
|
41
|
+
|
|
42
|
+
## Actions
|
|
43
|
+
- `ibmi.actions.list`
|
|
44
|
+
- `ibmi.actions.run`
|
|
45
|
+
- `ibmi.actions.save`
|
|
46
|
+
- `ibmi.actions.delete`
|
|
47
|
+
|
|
48
|
+
## Library List
|
|
49
|
+
- `ibmi.libl.get`
|
|
50
|
+
- `ibmi.libl.set`
|
|
51
|
+
- `ibmi.libl.add`
|
|
52
|
+
- `ibmi.libl.remove`
|
|
53
|
+
- `ibmi.libl.setCurrent`
|
|
54
|
+
- `ibmi.libl.validate`
|
|
55
|
+
|
|
56
|
+
## Profiles
|
|
57
|
+
- `ibmi.profiles.list`
|
|
58
|
+
- `ibmi.profiles.save`
|
|
59
|
+
- `ibmi.profiles.delete`
|
|
60
|
+
- `ibmi.profiles.activate`
|
|
61
|
+
|
|
62
|
+
## Resolve
|
|
63
|
+
- `ibmi.resolve.path`
|
|
64
|
+
|
|
65
|
+
## Deploy
|
|
66
|
+
- `ibmi.deploy.uploadDirectory`
|
|
67
|
+
- `ibmi.deploy.uploadFiles`
|
|
68
|
+
- `ibmi.deploy.setCcsid`
|
|
69
|
+
- `ibmi.deploy.compare`
|
|
70
|
+
- `ibmi.deploy.sync`
|
|
71
|
+
|
|
72
|
+
## Filters
|
|
73
|
+
- `ibmi.filters.list`
|
|
74
|
+
- `ibmi.filters.save`
|
|
75
|
+
- `ibmi.filters.delete`
|
|
76
|
+
|
|
77
|
+
## IFS Shortcuts
|
|
78
|
+
- `ibmi.ifs.shortcuts.list`
|
|
79
|
+
- `ibmi.ifs.shortcuts.add`
|
|
80
|
+
- `ibmi.ifs.shortcuts.delete`
|
|
81
|
+
|
|
82
|
+
## Debug
|
|
83
|
+
- `ibmi.debug.status`
|
|
84
|
+
- `ibmi.debug.startService`
|
|
85
|
+
- `ibmi.debug.stopService`
|
|
86
|
+
|
|
87
|
+
## SQL / CL
|
|
88
|
+
- `ibmi.sql.query`
|
|
89
|
+
- `ibmi.sql.execute`
|
|
90
|
+
- `ibmi.cl.run`
|
|
91
|
+
|
|
92
|
+
## Diagnostics / Ops
|
|
93
|
+
- `ibmi.diagnostics.parseEvfevent`
|
|
94
|
+
- `ibmi.joblog.get`
|
|
95
|
+
- `ibmi.spool.list`
|
|
96
|
+
- `ibmi.spool.read`
|
|
97
|
+
|
|
98
|
+
## TN5250 (Scaffold)
|
|
99
|
+
- `ibmi.tn5250.connect`
|
|
100
|
+
- `ibmi.tn5250.readScreen`
|
|
101
|
+
- `ibmi.tn5250.setField`
|
|
102
|
+
- `ibmi.tn5250.sendKeys`
|
|
103
|
+
- `ibmi.tn5250.waitFor`
|
|
104
|
+
- `ibmi.tn5250.snapshot`
|
|
105
|
+
- `ibmi.tn5250.disconnect`
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mcp-for-i",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Local MCP server and control plane for IBM i workflows",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"homepage": "https://github.com/ashishthomas-pcr/mcp-for-i",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/ashishthomas-pcr/mcp-for-i.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/ashishthomas-pcr/mcp-for-i/issues"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md",
|
|
18
|
+
"docs"
|
|
19
|
+
],
|
|
20
|
+
"bin": {
|
|
21
|
+
"mcp-for-i": "dist/index.js",
|
|
22
|
+
"mcp-for-i-control": "dist/controlplane/index.js"
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"prepack": "npm run build",
|
|
26
|
+
"build": "tsc -p tsconfig.json",
|
|
27
|
+
"start": "node dist/index.js",
|
|
28
|
+
"start:controlplane": "node dist/controlplane/index.js",
|
|
29
|
+
"dev": "ts-node src/index.ts",
|
|
30
|
+
"dev:controlplane": "ts-node src/controlplane/index.ts",
|
|
31
|
+
"test": "npm run build && node --test test/tools.test.mjs test/variables.test.mjs test/validation.test.mjs test/config.migration.test.mjs",
|
|
32
|
+
"test:all": "npm run build && node --test test/*.mjs",
|
|
33
|
+
"test:ibmi": "npm run build && node --test test/ibmi.integration.test.mjs",
|
|
34
|
+
"test:mcp": "npm run build && node --test test/mcp.integration.test.mjs"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
38
|
+
"diff": "^5.2.0",
|
|
39
|
+
"keytar": "^7.9.0",
|
|
40
|
+
"node-ssh": "^13.1.0",
|
|
41
|
+
"zod-to-json-schema": "^3.23.2"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/diff": "^7.0.2",
|
|
45
|
+
"dotenv": "^17.2.3",
|
|
46
|
+
"ts-node": "^10.9.0",
|
|
47
|
+
"typescript": "^5.4.0"
|
|
48
|
+
}
|
|
49
|
+
}
|