mikromcp 1.0.2 → 1.0.3
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 +1 -1
- package/dist/main.js +42 -35
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
[](https://github.com/AliKarami/MikroMCP/actions/workflows/ci.yml)
|
|
14
14
|
[](https://github.com/AliKarami/MikroMCP/actions/workflows/release.yml)
|
|
15
|
-
[](package.json)
|
|
16
16
|
[](LICENSE)
|
|
17
17
|
[](package.json)
|
|
18
18
|
[](https://help.mikrotik.com/docs/display/ROS/REST+API)
|
package/dist/main.js
CHANGED
|
@@ -2,28 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
// src/main.ts
|
|
4
4
|
import { config as loadDotenv } from "dotenv";
|
|
5
|
-
import { join as
|
|
6
|
-
import { homedir as
|
|
5
|
+
import { join as join5 } from "path";
|
|
6
|
+
import { homedir as homedir5 } from "os";
|
|
7
7
|
|
|
8
8
|
// src/cli/index.ts
|
|
9
9
|
import { Command } from "commander";
|
|
10
10
|
|
|
11
11
|
// src/config/app-config.ts
|
|
12
|
+
import { join } from "path";
|
|
13
|
+
import { homedir } from "os";
|
|
14
|
+
function mikromcpDir() {
|
|
15
|
+
return join(homedir(), ".mikromcp");
|
|
16
|
+
}
|
|
12
17
|
function loadAppConfig() {
|
|
13
18
|
const env = process.env;
|
|
14
|
-
const dataDir = env.MIKROMCP_DATA_DIR ?? "data";
|
|
19
|
+
const dataDir = env.MIKROMCP_DATA_DIR ?? join(mikromcpDir(), "data");
|
|
15
20
|
return {
|
|
16
21
|
transport: env.MIKROMCP_TRANSPORT === "http" ? "http" : "stdio",
|
|
17
22
|
port: parseInt(env.MIKROMCP_PORT ?? "3000", 10),
|
|
18
23
|
bindHost: env.MIKROMCP_BIND_HOST ?? "127.0.0.1",
|
|
19
24
|
logLevel: env.MIKROMCP_LOG_LEVEL ?? "info",
|
|
20
|
-
configPath: env.MIKROMCP_CONFIG_PATH ?? "
|
|
25
|
+
configPath: env.MIKROMCP_CONFIG_PATH ?? join(mikromcpDir(), "routers.yaml"),
|
|
21
26
|
dataDir,
|
|
22
27
|
snapshotDir: `${dataDir}/snapshots`,
|
|
23
28
|
journalPath: `${dataDir}/write-journal.ndjson`,
|
|
24
29
|
cmdAllow: (env.MIKROMCP_CMD_ALLOW ?? "").split(",").map((s) => s.trim()).filter(Boolean),
|
|
25
30
|
cmdDeny: (env.MIKROMCP_CMD_DENY ?? "").split(",").map((s) => s.trim()).filter(Boolean),
|
|
26
|
-
identitiesPath: env.MIKROMCP_IDENTITIES_PATH ?? "
|
|
31
|
+
identitiesPath: env.MIKROMCP_IDENTITIES_PATH ?? join(mikromcpDir(), "identities.yaml"),
|
|
27
32
|
stdioIdentity: env.MIKROMCP_STDIO_IDENTITY || void 0,
|
|
28
33
|
confirmationSecret: env.MIKROMCP_CONFIRMATION_SECRET || void 0,
|
|
29
34
|
auditLogPath: env.MIKROMCP_AUDIT_LOG_PATH || void 0,
|
|
@@ -4900,10 +4905,12 @@ var containerTools = [listContainersTool, manageContainerTool];
|
|
|
4900
4905
|
// src/domain/tools/change-management-tools.ts
|
|
4901
4906
|
import { z as z23 } from "zod";
|
|
4902
4907
|
import { readFileSync as readFileSync2 } from "fs";
|
|
4908
|
+
import { join as join3 } from "path";
|
|
4909
|
+
import { homedir as homedir2 } from "os";
|
|
4903
4910
|
|
|
4904
4911
|
// src/domain/snapshot/snapshot-engine.ts
|
|
4905
4912
|
import { mkdirSync, writeFileSync, readFileSync } from "fs";
|
|
4906
|
-
import { join } from "path";
|
|
4913
|
+
import { join as join2 } from "path";
|
|
4907
4914
|
import { nanoid } from "nanoid";
|
|
4908
4915
|
function pathToSlug(rosPath) {
|
|
4909
4916
|
return rosPath.replace(/\//g, "-");
|
|
@@ -4914,8 +4921,8 @@ function timestampPrefix() {
|
|
|
4914
4921
|
async function takeSnapshot(client, routerId, path, snapshotDir) {
|
|
4915
4922
|
const records = await client.get(path, {});
|
|
4916
4923
|
const id = `${timestampPrefix()}-${pathToSlug(path)}-${nanoid(6)}`;
|
|
4917
|
-
const dir =
|
|
4918
|
-
const filePath =
|
|
4924
|
+
const dir = join2(snapshotDir, routerId);
|
|
4925
|
+
const filePath = join2(dir, `${id}.json`);
|
|
4919
4926
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
4920
4927
|
mkdirSync(dir, { recursive: true });
|
|
4921
4928
|
const stored = { id, routerId, path, ts, records };
|
|
@@ -5177,7 +5184,7 @@ function createChangeManagementTools(baseTools2) {
|
|
|
5177
5184
|
async handler(params, context) {
|
|
5178
5185
|
const parsed = applyPlanInputSchema.parse(params);
|
|
5179
5186
|
log24.info({ routerId: context.routerId, stepCount: parsed.steps.length }, "Applying plan");
|
|
5180
|
-
const dataDir = process.env.MIKROMCP_DATA_DIR ?? "data";
|
|
5187
|
+
const dataDir = process.env.MIKROMCP_DATA_DIR ?? join3(homedir2(), ".mikromcp", "data");
|
|
5181
5188
|
const journalPath = `${dataDir}/write-journal.ndjson`;
|
|
5182
5189
|
const snapshotDir = `${dataDir}/snapshots`;
|
|
5183
5190
|
const results2 = [];
|
|
@@ -5271,7 +5278,7 @@ function createChangeManagementTools(baseTools2) {
|
|
|
5271
5278
|
},
|
|
5272
5279
|
async handler(params, context) {
|
|
5273
5280
|
const parsed = rollbackChangeInputSchema.parse(params);
|
|
5274
|
-
const dataDir = process.env.MIKROMCP_DATA_DIR ?? "data";
|
|
5281
|
+
const dataDir = process.env.MIKROMCP_DATA_DIR ?? join3(homedir2(), ".mikromcp", "data");
|
|
5275
5282
|
const journalPath = `${dataDir}/write-journal.ndjson`;
|
|
5276
5283
|
const snapshotDir = `${dataDir}/snapshots`;
|
|
5277
5284
|
log24.info({ routerId: context.routerId, journalId: parsed.journalId }, "Rolling back change");
|
|
@@ -7935,7 +7942,7 @@ function getStdioIdentity(stdioIdentityName, registry) {
|
|
|
7935
7942
|
details: { stdioIdentityName },
|
|
7936
7943
|
recoverability: {
|
|
7937
7944
|
retryable: false,
|
|
7938
|
-
suggestedAction: `Add an identity named "${stdioIdentityName}" to
|
|
7945
|
+
suggestedAction: `Add an identity named "${stdioIdentityName}" to ~/.mikromcp/identities.yaml or unset MIKROMCP_STDIO_IDENTITY.`
|
|
7939
7946
|
}
|
|
7940
7947
|
});
|
|
7941
7948
|
}
|
|
@@ -8606,7 +8613,7 @@ function createServerFactory(config, identityRegistry) {
|
|
|
8606
8613
|
const makeServer = () => {
|
|
8607
8614
|
const server = new McpServer({
|
|
8608
8615
|
name: "mikromcp",
|
|
8609
|
-
version: "1.0.
|
|
8616
|
+
version: "1.0.3"
|
|
8610
8617
|
});
|
|
8611
8618
|
registerAllTools(server, registry, pool, circuitBreakers, config, identityRegistry);
|
|
8612
8619
|
return server;
|
|
@@ -8926,10 +8933,10 @@ async function runServe() {
|
|
|
8926
8933
|
|
|
8927
8934
|
// src/cli/doctor.ts
|
|
8928
8935
|
import { existsSync as existsSync3, readFileSync as readFileSync6 } from "fs";
|
|
8929
|
-
import { homedir } from "os";
|
|
8936
|
+
import { homedir as homedir3 } from "os";
|
|
8930
8937
|
import * as net from "net";
|
|
8931
8938
|
import chalk from "chalk";
|
|
8932
|
-
var localVersion = "1.0.
|
|
8939
|
+
var localVersion = "1.0.3";
|
|
8933
8940
|
var results = [];
|
|
8934
8941
|
function ok(msg) {
|
|
8935
8942
|
console.log(chalk.green("\u2705 ") + msg);
|
|
@@ -9085,7 +9092,7 @@ async function checkRouter(router) {
|
|
|
9085
9092
|
}
|
|
9086
9093
|
}
|
|
9087
9094
|
function checkIdentities(identitiesPath, transport2) {
|
|
9088
|
-
if (!process.env.MIKROMCP_IDENTITIES_PATH && identitiesPath
|
|
9095
|
+
if (!process.env.MIKROMCP_IDENTITIES_PATH && identitiesPath.endsWith(".mikromcp/identities.yaml")) {
|
|
9089
9096
|
if (!existsSync3(identitiesPath)) {
|
|
9090
9097
|
return;
|
|
9091
9098
|
}
|
|
@@ -9109,8 +9116,8 @@ function checkIdentities(identitiesPath, transport2) {
|
|
|
9109
9116
|
}
|
|
9110
9117
|
function checkClaudeDesktop() {
|
|
9111
9118
|
const candidatePaths = [
|
|
9112
|
-
`${
|
|
9113
|
-
`${
|
|
9119
|
+
`${homedir3()}/Library/Application Support/Claude/claude_desktop_config.json`,
|
|
9120
|
+
`${homedir3()}/.config/Claude/claude_desktop_config.json`
|
|
9114
9121
|
];
|
|
9115
9122
|
const configPath = candidatePaths.find((p) => existsSync3(p));
|
|
9116
9123
|
if (!configPath) {
|
|
@@ -9208,16 +9215,16 @@ import {
|
|
|
9208
9215
|
mkdirSync as mkdirSync3,
|
|
9209
9216
|
copyFileSync
|
|
9210
9217
|
} from "fs";
|
|
9211
|
-
import { homedir as
|
|
9212
|
-
import { join as
|
|
9218
|
+
import { homedir as homedir4 } from "os";
|
|
9219
|
+
import { join as join4 } from "path";
|
|
9213
9220
|
import { stringify as yamlStringify, parse as yamlParse } from "yaml";
|
|
9214
9221
|
import bcrypt2 from "bcryptjs";
|
|
9215
9222
|
import chalk2 from "chalk";
|
|
9216
|
-
function
|
|
9217
|
-
return
|
|
9223
|
+
function mikromcpDir2() {
|
|
9224
|
+
return join4(homedir4(), ".mikromcp");
|
|
9218
9225
|
}
|
|
9219
9226
|
function defaultAuditLogPath() {
|
|
9220
|
-
return
|
|
9227
|
+
return join4(mikromcpDir2(), "audit.ndjson");
|
|
9221
9228
|
}
|
|
9222
9229
|
function suggestEnvPrefix(routerId) {
|
|
9223
9230
|
return "ROUTER_" + routerId.toUpperCase().replace(/-/g, "_");
|
|
@@ -9231,8 +9238,8 @@ function splitTags(val) {
|
|
|
9231
9238
|
}
|
|
9232
9239
|
function findClaudeDesktopConfig() {
|
|
9233
9240
|
const candidates = [
|
|
9234
|
-
|
|
9235
|
-
|
|
9241
|
+
join4(homedir4(), "Library", "Application Support", "Claude", "claude_desktop_config.json"),
|
|
9242
|
+
join4(homedir4(), ".config", "Claude", "claude_desktop_config.json")
|
|
9236
9243
|
];
|
|
9237
9244
|
return candidates.find((p) => existsSync4(p)) ?? null;
|
|
9238
9245
|
}
|
|
@@ -9354,7 +9361,7 @@ async function collectClaudeDesktopPreference() {
|
|
|
9354
9361
|
return confirm({ message: "Register with Claude Desktop?", default: true });
|
|
9355
9362
|
}
|
|
9356
9363
|
function writeRoutersYaml(data) {
|
|
9357
|
-
const filePath =
|
|
9364
|
+
const filePath = join4(data.configDir, "routers.yaml");
|
|
9358
9365
|
const newEntry = {
|
|
9359
9366
|
host: data.host,
|
|
9360
9367
|
port: data.port,
|
|
@@ -9381,7 +9388,7 @@ function writeRoutersYaml(data) {
|
|
|
9381
9388
|
return true;
|
|
9382
9389
|
}
|
|
9383
9390
|
function writeIdentitiesYaml(data) {
|
|
9384
|
-
const filePath =
|
|
9391
|
+
const filePath = join4(data.configDir, "identities.yaml");
|
|
9385
9392
|
const newEntry = {
|
|
9386
9393
|
token: data.tokenHash,
|
|
9387
9394
|
role: data.role,
|
|
@@ -9416,8 +9423,8 @@ function writeDotEnv(data) {
|
|
|
9416
9423
|
`MIKROMCP_TRANSPORT=${transport2}`,
|
|
9417
9424
|
"",
|
|
9418
9425
|
"# \u2500\u2500 Config paths \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
9419
|
-
`MIKROMCP_CONFIG_PATH=${
|
|
9420
|
-
`MIKROMCP_IDENTITIES_PATH=${
|
|
9426
|
+
`MIKROMCP_CONFIG_PATH=${join4(data.configDir, "routers.yaml")}`,
|
|
9427
|
+
`MIKROMCP_IDENTITIES_PATH=${join4(data.configDir, "identities.yaml")}`,
|
|
9421
9428
|
"",
|
|
9422
9429
|
"# \u2500\u2500 Logging \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
9423
9430
|
"# Levels: trace | debug | info | warn | error",
|
|
@@ -9477,11 +9484,11 @@ async function runInit() {
|
|
|
9477
9484
|
console.log(chalk2.bold.cyan("\n\u{1F527} MikroMCP \u2014 Interactive Setup Wizard\n"));
|
|
9478
9485
|
const routerInfo = await collectRouterInfo();
|
|
9479
9486
|
const identityInfo = await collectIdentityInfo();
|
|
9480
|
-
const configDir =
|
|
9481
|
-
const envPath =
|
|
9487
|
+
const configDir = mikromcpDir2();
|
|
9488
|
+
const envPath = join4(configDir, ".env");
|
|
9482
9489
|
const writeEnv = await collectEnvPreference();
|
|
9483
9490
|
let writeRouters = true;
|
|
9484
|
-
const routersYamlPath =
|
|
9491
|
+
const routersYamlPath = join4(configDir, "routers.yaml");
|
|
9485
9492
|
if (existsSync4(routersYamlPath)) {
|
|
9486
9493
|
console.log(chalk2.bold("\n\u2500\u2500 Config files \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
9487
9494
|
writeRouters = await confirm({
|
|
@@ -9505,12 +9512,12 @@ async function runInit() {
|
|
|
9505
9512
|
if (data.writeRoutersYaml) {
|
|
9506
9513
|
writeRoutersYaml(data);
|
|
9507
9514
|
summary.push(`routers.yaml written to ${data.configDir}`);
|
|
9508
|
-
console.log(chalk2.green(` \u2714 ${
|
|
9515
|
+
console.log(chalk2.green(` \u2714 ${join4(data.configDir, "routers.yaml")}`));
|
|
9509
9516
|
}
|
|
9510
9517
|
if (data.writeIdentitiesYaml) {
|
|
9511
9518
|
writeIdentitiesYaml(data);
|
|
9512
9519
|
summary.push(`identities.yaml written to ${data.configDir}`);
|
|
9513
|
-
console.log(chalk2.green(` \u2714 ${
|
|
9520
|
+
console.log(chalk2.green(` \u2714 ${join4(data.configDir, "identities.yaml")}`));
|
|
9514
9521
|
}
|
|
9515
9522
|
if (data.writeEnv) {
|
|
9516
9523
|
writeDotEnv(data);
|
|
@@ -9543,12 +9550,12 @@ async function runInit() {
|
|
|
9543
9550
|
}
|
|
9544
9551
|
|
|
9545
9552
|
// src/cli/index.ts
|
|
9546
|
-
var program = new Command().name("mikromcp").description("MikroTik RouterOS MCP server").version("1.0.
|
|
9553
|
+
var program = new Command().name("mikromcp").description("MikroTik RouterOS MCP server").version("1.0.3");
|
|
9547
9554
|
program.command("serve", { isDefault: true }).description("Start the MCP server (default)").action(runServe);
|
|
9548
9555
|
program.command("doctor").description("Check config, connectivity, and permissions").action(runDoctor);
|
|
9549
9556
|
program.command("init").description("Interactive setup wizard").action(runInit);
|
|
9550
9557
|
|
|
9551
9558
|
// src/main.ts
|
|
9552
|
-
loadDotenv({ path:
|
|
9559
|
+
loadDotenv({ path: join5(homedir5(), ".mikromcp", ".env"), override: false });
|
|
9553
9560
|
program.parse();
|
|
9554
9561
|
//# sourceMappingURL=main.js.map
|