mikromcp 1.0.0 → 1.0.2
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 +89 -67
- package/package.json +3 -3
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,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
// src/main.ts
|
|
4
4
|
import { config as loadDotenv } from "dotenv";
|
|
5
|
+
import { join as join3 } from "path";
|
|
6
|
+
import { homedir as homedir3 } from "os";
|
|
5
7
|
|
|
6
8
|
// src/cli/index.ts
|
|
7
9
|
import { Command } from "commander";
|
|
8
|
-
import { createRequire as createRequire2 } from "module";
|
|
9
10
|
|
|
10
11
|
// src/config/app-config.ts
|
|
11
12
|
function loadAppConfig() {
|
|
@@ -8605,7 +8606,7 @@ function createServerFactory(config, identityRegistry) {
|
|
|
8605
8606
|
const makeServer = () => {
|
|
8606
8607
|
const server = new McpServer({
|
|
8607
8608
|
name: "mikromcp",
|
|
8608
|
-
version: "1.0.
|
|
8609
|
+
version: "1.0.2"
|
|
8609
8610
|
});
|
|
8610
8611
|
registerAllTools(server, registry, pool, circuitBreakers, config, identityRegistry);
|
|
8611
8612
|
return server;
|
|
@@ -8927,10 +8928,8 @@ async function runServe() {
|
|
|
8927
8928
|
import { existsSync as existsSync3, readFileSync as readFileSync6 } from "fs";
|
|
8928
8929
|
import { homedir } from "os";
|
|
8929
8930
|
import * as net from "net";
|
|
8930
|
-
import { createRequire } from "module";
|
|
8931
8931
|
import chalk from "chalk";
|
|
8932
|
-
var
|
|
8933
|
-
var { version: localVersion } = require2("../../package.json");
|
|
8932
|
+
var localVersion = "1.0.2";
|
|
8934
8933
|
var results = [];
|
|
8935
8934
|
function ok(msg) {
|
|
8936
8935
|
console.log(chalk.green("\u2705 ") + msg);
|
|
@@ -9214,6 +9213,12 @@ import { join as join2 } from "path";
|
|
|
9214
9213
|
import { stringify as yamlStringify, parse as yamlParse } from "yaml";
|
|
9215
9214
|
import bcrypt2 from "bcryptjs";
|
|
9216
9215
|
import chalk2 from "chalk";
|
|
9216
|
+
function mikromcpDir() {
|
|
9217
|
+
return join2(homedir2(), ".mikromcp");
|
|
9218
|
+
}
|
|
9219
|
+
function defaultAuditLogPath() {
|
|
9220
|
+
return join2(mikromcpDir(), "audit.ndjson");
|
|
9221
|
+
}
|
|
9217
9222
|
function suggestEnvPrefix(routerId) {
|
|
9218
9223
|
return "ROUTER_" + routerId.toUpperCase().replace(/-/g, "_");
|
|
9219
9224
|
}
|
|
@@ -9231,17 +9236,6 @@ function findClaudeDesktopConfig() {
|
|
|
9231
9236
|
];
|
|
9232
9237
|
return candidates.find((p) => existsSync4(p)) ?? null;
|
|
9233
9238
|
}
|
|
9234
|
-
function appendToGitignore(projectRoot, entry) {
|
|
9235
|
-
const gitignorePath = join2(projectRoot, ".gitignore");
|
|
9236
|
-
if (existsSync4(gitignorePath)) {
|
|
9237
|
-
const content = readFileSync7(gitignorePath, "utf-8");
|
|
9238
|
-
if (!content.split("\n").some((line) => line.trim() === entry)) {
|
|
9239
|
-
writeFileSync2(gitignorePath, content.endsWith("\n") ? content + entry + "\n" : content + "\n" + entry + "\n");
|
|
9240
|
-
}
|
|
9241
|
-
} else {
|
|
9242
|
-
writeFileSync2(gitignorePath, entry + "\n");
|
|
9243
|
-
}
|
|
9244
|
-
}
|
|
9245
9239
|
async function collectRouterInfo() {
|
|
9246
9240
|
console.log(chalk2.bold("\n\u2500\u2500 Router configuration \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"));
|
|
9247
9241
|
const routerId = await input({
|
|
@@ -9249,19 +9243,20 @@ async function collectRouterInfo() {
|
|
|
9249
9243
|
validate: validateRouterId
|
|
9250
9244
|
});
|
|
9251
9245
|
const host = await input({
|
|
9252
|
-
message: "Host / IP (e.g. 192.168.
|
|
9246
|
+
message: "Host / IP (e.g. 192.168.88.1):",
|
|
9253
9247
|
validate: (v) => v.trim().length > 0 ? true : "Host is required"
|
|
9254
9248
|
});
|
|
9255
9249
|
const portStr = await input({
|
|
9256
9250
|
message: "Port:",
|
|
9257
|
-
default: "
|
|
9251
|
+
default: "443",
|
|
9258
9252
|
validate: (v) => {
|
|
9259
9253
|
const n = Number(v);
|
|
9260
9254
|
return Number.isInteger(n) && n >= 1 && n <= 65535 ? true : "Port must be 1\u201365535";
|
|
9261
9255
|
}
|
|
9262
9256
|
});
|
|
9263
9257
|
const port = Number(portStr);
|
|
9264
|
-
const
|
|
9258
|
+
const tlsDefault = port === 443 || port === 8443;
|
|
9259
|
+
const tlsEnabled = await confirm({ message: "Enable TLS?", default: tlsDefault });
|
|
9265
9260
|
let rejectUnauthorized = true;
|
|
9266
9261
|
if (tlsEnabled) {
|
|
9267
9262
|
rejectUnauthorized = await confirm({
|
|
@@ -9348,16 +9343,18 @@ async function collectIdentityInfo() {
|
|
|
9348
9343
|
tokenHash
|
|
9349
9344
|
};
|
|
9350
9345
|
}
|
|
9351
|
-
async function collectEnvPreference(
|
|
9352
|
-
|
|
9353
|
-
|
|
9346
|
+
async function collectEnvPreference() {
|
|
9347
|
+
return confirm({
|
|
9348
|
+
message: "Write credentials to ~/.mikromcp/.env? (No = inject env vars at runtime)",
|
|
9349
|
+
default: true
|
|
9350
|
+
});
|
|
9354
9351
|
}
|
|
9355
9352
|
async function collectClaudeDesktopPreference() {
|
|
9356
9353
|
console.log(chalk2.bold("\n\u2500\u2500 Claude Desktop integration \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"));
|
|
9357
9354
|
return confirm({ message: "Register with Claude Desktop?", default: true });
|
|
9358
9355
|
}
|
|
9359
|
-
function writeRoutersYaml(data
|
|
9360
|
-
const filePath = join2(configDir, "routers.yaml");
|
|
9356
|
+
function writeRoutersYaml(data) {
|
|
9357
|
+
const filePath = join2(data.configDir, "routers.yaml");
|
|
9361
9358
|
const newEntry = {
|
|
9362
9359
|
host: data.host,
|
|
9363
9360
|
port: data.port,
|
|
@@ -9379,12 +9376,12 @@ function writeRoutersYaml(data, configDir) {
|
|
|
9379
9376
|
if (!parsed.routers) parsed.routers = {};
|
|
9380
9377
|
}
|
|
9381
9378
|
parsed.routers[data.routerId] = newEntry;
|
|
9382
|
-
mkdirSync3(configDir, { recursive: true });
|
|
9379
|
+
mkdirSync3(data.configDir, { recursive: true });
|
|
9383
9380
|
writeFileSync2(filePath, yamlStringify(parsed, { lineWidth: 0 }));
|
|
9384
9381
|
return true;
|
|
9385
9382
|
}
|
|
9386
|
-
function writeIdentitiesYaml(data
|
|
9387
|
-
const filePath = join2(configDir, "identities.yaml");
|
|
9383
|
+
function writeIdentitiesYaml(data) {
|
|
9384
|
+
const filePath = join2(data.configDir, "identities.yaml");
|
|
9388
9385
|
const newEntry = {
|
|
9389
9386
|
token: data.tokenHash,
|
|
9390
9387
|
role: data.role,
|
|
@@ -9398,32 +9395,55 @@ function writeIdentitiesYaml(data, configDir) {
|
|
|
9398
9395
|
if (!parsed.identities) parsed.identities = {};
|
|
9399
9396
|
}
|
|
9400
9397
|
parsed.identities[data.identityId] = newEntry;
|
|
9401
|
-
mkdirSync3(configDir, { recursive: true });
|
|
9398
|
+
mkdirSync3(data.configDir, { recursive: true });
|
|
9402
9399
|
writeFileSync2(filePath, yamlStringify(parsed, { lineWidth: 0 }));
|
|
9403
9400
|
return true;
|
|
9404
9401
|
}
|
|
9405
|
-
function writeDotEnv(data
|
|
9406
|
-
const envPath = join2(projectRoot, ".env");
|
|
9407
|
-
const lines = [];
|
|
9408
|
-
lines.push(`ROUTER_${data.envPrefix.replace(/^ROUTER_/, "")}_USER=`);
|
|
9409
|
-
lines.push(`ROUTER_${data.envPrefix.replace(/^ROUTER_/, "")}_PASS=`);
|
|
9402
|
+
function writeDotEnv(data) {
|
|
9410
9403
|
const userKey = `${data.envPrefix}_USER`;
|
|
9411
9404
|
const passKey = `${data.envPrefix}_PASS`;
|
|
9412
|
-
|
|
9413
|
-
|
|
9414
|
-
|
|
9415
|
-
|
|
9416
|
-
|
|
9417
|
-
|
|
9418
|
-
|
|
9419
|
-
|
|
9405
|
+
const auditLogPath = defaultAuditLogPath();
|
|
9406
|
+
const transport2 = data.createIdentity ? "http" : "stdio";
|
|
9407
|
+
const confirmationSecret = data.createIdentity ? randomBytes(32).toString("hex") : "";
|
|
9408
|
+
const lines = [
|
|
9409
|
+
"# \u2500\u2500 Router credentials \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",
|
|
9410
|
+
`${userKey}=`,
|
|
9411
|
+
`${passKey}=`,
|
|
9412
|
+
"",
|
|
9413
|
+
"# \u2500\u2500 Transport \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",
|
|
9414
|
+
`# stdio \u2192 launched directly by Claude Desktop or another MCP client`,
|
|
9415
|
+
`# http \u2192 standalone server mode with bearer-token auth`,
|
|
9416
|
+
`MIKROMCP_TRANSPORT=${transport2}`,
|
|
9417
|
+
"",
|
|
9418
|
+
"# \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=${join2(data.configDir, "routers.yaml")}`,
|
|
9420
|
+
`MIKROMCP_IDENTITIES_PATH=${join2(data.configDir, "identities.yaml")}`,
|
|
9421
|
+
"",
|
|
9422
|
+
"# \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
|
+
"# Levels: trace | debug | info | warn | error",
|
|
9424
|
+
"MIKROMCP_LOG_LEVEL=info",
|
|
9425
|
+
`MIKROMCP_AUDIT_LOG_PATH=${auditLogPath}`,
|
|
9426
|
+
"",
|
|
9427
|
+
"# \u2500\u2500 HTTP transport (only used when MIKROMCP_TRANSPORT=http) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
9428
|
+
"MIKROMCP_PORT=3000",
|
|
9429
|
+
`MIKROMCP_CONFIRMATION_SECRET=${confirmationSecret}`,
|
|
9430
|
+
"",
|
|
9431
|
+
"# \u2500\u2500 RBAC (optional, for stdio with identity enforcement) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
9432
|
+
"# MIKROMCP_STDIO_IDENTITY="
|
|
9433
|
+
];
|
|
9434
|
+
const content = lines.join("\n") + "\n";
|
|
9435
|
+
mkdirSync3(data.configDir, { recursive: true });
|
|
9436
|
+
if (existsSync4(data.envPath)) {
|
|
9437
|
+
const existing = readFileSync7(data.envPath, "utf-8");
|
|
9438
|
+
writeFileSync2(data.envPath, existing.endsWith("\n") ? existing + "\n" + content : existing + "\n\n" + content);
|
|
9420
9439
|
} else {
|
|
9421
|
-
writeFileSync2(envPath,
|
|
9440
|
+
writeFileSync2(data.envPath, content);
|
|
9422
9441
|
}
|
|
9423
|
-
|
|
9424
|
-
|
|
9442
|
+
console.log(
|
|
9443
|
+
chalk2.dim(` Fill in ${userKey} and ${passKey} in ${data.envPath}`)
|
|
9444
|
+
);
|
|
9425
9445
|
}
|
|
9426
|
-
function registerClaudeDesktop(
|
|
9446
|
+
function registerClaudeDesktop() {
|
|
9427
9447
|
const configPath = findClaudeDesktopConfig();
|
|
9428
9448
|
const entry = {
|
|
9429
9449
|
command: "mikromcp",
|
|
@@ -9455,17 +9475,17 @@ function registerClaudeDesktop(_projectRoot) {
|
|
|
9455
9475
|
}
|
|
9456
9476
|
async function runInit() {
|
|
9457
9477
|
console.log(chalk2.bold.cyan("\n\u{1F527} MikroMCP \u2014 Interactive Setup Wizard\n"));
|
|
9458
|
-
const projectRoot = process.cwd();
|
|
9459
|
-
const configDir = join2(projectRoot, "config");
|
|
9460
9478
|
const routerInfo = await collectRouterInfo();
|
|
9461
9479
|
const identityInfo = await collectIdentityInfo();
|
|
9462
|
-
const
|
|
9480
|
+
const configDir = mikromcpDir();
|
|
9481
|
+
const envPath = join2(configDir, ".env");
|
|
9482
|
+
const writeEnv = await collectEnvPreference();
|
|
9463
9483
|
let writeRouters = true;
|
|
9464
9484
|
const routersYamlPath = join2(configDir, "routers.yaml");
|
|
9465
9485
|
if (existsSync4(routersYamlPath)) {
|
|
9466
9486
|
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"));
|
|
9467
9487
|
writeRouters = await confirm({
|
|
9468
|
-
message: "
|
|
9488
|
+
message: "routers.yaml already exists. Add this router to it?",
|
|
9469
9489
|
default: true
|
|
9470
9490
|
});
|
|
9471
9491
|
}
|
|
@@ -9473,6 +9493,8 @@ async function runInit() {
|
|
|
9473
9493
|
const data = {
|
|
9474
9494
|
...routerInfo,
|
|
9475
9495
|
...identityInfo,
|
|
9496
|
+
envPath,
|
|
9497
|
+
configDir,
|
|
9476
9498
|
writeEnv,
|
|
9477
9499
|
writeRoutersYaml: writeRouters,
|
|
9478
9500
|
writeIdentitiesYaml: identityInfo.createIdentity,
|
|
@@ -9481,23 +9503,23 @@ async function runInit() {
|
|
|
9481
9503
|
console.log(chalk2.bold("\n\u2500\u2500 Writing 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"));
|
|
9482
9504
|
const summary = [];
|
|
9483
9505
|
if (data.writeRoutersYaml) {
|
|
9484
|
-
writeRoutersYaml(data
|
|
9485
|
-
summary.push(`
|
|
9486
|
-
console.log(chalk2.green(
|
|
9506
|
+
writeRoutersYaml(data);
|
|
9507
|
+
summary.push(`routers.yaml written to ${data.configDir}`);
|
|
9508
|
+
console.log(chalk2.green(` \u2714 ${join2(data.configDir, "routers.yaml")}`));
|
|
9487
9509
|
}
|
|
9488
9510
|
if (data.writeIdentitiesYaml) {
|
|
9489
|
-
writeIdentitiesYaml(data
|
|
9490
|
-
summary.push(`
|
|
9491
|
-
console.log(chalk2.green(
|
|
9511
|
+
writeIdentitiesYaml(data);
|
|
9512
|
+
summary.push(`identities.yaml written to ${data.configDir}`);
|
|
9513
|
+
console.log(chalk2.green(` \u2714 ${join2(data.configDir, "identities.yaml")}`));
|
|
9492
9514
|
}
|
|
9493
9515
|
if (data.writeEnv) {
|
|
9494
|
-
writeDotEnv(data
|
|
9495
|
-
summary.push(`.env
|
|
9496
|
-
console.log(chalk2.green(
|
|
9516
|
+
writeDotEnv(data);
|
|
9517
|
+
summary.push(`.env written to ${data.envPath}`);
|
|
9518
|
+
console.log(chalk2.green(` \u2714 ${data.envPath}`));
|
|
9497
9519
|
}
|
|
9498
9520
|
let desktopRegistered = false;
|
|
9499
9521
|
if (data.registerClaudeDesktop) {
|
|
9500
|
-
const result = registerClaudeDesktop(
|
|
9522
|
+
const result = registerClaudeDesktop();
|
|
9501
9523
|
desktopRegistered = result.registered;
|
|
9502
9524
|
if (desktopRegistered) {
|
|
9503
9525
|
summary.push("Claude Desktop registered");
|
|
@@ -9509,24 +9531,24 @@ async function runInit() {
|
|
|
9509
9531
|
console.log(chalk2.green(` \u2705 ${item}`));
|
|
9510
9532
|
}
|
|
9511
9533
|
if (data.createIdentity && data.rawToken) {
|
|
9512
|
-
console.log(
|
|
9534
|
+
console.log(
|
|
9535
|
+
chalk2.bold.yellow(` \u2705 Bearer token: ${data.rawToken} (save this \u2014 it won't be shown again)`)
|
|
9536
|
+
);
|
|
9513
9537
|
}
|
|
9514
9538
|
console.log(chalk2.bold("\nNext steps:"));
|
|
9515
|
-
console.log(chalk2.dim(` 1.
|
|
9516
|
-
console.log(chalk2.dim(" 2. Run:
|
|
9517
|
-
console.log(chalk2.dim(" 3.
|
|
9539
|
+
console.log(chalk2.dim(` 1. Fill in router credentials in ${data.envPath}`));
|
|
9540
|
+
console.log(chalk2.dim(" 2. Run: mikromcp doctor"));
|
|
9541
|
+
console.log(chalk2.dim(" 3. Restart Claude Desktop to load the MCP server"));
|
|
9518
9542
|
console.log();
|
|
9519
9543
|
}
|
|
9520
9544
|
|
|
9521
9545
|
// src/cli/index.ts
|
|
9522
|
-
var
|
|
9523
|
-
var { version } = require3("../../package.json");
|
|
9524
|
-
var program = new Command().name("mikromcp").description("MikroTik RouterOS MCP server").version(version);
|
|
9546
|
+
var program = new Command().name("mikromcp").description("MikroTik RouterOS MCP server").version("1.0.2");
|
|
9525
9547
|
program.command("serve", { isDefault: true }).description("Start the MCP server (default)").action(runServe);
|
|
9526
9548
|
program.command("doctor").description("Check config, connectivity, and permissions").action(runDoctor);
|
|
9527
9549
|
program.command("init").description("Interactive setup wizard").action(runInit);
|
|
9528
9550
|
|
|
9529
9551
|
// src/main.ts
|
|
9530
|
-
loadDotenv({ override: false });
|
|
9552
|
+
loadDotenv({ path: join3(homedir3(), ".mikromcp", ".env"), override: false });
|
|
9531
9553
|
program.parse();
|
|
9532
9554
|
//# sourceMappingURL=main.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mikromcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Production-grade MCP server for MikroTik RouterOS",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"dev": "tsx watch src/main.ts",
|
|
20
20
|
"build": "tsup",
|
|
21
21
|
"clean": "rm -rf dist",
|
|
22
|
-
"test": "vitest run",
|
|
22
|
+
"test": "vitest run && tsc --noEmit && eslint src/",
|
|
23
23
|
"test:watch": "vitest",
|
|
24
24
|
"lint": "eslint src/",
|
|
25
25
|
"format": "prettier --write 'src/**/*.ts' 'test/**/*.ts'",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
],
|
|
39
39
|
"repository": {
|
|
40
40
|
"type": "git",
|
|
41
|
-
"url": "https://github.com/AliKarami/MikroMCP"
|
|
41
|
+
"url": "git+https://github.com/AliKarami/MikroMCP.git"
|
|
42
42
|
},
|
|
43
43
|
"author": "Ali Karami",
|
|
44
44
|
"license": "MIT",
|