@postmcp/cli 0.1.25 → 0.1.27
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/dist/bin.js +146 -27
- package/dist/bin.js.map +1 -1
- package/dist/bin.mjs +148 -29
- package/dist/bin.mjs.map +1 -1
- package/dist/index.d.mts +8 -4
- package/dist/index.d.ts +8 -4
- package/dist/index.js +148 -25
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +146 -25
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -4
package/dist/bin.mjs
CHANGED
|
@@ -569,6 +569,15 @@ function getClientConfigPath(client) {
|
|
|
569
569
|
if (client === "cursor") {
|
|
570
570
|
return path4.join(process.cwd(), ".cursor", "mcp.json");
|
|
571
571
|
}
|
|
572
|
+
if (client === "opencode") {
|
|
573
|
+
return path4.join(process.cwd(), "opencode.json");
|
|
574
|
+
}
|
|
575
|
+
if (client === "claude-code") {
|
|
576
|
+
return path4.join(process.cwd(), ".mcp.json");
|
|
577
|
+
}
|
|
578
|
+
if (client === "codex") {
|
|
579
|
+
return path4.join(process.cwd(), ".codex", "config.toml");
|
|
580
|
+
}
|
|
572
581
|
if (client === "claude") {
|
|
573
582
|
if (process.platform === "darwin") {
|
|
574
583
|
return path4.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
@@ -586,6 +595,7 @@ function getClientConfigPath(client) {
|
|
|
586
595
|
function buildClientConfigSnippet(serverKey, specPath, options) {
|
|
587
596
|
const env = {};
|
|
588
597
|
if (options.bearer) {
|
|
598
|
+
env["BEARER_TOKEN"] = options.bearer;
|
|
589
599
|
env["API_KEY"] = options.bearer;
|
|
590
600
|
}
|
|
591
601
|
if (options.baseUrl) {
|
|
@@ -593,24 +603,87 @@ function buildClientConfigSnippet(serverKey, specPath, options) {
|
|
|
593
603
|
}
|
|
594
604
|
if (options.env) {
|
|
595
605
|
for (const e of options.env) {
|
|
596
|
-
const
|
|
597
|
-
if (
|
|
606
|
+
const eqIdx = e.indexOf("=");
|
|
607
|
+
if (eqIdx !== -1) {
|
|
608
|
+
const k = e.slice(0, eqIdx).trim();
|
|
609
|
+
const v = e.slice(eqIdx + 1).trim();
|
|
610
|
+
if (k) env[k] = v;
|
|
611
|
+
}
|
|
598
612
|
}
|
|
599
613
|
}
|
|
614
|
+
const targetSpecPath = specPath.startsWith("http://") || specPath.startsWith("https://") || specPath.startsWith("@") ? specPath : path4.resolve(process.cwd(), specPath);
|
|
600
615
|
return {
|
|
601
616
|
mcpServers: {
|
|
602
617
|
[serverKey]: {
|
|
603
618
|
command: "npx",
|
|
604
|
-
args: ["-y", "@postmcp/cli", "run",
|
|
619
|
+
args: ["-y", "@postmcp/cli", "run", targetSpecPath],
|
|
605
620
|
env: Object.keys(env).length > 0 ? env : void 0
|
|
606
621
|
}
|
|
607
622
|
}
|
|
608
623
|
};
|
|
609
624
|
}
|
|
625
|
+
function buildOpenCodeConfigSnippet(serverKey, specPath, options) {
|
|
626
|
+
const env = {};
|
|
627
|
+
if (options.bearer) {
|
|
628
|
+
env["BEARER_TOKEN"] = options.bearer;
|
|
629
|
+
}
|
|
630
|
+
if (options.baseUrl) {
|
|
631
|
+
env["BASE_URL"] = options.baseUrl;
|
|
632
|
+
}
|
|
633
|
+
if (options.env) {
|
|
634
|
+
for (const e of options.env) {
|
|
635
|
+
const eqIdx = e.indexOf("=");
|
|
636
|
+
if (eqIdx !== -1) {
|
|
637
|
+
const k = e.slice(0, eqIdx).trim();
|
|
638
|
+
const v = e.slice(eqIdx + 1).trim();
|
|
639
|
+
if (k) env[k] = v;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
const targetSpecPath = specPath.startsWith("http://") || specPath.startsWith("https://") || specPath.startsWith("@") ? specPath : path4.resolve(process.cwd(), specPath);
|
|
644
|
+
return {
|
|
645
|
+
$schema: "https://opencode.ai/config.json",
|
|
646
|
+
mcp: {
|
|
647
|
+
[serverKey]: {
|
|
648
|
+
type: "local",
|
|
649
|
+
enabled: true,
|
|
650
|
+
command: ["npx", "-y", "@postmcp/cli", "run", targetSpecPath],
|
|
651
|
+
environment: Object.keys(env).length > 0 ? env : void 0
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
function buildCodexTomlSnippet(serverKey, specPath, options) {
|
|
657
|
+
const env = {};
|
|
658
|
+
if (options.bearer) {
|
|
659
|
+
env["BEARER_TOKEN"] = options.bearer;
|
|
660
|
+
}
|
|
661
|
+
if (options.baseUrl) {
|
|
662
|
+
env["BASE_URL"] = options.baseUrl;
|
|
663
|
+
}
|
|
664
|
+
if (options.env) {
|
|
665
|
+
for (const e of options.env) {
|
|
666
|
+
const eqIdx = e.indexOf("=");
|
|
667
|
+
if (eqIdx !== -1) {
|
|
668
|
+
const k = e.slice(0, eqIdx).trim();
|
|
669
|
+
const v = e.slice(eqIdx + 1).trim();
|
|
670
|
+
if (k) env[k] = v;
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
const targetSpecPath = specPath.startsWith("http://") || specPath.startsWith("https://") || specPath.startsWith("@") ? specPath : path4.resolve(process.cwd(), specPath);
|
|
675
|
+
const envEntries = Object.entries(env).map(([k, v]) => `${k} = "${v}"`).join(", ");
|
|
676
|
+
const envLine = envEntries.length > 0 ? `
|
|
677
|
+
env = { ${envEntries} }` : "";
|
|
678
|
+
return `[mcp_servers.${serverKey}]
|
|
679
|
+
command = "npx"
|
|
680
|
+
args = ["-y", "@postmcp/cli", "run", "${targetSpecPath}"]${envLine}`;
|
|
681
|
+
}
|
|
682
|
+
var ALL_CLIENTS = ["cursor", "opencode", "claude-code", "codex", "claude", "windsurf"];
|
|
610
683
|
async function exportCommand(specArg, options) {
|
|
611
684
|
let specPath = specArg;
|
|
612
685
|
if (!specPath) {
|
|
613
|
-
console.error(pc4.red("Error: No OpenAPI spec provided. Usage: postmcp export <spec-path-or-url-or-@preset> --target cursor|claude|windsurf|all"));
|
|
686
|
+
console.error(pc4.red("Error: No OpenAPI spec provided. Usage: postmcp export <spec-path-or-url-or-@preset> --target cursor|opencode|claude-code|codex|claude|windsurf|all"));
|
|
614
687
|
process.exit(1);
|
|
615
688
|
}
|
|
616
689
|
let serverKey = "api-server";
|
|
@@ -625,39 +698,85 @@ async function exportCommand(specArg, options) {
|
|
|
625
698
|
}
|
|
626
699
|
}
|
|
627
700
|
const selectedTarget = (options.client || options.target || "all").toLowerCase();
|
|
628
|
-
const clientsToExport = selectedTarget === "all" ?
|
|
701
|
+
const clientsToExport = selectedTarget === "all" ? ALL_CLIENTS : [selectedTarget];
|
|
629
702
|
console.log(pc4.bold(pc4.cyan(`PostMCP 1-Click Client Configuration Exporter`)));
|
|
630
703
|
console.log();
|
|
631
704
|
for (const c of clientsToExport) {
|
|
632
705
|
const configPath = getClientConfigPath(c);
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
706
|
+
let formattedSnippet = "";
|
|
707
|
+
if (c === "opencode") {
|
|
708
|
+
const snippet = buildOpenCodeConfigSnippet(serverKey, specPath, options);
|
|
709
|
+
formattedSnippet = JSON.stringify(snippet, null, 2);
|
|
710
|
+
} else if (c === "codex") {
|
|
711
|
+
formattedSnippet = buildCodexTomlSnippet(serverKey, specPath, options);
|
|
712
|
+
} else {
|
|
713
|
+
const snippet = buildClientConfigSnippet(serverKey, specPath, options);
|
|
714
|
+
formattedSnippet = JSON.stringify(snippet, null, 2);
|
|
715
|
+
}
|
|
716
|
+
const isProjectLocal = ["cursor", "opencode", "claude-code", "codex"].includes(c);
|
|
717
|
+
console.log(pc4.bold(pc4.green(`\u25B6 ${c.toUpperCase()} (${isProjectLocal ? "Project Local" : "Global Client"})`)));
|
|
636
718
|
console.log(pc4.dim(` Config path: ${configPath}`));
|
|
637
719
|
console.log();
|
|
638
720
|
console.log(pc4.gray(formattedSnippet));
|
|
639
721
|
console.log();
|
|
640
722
|
if (options.write) {
|
|
641
723
|
try {
|
|
642
|
-
let existingConfig = {};
|
|
643
|
-
if (fs4.existsSync(configPath)) {
|
|
644
|
-
const raw = fs4.readFileSync(configPath, "utf-8");
|
|
645
|
-
try {
|
|
646
|
-
existingConfig = JSON.parse(raw);
|
|
647
|
-
} catch {
|
|
648
|
-
existingConfig = {};
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
existingConfig.mcpServers = existingConfig.mcpServers || {};
|
|
652
|
-
if (snippet.mcpServers?.[serverKey]) {
|
|
653
|
-
existingConfig.mcpServers[serverKey] = snippet.mcpServers[serverKey];
|
|
654
|
-
}
|
|
655
724
|
const parentDir = path4.dirname(configPath);
|
|
656
725
|
if (!fs4.existsSync(parentDir)) {
|
|
657
726
|
fs4.mkdirSync(parentDir, { recursive: true });
|
|
658
727
|
}
|
|
659
|
-
|
|
660
|
-
|
|
728
|
+
if (c === "codex") {
|
|
729
|
+
let content = "";
|
|
730
|
+
if (fs4.existsSync(configPath)) {
|
|
731
|
+
content = fs4.readFileSync(configPath, "utf-8");
|
|
732
|
+
}
|
|
733
|
+
if (!content.includes(`[mcp_servers.${serverKey}]`)) {
|
|
734
|
+
content = content ? `${content.trim()}
|
|
735
|
+
|
|
736
|
+
${formattedSnippet}
|
|
737
|
+
` : `${formattedSnippet}
|
|
738
|
+
`;
|
|
739
|
+
fs4.writeFileSync(configPath, content, "utf-8");
|
|
740
|
+
console.log(pc4.green(` Successfully appended to ${configPath}`));
|
|
741
|
+
} else {
|
|
742
|
+
console.log(pc4.yellow(` Server [mcp_servers.${serverKey}] already exists in ${configPath}`));
|
|
743
|
+
}
|
|
744
|
+
} else if (c === "opencode") {
|
|
745
|
+
let existingConfig = {};
|
|
746
|
+
if (fs4.existsSync(configPath)) {
|
|
747
|
+
try {
|
|
748
|
+
existingConfig = JSON.parse(fs4.readFileSync(configPath, "utf-8"));
|
|
749
|
+
} catch {
|
|
750
|
+
existingConfig = {};
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
existingConfig.$schema = existingConfig.$schema || "https://opencode.ai/config.json";
|
|
754
|
+
existingConfig.mcp = existingConfig.mcp || {};
|
|
755
|
+
const openCodeSnippet = buildOpenCodeConfigSnippet(serverKey, specPath, options);
|
|
756
|
+
const newMcp = openCodeSnippet.mcp?.[serverKey];
|
|
757
|
+
if (newMcp) {
|
|
758
|
+
existingConfig.mcp[serverKey] = newMcp;
|
|
759
|
+
}
|
|
760
|
+
fs4.writeFileSync(configPath, JSON.stringify(existingConfig, null, 2), "utf-8");
|
|
761
|
+
console.log(pc4.green(` Successfully merged and written to ${configPath}`));
|
|
762
|
+
} else {
|
|
763
|
+
let existingConfig = {};
|
|
764
|
+
if (fs4.existsSync(configPath)) {
|
|
765
|
+
const raw = fs4.readFileSync(configPath, "utf-8");
|
|
766
|
+
try {
|
|
767
|
+
existingConfig = JSON.parse(raw);
|
|
768
|
+
} catch {
|
|
769
|
+
existingConfig = {};
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
existingConfig.mcpServers = existingConfig.mcpServers || {};
|
|
773
|
+
const snippet = buildClientConfigSnippet(serverKey, specPath, options);
|
|
774
|
+
if (snippet.mcpServers?.[serverKey]) {
|
|
775
|
+
existingConfig.mcpServers[serverKey] = snippet.mcpServers[serverKey];
|
|
776
|
+
}
|
|
777
|
+
fs4.writeFileSync(configPath, JSON.stringify(existingConfig, null, 2), "utf-8");
|
|
778
|
+
console.log(pc4.green(` Successfully merged and written to ${configPath}`));
|
|
779
|
+
}
|
|
661
780
|
} catch (err) {
|
|
662
781
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
663
782
|
console.error(pc4.red(` Failed to write to ${configPath}: ${errMsg}`));
|
|
@@ -912,8 +1031,8 @@ async function studioCommand(specArg, options = {}) {
|
|
|
912
1031
|
}
|
|
913
1032
|
}
|
|
914
1033
|
if (child) {
|
|
915
|
-
await new Promise((
|
|
916
|
-
child?.on("close", () =>
|
|
1034
|
+
await new Promise((resolve6) => {
|
|
1035
|
+
child?.on("close", () => resolve6());
|
|
917
1036
|
});
|
|
918
1037
|
}
|
|
919
1038
|
}
|
|
@@ -947,15 +1066,15 @@ async function docsCommand(options = {}) {
|
|
|
947
1066
|
|
|
948
1067
|
// src/bin.ts
|
|
949
1068
|
import { readFileSync as readFileSync4 } from "fs";
|
|
950
|
-
import { resolve as
|
|
1069
|
+
import { resolve as resolve5 } from "path";
|
|
951
1070
|
import pc8 from "picocolors";
|
|
952
1071
|
function getCliVersion() {
|
|
953
1072
|
if (true) {
|
|
954
|
-
return "0.1.
|
|
1073
|
+
return "0.1.27";
|
|
955
1074
|
}
|
|
956
1075
|
try {
|
|
957
1076
|
const dir = typeof __dirname !== "undefined" ? __dirname : process.cwd();
|
|
958
|
-
const pkg = JSON.parse(readFileSync4(
|
|
1077
|
+
const pkg = JSON.parse(readFileSync4(resolve5(dir, "../package.json"), "utf8"));
|
|
959
1078
|
return pkg.version || "unknown";
|
|
960
1079
|
} catch {
|
|
961
1080
|
return "unknown";
|
|
@@ -982,7 +1101,7 @@ function createCli() {
|
|
|
982
1101
|
process.exit(1);
|
|
983
1102
|
});
|
|
984
1103
|
});
|
|
985
|
-
program.command("export <spec>").description("1-Click configuration exporter for Cursor, Claude Desktop, and Windsurf").option("-t, --target <name>", "Target client: cursor, claude, windsurf, or all").option("--client <name>", "Alias for --target").option("-w, --write", "Automatically merge and write configuration directly to the client config file on disk").option("--bearer <token>", "Bearer token for client configuration environment").option("-b, --base-url <url>", "Base URL override for client configuration environment").option("-e, --env <key=val...>", "Environment variables for client configuration", (val, prev = []) => [...prev, val]).action((spec, opts) => {
|
|
1104
|
+
program.command("export <spec>").description("1-Click configuration exporter for OpenCode, Claude Code, Codex, Cursor, Claude Desktop, and Windsurf").option("-t, --target <name>", "Target client: cursor, opencode, claude-code, codex, claude, windsurf, or all").option("--client <name>", "Alias for --target").option("-w, --write", "Automatically merge and write configuration directly to the client config file on disk").option("--bearer <token>", "Bearer token for client configuration environment").option("-b, --base-url <url>", "Base URL override for client configuration environment").option("-e, --env <key=val...>", "Environment variables for client configuration", (val, prev = []) => [...prev, val]).action((spec, opts) => {
|
|
986
1105
|
const target = opts.target || opts.client || "all";
|
|
987
1106
|
exportCommand(spec, { ...opts, target, client: target }).catch((err) => {
|
|
988
1107
|
console.error(pc8.red(`Fatal error: ${err.message}`));
|