@hasna/connectors 0.3.14 → 0.3.15
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/bin/index.js +147 -1
- package/bin/mcp.js +83 -1
- package/package.json +1 -1
package/bin/index.js
CHANGED
|
@@ -6833,7 +6833,7 @@ var PRESETS = {
|
|
|
6833
6833
|
commerce: { description: "Commerce and finance", connectors: ["stripe", "shopify", "revolut", "mercury", "pandadoc"] }
|
|
6834
6834
|
};
|
|
6835
6835
|
var program2 = new Command;
|
|
6836
|
-
program2.name("connectors").description("Install API connectors for your project").version("0.3.
|
|
6836
|
+
program2.name("connectors").description("Install API connectors for your project").version("0.3.15").enablePositionalOptions();
|
|
6837
6837
|
program2.command("interactive", { isDefault: true }).alias("i").description("Interactive connector browser").action(() => {
|
|
6838
6838
|
if (!isTTY) {
|
|
6839
6839
|
console.log(`Non-interactive environment detected. Use a subcommand:
|
|
@@ -8569,4 +8569,150 @@ program2.command("run").description("Execute an API operation on a connector").a
|
|
|
8569
8569
|
}
|
|
8570
8570
|
process.exit(result.exitCode);
|
|
8571
8571
|
});
|
|
8572
|
+
program2.command("setup").argument("<name>", "Connector name to set up").option("-k, --key <value>", "API key or bearer token value").option("-f, --field <field>", "Which field to set (for multi-field connectors)").option("-o, --overwrite", "Overwrite existing installation", false).option("--json", "Output as JSON", false).description("Install, configure auth, and verify a connector in one step").action(async (name, options) => {
|
|
8573
|
+
const meta = getConnector(name);
|
|
8574
|
+
if (!meta) {
|
|
8575
|
+
if (options.json) {
|
|
8576
|
+
console.log(JSON.stringify({ error: `Connector '${name}' not found` }));
|
|
8577
|
+
} else {
|
|
8578
|
+
console.log(chalk2.red(`Connector '${name}' not found`));
|
|
8579
|
+
}
|
|
8580
|
+
process.exit(1);
|
|
8581
|
+
return;
|
|
8582
|
+
}
|
|
8583
|
+
if (!options.json) {
|
|
8584
|
+
console.log(chalk2.bold(`
|
|
8585
|
+
Setting up ${meta.displayName}...
|
|
8586
|
+
`));
|
|
8587
|
+
}
|
|
8588
|
+
const installed = getInstalledConnectors();
|
|
8589
|
+
const alreadyInstalled = installed.includes(meta.name);
|
|
8590
|
+
let installResult;
|
|
8591
|
+
if (alreadyInstalled && !options.overwrite) {
|
|
8592
|
+
installResult = { success: true, path: join6(process.cwd(), ".connectors", `connect-${meta.name}`) };
|
|
8593
|
+
if (!options.json) {
|
|
8594
|
+
console.log(` ${chalk2.green("\u2713")} Already installed`);
|
|
8595
|
+
}
|
|
8596
|
+
} else {
|
|
8597
|
+
const result = installConnector(name, { overwrite: options.overwrite });
|
|
8598
|
+
installResult = { success: result.success, path: result.path, error: result.error };
|
|
8599
|
+
if (!options.json) {
|
|
8600
|
+
if (result.success) {
|
|
8601
|
+
console.log(` ${chalk2.green("\u2713")} Installed \u2192 ${chalk2.dim(result.path)}`);
|
|
8602
|
+
} else {
|
|
8603
|
+
console.log(` ${chalk2.red("\u2717")} Install failed: ${result.error}`);
|
|
8604
|
+
process.exit(1);
|
|
8605
|
+
return;
|
|
8606
|
+
}
|
|
8607
|
+
} else if (!result.success) {
|
|
8608
|
+
console.log(JSON.stringify({ error: `Install failed: ${result.error}` }));
|
|
8609
|
+
process.exit(1);
|
|
8610
|
+
return;
|
|
8611
|
+
}
|
|
8612
|
+
}
|
|
8613
|
+
const authType = getAuthType(name);
|
|
8614
|
+
let authConfigured = false;
|
|
8615
|
+
if (authType === "oauth") {
|
|
8616
|
+
if (options.key) {
|
|
8617
|
+
saveApiKey(name, options.key, options.field || undefined);
|
|
8618
|
+
authConfigured = true;
|
|
8619
|
+
if (!options.json) {
|
|
8620
|
+
console.log(` ${chalk2.green("\u2713")} Token saved`);
|
|
8621
|
+
}
|
|
8622
|
+
} else {
|
|
8623
|
+
const statusBefore = getAuthStatus(name);
|
|
8624
|
+
if (statusBefore.configured) {
|
|
8625
|
+
authConfigured = true;
|
|
8626
|
+
if (!options.json) {
|
|
8627
|
+
console.log(` ${chalk2.green("\u2713")} OAuth already configured`);
|
|
8628
|
+
}
|
|
8629
|
+
} else {
|
|
8630
|
+
if (options.json) {
|
|
8631
|
+
const summary = {
|
|
8632
|
+
connector: name,
|
|
8633
|
+
displayName: meta.displayName,
|
|
8634
|
+
installed: installResult.success,
|
|
8635
|
+
path: installResult.path,
|
|
8636
|
+
authType: "oauth",
|
|
8637
|
+
authConfigured: false,
|
|
8638
|
+
message: "OAuth requires browser-based authentication. Use 'connectors serve' or pass --key to set tokens manually."
|
|
8639
|
+
};
|
|
8640
|
+
console.log(JSON.stringify(summary, null, 2));
|
|
8641
|
+
process.exit(0);
|
|
8642
|
+
return;
|
|
8643
|
+
}
|
|
8644
|
+
console.log(` ${chalk2.yellow("\u27F3")} OAuth authentication required \u2014 starting server...`);
|
|
8645
|
+
try {
|
|
8646
|
+
const port = 19426;
|
|
8647
|
+
const { startServer: startServer2 } = await Promise.resolve().then(() => (init_serve(), exports_serve));
|
|
8648
|
+
await startServer2(port, { open: false });
|
|
8649
|
+
const oauthUrl = `http://localhost:${port}/oauth/${name}/start`;
|
|
8650
|
+
console.log(`
|
|
8651
|
+
${chalk2.bold("Open this URL to authenticate:")}`);
|
|
8652
|
+
console.log(` ${chalk2.cyan(oauthUrl)}
|
|
8653
|
+
`);
|
|
8654
|
+
try {
|
|
8655
|
+
const { exec } = await import("child_process");
|
|
8656
|
+
const openCmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
8657
|
+
exec(`${openCmd} "${oauthUrl}"`);
|
|
8658
|
+
console.log(chalk2.dim(` Browser opened. Complete the OAuth flow, then press Ctrl+C.
|
|
8659
|
+
`));
|
|
8660
|
+
} catch {
|
|
8661
|
+
console.log(chalk2.dim(` Open the URL above in your browser.
|
|
8662
|
+
`));
|
|
8663
|
+
}
|
|
8664
|
+
await new Promise(() => {});
|
|
8665
|
+
} catch (err) {
|
|
8666
|
+
console.log(` ${chalk2.red("\u2717")} OAuth flow failed: ${err}`);
|
|
8667
|
+
console.log(chalk2.dim(" Try 'connectors serve' to use the full dashboard."));
|
|
8668
|
+
}
|
|
8669
|
+
process.exit(0);
|
|
8670
|
+
return;
|
|
8671
|
+
}
|
|
8672
|
+
}
|
|
8673
|
+
} else {
|
|
8674
|
+
if (options.key) {
|
|
8675
|
+
saveApiKey(name, options.key, options.field || undefined);
|
|
8676
|
+
authConfigured = true;
|
|
8677
|
+
if (!options.json) {
|
|
8678
|
+
console.log(` ${chalk2.green("\u2713")} ${authType === "bearer" ? "Bearer token" : "API key"} saved`);
|
|
8679
|
+
}
|
|
8680
|
+
} else {
|
|
8681
|
+
const statusBefore = getAuthStatus(name);
|
|
8682
|
+
if (statusBefore.configured) {
|
|
8683
|
+
authConfigured = true;
|
|
8684
|
+
if (!options.json) {
|
|
8685
|
+
console.log(` ${chalk2.green("\u2713")} Auth already configured (${authType === "bearer" ? "bearer token" : "API key"})`);
|
|
8686
|
+
}
|
|
8687
|
+
} else {
|
|
8688
|
+
if (!options.json) {
|
|
8689
|
+
console.log(` ${chalk2.yellow("\u26A0")} No API key provided. Use --key <value> to configure auth.`);
|
|
8690
|
+
}
|
|
8691
|
+
}
|
|
8692
|
+
}
|
|
8693
|
+
}
|
|
8694
|
+
const finalStatus = getAuthStatus(name);
|
|
8695
|
+
if (options.json) {
|
|
8696
|
+
const summary = {
|
|
8697
|
+
connector: name,
|
|
8698
|
+
displayName: meta.displayName,
|
|
8699
|
+
installed: installResult.success,
|
|
8700
|
+
path: installResult.path,
|
|
8701
|
+
authType: finalStatus.type,
|
|
8702
|
+
authConfigured: finalStatus.configured,
|
|
8703
|
+
envVars: finalStatus.envVars,
|
|
8704
|
+
tokenExpiry: finalStatus.tokenExpiry
|
|
8705
|
+
};
|
|
8706
|
+
console.log(JSON.stringify(summary, null, 2));
|
|
8707
|
+
} else {
|
|
8708
|
+
console.log();
|
|
8709
|
+
console.log(chalk2.bold(" Summary"));
|
|
8710
|
+
console.log(` \u251C\u2500 Connector: ${meta.displayName}`);
|
|
8711
|
+
console.log(` \u251C\u2500 Installed: ${chalk2.green("yes")}`);
|
|
8712
|
+
console.log(` \u251C\u2500 Auth type: ${finalStatus.type === "oauth" ? "OAuth" : finalStatus.type === "apikey" ? "API Key" : "Bearer Token"}`);
|
|
8713
|
+
console.log(` \u2514\u2500 Auth: ${finalStatus.configured ? chalk2.green("configured") : chalk2.red("not configured")}`);
|
|
8714
|
+
console.log();
|
|
8715
|
+
}
|
|
8716
|
+
process.exit(0);
|
|
8717
|
+
});
|
|
8572
8718
|
program2.parse();
|
package/bin/mcp.js
CHANGED
|
@@ -20315,7 +20315,7 @@ async function getConnectorCommandHelp(name, command) {
|
|
|
20315
20315
|
loadConnectorVersions();
|
|
20316
20316
|
var server = new McpServer({
|
|
20317
20317
|
name: "connectors",
|
|
20318
|
-
version: "0.3.
|
|
20318
|
+
version: "0.3.15"
|
|
20319
20319
|
});
|
|
20320
20320
|
server.registerTool("search_connectors", {
|
|
20321
20321
|
title: "Search Connectors",
|
|
@@ -20671,6 +20671,86 @@ ${result.stderr}`;
|
|
|
20671
20671
|
]
|
|
20672
20672
|
};
|
|
20673
20673
|
});
|
|
20674
|
+
server.registerTool("setup_connector", {
|
|
20675
|
+
title: "Setup Connector",
|
|
20676
|
+
description: "Install a connector and configure auth in one step. Installs if not already present, saves API key if provided, and returns install + auth status.",
|
|
20677
|
+
inputSchema: {
|
|
20678
|
+
name: exports_external.string().describe("Connector name (e.g. stripe, gmail, anthropic)"),
|
|
20679
|
+
key: exports_external.string().optional().describe("API key or bearer token to save"),
|
|
20680
|
+
field: exports_external.string().optional().describe("Which field to save the key as (for multi-field connectors)"),
|
|
20681
|
+
overwrite: exports_external.boolean().optional().describe("Overwrite existing installation (default: false)")
|
|
20682
|
+
}
|
|
20683
|
+
}, async ({ name, key, field, overwrite }) => {
|
|
20684
|
+
const meta = getConnector(name);
|
|
20685
|
+
if (!meta) {
|
|
20686
|
+
return {
|
|
20687
|
+
content: [{ type: "text", text: `Connector '${name}' not found.` }],
|
|
20688
|
+
isError: true
|
|
20689
|
+
};
|
|
20690
|
+
}
|
|
20691
|
+
const installed = getInstalledConnectors();
|
|
20692
|
+
const alreadyInstalled = installed.includes(meta.name);
|
|
20693
|
+
let installStatus;
|
|
20694
|
+
if (alreadyInstalled && !overwrite) {
|
|
20695
|
+
installStatus = { installed: true, path: `.connectors/connect-${meta.name}` };
|
|
20696
|
+
} else {
|
|
20697
|
+
const result = installConnector(name, { overwrite: overwrite ?? false });
|
|
20698
|
+
if (!result.success) {
|
|
20699
|
+
return {
|
|
20700
|
+
content: [
|
|
20701
|
+
{
|
|
20702
|
+
type: "text",
|
|
20703
|
+
text: JSON.stringify({
|
|
20704
|
+
connector: name,
|
|
20705
|
+
installed: false,
|
|
20706
|
+
error: result.error
|
|
20707
|
+
}, null, 2)
|
|
20708
|
+
}
|
|
20709
|
+
],
|
|
20710
|
+
isError: true
|
|
20711
|
+
};
|
|
20712
|
+
}
|
|
20713
|
+
installStatus = { installed: true, path: result.path };
|
|
20714
|
+
}
|
|
20715
|
+
if (key) {
|
|
20716
|
+
try {
|
|
20717
|
+
saveApiKey(name, key, field);
|
|
20718
|
+
} catch (error2) {
|
|
20719
|
+
return {
|
|
20720
|
+
content: [
|
|
20721
|
+
{
|
|
20722
|
+
type: "text",
|
|
20723
|
+
text: JSON.stringify({
|
|
20724
|
+
connector: name,
|
|
20725
|
+
installed: installStatus.installed,
|
|
20726
|
+
path: installStatus.path,
|
|
20727
|
+
authError: error2 instanceof Error ? error2.message : String(error2)
|
|
20728
|
+
}, null, 2)
|
|
20729
|
+
}
|
|
20730
|
+
],
|
|
20731
|
+
isError: true
|
|
20732
|
+
};
|
|
20733
|
+
}
|
|
20734
|
+
}
|
|
20735
|
+
const authStatus = getAuthStatus(name);
|
|
20736
|
+
return {
|
|
20737
|
+
content: [
|
|
20738
|
+
{
|
|
20739
|
+
type: "text",
|
|
20740
|
+
text: JSON.stringify({
|
|
20741
|
+
connector: name,
|
|
20742
|
+
displayName: meta.displayName,
|
|
20743
|
+
installed: installStatus.installed,
|
|
20744
|
+
path: installStatus.path,
|
|
20745
|
+
authType: authStatus.type,
|
|
20746
|
+
authConfigured: authStatus.configured,
|
|
20747
|
+
tokenExpiry: authStatus.tokenExpiry,
|
|
20748
|
+
envVars: authStatus.envVars
|
|
20749
|
+
}, null, 2)
|
|
20750
|
+
}
|
|
20751
|
+
]
|
|
20752
|
+
};
|
|
20753
|
+
});
|
|
20674
20754
|
server.registerTool("search_tools", {
|
|
20675
20755
|
title: "Search Tools",
|
|
20676
20756
|
description: "List tool names, optionally filtered by keyword.",
|
|
@@ -20686,6 +20766,7 @@ server.registerTool("search_tools", {
|
|
|
20686
20766
|
"connector_info",
|
|
20687
20767
|
"connector_auth_status",
|
|
20688
20768
|
"configure_auth",
|
|
20769
|
+
"setup_connector",
|
|
20689
20770
|
"list_categories",
|
|
20690
20771
|
"list_connector_operations",
|
|
20691
20772
|
"run_connector_operation",
|
|
@@ -20710,6 +20791,7 @@ server.registerTool("describe_tools", {
|
|
|
20710
20791
|
connector_info: "Get metadata and install status. Params: name",
|
|
20711
20792
|
connector_auth_status: "Check auth status and env vars. Params: name",
|
|
20712
20793
|
configure_auth: "Save API key or token. Params: name, key, field?",
|
|
20794
|
+
setup_connector: "Install + configure auth + verify in one call. Params: name, key?, field?, overwrite?",
|
|
20713
20795
|
list_categories: "List connector categories with counts.",
|
|
20714
20796
|
list_connector_operations: "Discover available API operations for a connector. Params: name, command?",
|
|
20715
20797
|
run_connector_operation: "Execute an API operation on a connector. Params: name, args[], format?, timeout?"
|