@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 CHANGED
@@ -596,6 +596,15 @@ function getClientConfigPath(client) {
596
596
  if (client === "cursor") {
597
597
  return path4.join(process.cwd(), ".cursor", "mcp.json");
598
598
  }
599
+ if (client === "opencode") {
600
+ return path4.join(process.cwd(), "opencode.json");
601
+ }
602
+ if (client === "claude-code") {
603
+ return path4.join(process.cwd(), ".mcp.json");
604
+ }
605
+ if (client === "codex") {
606
+ return path4.join(process.cwd(), ".codex", "config.toml");
607
+ }
599
608
  if (client === "claude") {
600
609
  if (process.platform === "darwin") {
601
610
  return path4.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
@@ -613,6 +622,7 @@ function getClientConfigPath(client) {
613
622
  function buildClientConfigSnippet(serverKey, specPath, options) {
614
623
  const env = {};
615
624
  if (options.bearer) {
625
+ env["BEARER_TOKEN"] = options.bearer;
616
626
  env["API_KEY"] = options.bearer;
617
627
  }
618
628
  if (options.baseUrl) {
@@ -620,24 +630,87 @@ function buildClientConfigSnippet(serverKey, specPath, options) {
620
630
  }
621
631
  if (options.env) {
622
632
  for (const e of options.env) {
623
- const [k, v] = e.split("=");
624
- if (k && v) env[k] = v;
633
+ const eqIdx = e.indexOf("=");
634
+ if (eqIdx !== -1) {
635
+ const k = e.slice(0, eqIdx).trim();
636
+ const v = e.slice(eqIdx + 1).trim();
637
+ if (k) env[k] = v;
638
+ }
625
639
  }
626
640
  }
641
+ const targetSpecPath = specPath.startsWith("http://") || specPath.startsWith("https://") || specPath.startsWith("@") ? specPath : path4.resolve(process.cwd(), specPath);
627
642
  return {
628
643
  mcpServers: {
629
644
  [serverKey]: {
630
645
  command: "npx",
631
- args: ["-y", "@postmcp/cli", "run", specPath],
646
+ args: ["-y", "@postmcp/cli", "run", targetSpecPath],
632
647
  env: Object.keys(env).length > 0 ? env : void 0
633
648
  }
634
649
  }
635
650
  };
636
651
  }
652
+ function buildOpenCodeConfigSnippet(serverKey, specPath, options) {
653
+ const env = {};
654
+ if (options.bearer) {
655
+ env["BEARER_TOKEN"] = options.bearer;
656
+ }
657
+ if (options.baseUrl) {
658
+ env["BASE_URL"] = options.baseUrl;
659
+ }
660
+ if (options.env) {
661
+ for (const e of options.env) {
662
+ const eqIdx = e.indexOf("=");
663
+ if (eqIdx !== -1) {
664
+ const k = e.slice(0, eqIdx).trim();
665
+ const v = e.slice(eqIdx + 1).trim();
666
+ if (k) env[k] = v;
667
+ }
668
+ }
669
+ }
670
+ const targetSpecPath = specPath.startsWith("http://") || specPath.startsWith("https://") || specPath.startsWith("@") ? specPath : path4.resolve(process.cwd(), specPath);
671
+ return {
672
+ $schema: "https://opencode.ai/config.json",
673
+ mcp: {
674
+ [serverKey]: {
675
+ type: "local",
676
+ enabled: true,
677
+ command: ["npx", "-y", "@postmcp/cli", "run", targetSpecPath],
678
+ environment: Object.keys(env).length > 0 ? env : void 0
679
+ }
680
+ }
681
+ };
682
+ }
683
+ function buildCodexTomlSnippet(serverKey, specPath, options) {
684
+ const env = {};
685
+ if (options.bearer) {
686
+ env["BEARER_TOKEN"] = options.bearer;
687
+ }
688
+ if (options.baseUrl) {
689
+ env["BASE_URL"] = options.baseUrl;
690
+ }
691
+ if (options.env) {
692
+ for (const e of options.env) {
693
+ const eqIdx = e.indexOf("=");
694
+ if (eqIdx !== -1) {
695
+ const k = e.slice(0, eqIdx).trim();
696
+ const v = e.slice(eqIdx + 1).trim();
697
+ if (k) env[k] = v;
698
+ }
699
+ }
700
+ }
701
+ const targetSpecPath = specPath.startsWith("http://") || specPath.startsWith("https://") || specPath.startsWith("@") ? specPath : path4.resolve(process.cwd(), specPath);
702
+ const envEntries = Object.entries(env).map(([k, v]) => `${k} = "${v}"`).join(", ");
703
+ const envLine = envEntries.length > 0 ? `
704
+ env = { ${envEntries} }` : "";
705
+ return `[mcp_servers.${serverKey}]
706
+ command = "npx"
707
+ args = ["-y", "@postmcp/cli", "run", "${targetSpecPath}"]${envLine}`;
708
+ }
709
+ var ALL_CLIENTS = ["cursor", "opencode", "claude-code", "codex", "claude", "windsurf"];
637
710
  async function exportCommand(specArg, options) {
638
711
  let specPath = specArg;
639
712
  if (!specPath) {
640
- console.error(import_picocolors4.default.red("Error: No OpenAPI spec provided. Usage: postmcp export <spec-path-or-url-or-@preset> --target cursor|claude|windsurf|all"));
713
+ console.error(import_picocolors4.default.red("Error: No OpenAPI spec provided. Usage: postmcp export <spec-path-or-url-or-@preset> --target cursor|opencode|claude-code|codex|claude|windsurf|all"));
641
714
  process.exit(1);
642
715
  }
643
716
  let serverKey = "api-server";
@@ -652,39 +725,85 @@ async function exportCommand(specArg, options) {
652
725
  }
653
726
  }
654
727
  const selectedTarget = (options.client || options.target || "all").toLowerCase();
655
- const clientsToExport = selectedTarget === "all" ? ["cursor", "claude", "windsurf"] : [selectedTarget];
728
+ const clientsToExport = selectedTarget === "all" ? ALL_CLIENTS : [selectedTarget];
656
729
  console.log(import_picocolors4.default.bold(import_picocolors4.default.cyan(`PostMCP 1-Click Client Configuration Exporter`)));
657
730
  console.log();
658
731
  for (const c of clientsToExport) {
659
732
  const configPath = getClientConfigPath(c);
660
- const snippet = buildClientConfigSnippet(serverKey, specPath, options);
661
- const formattedSnippet = JSON.stringify(snippet, null, 2);
662
- console.log(import_picocolors4.default.bold(import_picocolors4.default.green(`\u25B6 ${c.toUpperCase()} (${c === "cursor" ? "Project Local" : "Global Client"})`)));
733
+ let formattedSnippet = "";
734
+ if (c === "opencode") {
735
+ const snippet = buildOpenCodeConfigSnippet(serverKey, specPath, options);
736
+ formattedSnippet = JSON.stringify(snippet, null, 2);
737
+ } else if (c === "codex") {
738
+ formattedSnippet = buildCodexTomlSnippet(serverKey, specPath, options);
739
+ } else {
740
+ const snippet = buildClientConfigSnippet(serverKey, specPath, options);
741
+ formattedSnippet = JSON.stringify(snippet, null, 2);
742
+ }
743
+ const isProjectLocal = ["cursor", "opencode", "claude-code", "codex"].includes(c);
744
+ console.log(import_picocolors4.default.bold(import_picocolors4.default.green(`\u25B6 ${c.toUpperCase()} (${isProjectLocal ? "Project Local" : "Global Client"})`)));
663
745
  console.log(import_picocolors4.default.dim(` Config path: ${configPath}`));
664
746
  console.log();
665
747
  console.log(import_picocolors4.default.gray(formattedSnippet));
666
748
  console.log();
667
749
  if (options.write) {
668
750
  try {
669
- let existingConfig = {};
670
- if (fs4.existsSync(configPath)) {
671
- const raw = fs4.readFileSync(configPath, "utf-8");
672
- try {
673
- existingConfig = JSON.parse(raw);
674
- } catch {
675
- existingConfig = {};
676
- }
677
- }
678
- existingConfig.mcpServers = existingConfig.mcpServers || {};
679
- if (snippet.mcpServers?.[serverKey]) {
680
- existingConfig.mcpServers[serverKey] = snippet.mcpServers[serverKey];
681
- }
682
751
  const parentDir = path4.dirname(configPath);
683
752
  if (!fs4.existsSync(parentDir)) {
684
753
  fs4.mkdirSync(parentDir, { recursive: true });
685
754
  }
686
- fs4.writeFileSync(configPath, JSON.stringify(existingConfig, null, 2), "utf-8");
687
- console.log(import_picocolors4.default.green(` Successfully merged and written to ${configPath}`));
755
+ if (c === "codex") {
756
+ let content = "";
757
+ if (fs4.existsSync(configPath)) {
758
+ content = fs4.readFileSync(configPath, "utf-8");
759
+ }
760
+ if (!content.includes(`[mcp_servers.${serverKey}]`)) {
761
+ content = content ? `${content.trim()}
762
+
763
+ ${formattedSnippet}
764
+ ` : `${formattedSnippet}
765
+ `;
766
+ fs4.writeFileSync(configPath, content, "utf-8");
767
+ console.log(import_picocolors4.default.green(` Successfully appended to ${configPath}`));
768
+ } else {
769
+ console.log(import_picocolors4.default.yellow(` Server [mcp_servers.${serverKey}] already exists in ${configPath}`));
770
+ }
771
+ } else if (c === "opencode") {
772
+ let existingConfig = {};
773
+ if (fs4.existsSync(configPath)) {
774
+ try {
775
+ existingConfig = JSON.parse(fs4.readFileSync(configPath, "utf-8"));
776
+ } catch {
777
+ existingConfig = {};
778
+ }
779
+ }
780
+ existingConfig.$schema = existingConfig.$schema || "https://opencode.ai/config.json";
781
+ existingConfig.mcp = existingConfig.mcp || {};
782
+ const openCodeSnippet = buildOpenCodeConfigSnippet(serverKey, specPath, options);
783
+ const newMcp = openCodeSnippet.mcp?.[serverKey];
784
+ if (newMcp) {
785
+ existingConfig.mcp[serverKey] = newMcp;
786
+ }
787
+ fs4.writeFileSync(configPath, JSON.stringify(existingConfig, null, 2), "utf-8");
788
+ console.log(import_picocolors4.default.green(` Successfully merged and written to ${configPath}`));
789
+ } else {
790
+ let existingConfig = {};
791
+ if (fs4.existsSync(configPath)) {
792
+ const raw = fs4.readFileSync(configPath, "utf-8");
793
+ try {
794
+ existingConfig = JSON.parse(raw);
795
+ } catch {
796
+ existingConfig = {};
797
+ }
798
+ }
799
+ existingConfig.mcpServers = existingConfig.mcpServers || {};
800
+ const snippet = buildClientConfigSnippet(serverKey, specPath, options);
801
+ if (snippet.mcpServers?.[serverKey]) {
802
+ existingConfig.mcpServers[serverKey] = snippet.mcpServers[serverKey];
803
+ }
804
+ fs4.writeFileSync(configPath, JSON.stringify(existingConfig, null, 2), "utf-8");
805
+ console.log(import_picocolors4.default.green(` Successfully merged and written to ${configPath}`));
806
+ }
688
807
  } catch (err) {
689
808
  const errMsg = err instanceof Error ? err.message : String(err);
690
809
  console.error(import_picocolors4.default.red(` Failed to write to ${configPath}: ${errMsg}`));
@@ -939,8 +1058,8 @@ async function studioCommand(specArg, options = {}) {
939
1058
  }
940
1059
  }
941
1060
  if (child) {
942
- await new Promise((resolve5) => {
943
- child?.on("close", () => resolve5());
1061
+ await new Promise((resolve6) => {
1062
+ child?.on("close", () => resolve6());
944
1063
  });
945
1064
  }
946
1065
  }
@@ -978,7 +1097,7 @@ var import_path = require("path");
978
1097
  var import_picocolors8 = __toESM(require("picocolors"));
979
1098
  function getCliVersion() {
980
1099
  if (true) {
981
- return "0.1.25";
1100
+ return "0.1.27";
982
1101
  }
983
1102
  try {
984
1103
  const dir = typeof __dirname !== "undefined" ? __dirname : process.cwd();
@@ -1009,7 +1128,7 @@ function createCli() {
1009
1128
  process.exit(1);
1010
1129
  });
1011
1130
  });
1012
- 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) => {
1131
+ 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) => {
1013
1132
  const target = opts.target || opts.client || "all";
1014
1133
  exportCommand(spec, { ...opts, target, client: target }).catch((err) => {
1015
1134
  console.error(import_picocolors8.default.red(`Fatal error: ${err.message}`));