@opennous/mcp 0.26.0 → 0.28.0
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/package.json +1 -1
- package/src/client.js +18 -7
- package/src/server.js +7 -1
package/package.json
CHANGED
package/src/client.js
CHANGED
|
@@ -37,22 +37,33 @@ export function runWithApiKey(apiKey, fn) {
|
|
|
37
37
|
|
|
38
38
|
// Credential written by `nous login` (the browser device-auth flow). The CLI and
|
|
39
39
|
// the MCP server share ~/.nous/config.json, so a user who runs the login command
|
|
40
|
-
// gets a key
|
|
41
|
-
|
|
40
|
+
// gets a key — and, for self-host, the API URL — the MCP picks up on the next
|
|
41
|
+
// call, with no paste and no env var.
|
|
42
|
+
function readFileConfig() {
|
|
42
43
|
try {
|
|
43
44
|
const dir = resolvedEnv("NOUS_CONFIG_DIR") || path.join(os.homedir(), ".nous");
|
|
44
|
-
|
|
45
|
-
const k = cfg?.apiKey;
|
|
46
|
-
return k && !String(k).includes("${") ? k : undefined;
|
|
45
|
+
return JSON.parse(fs.readFileSync(path.join(dir, "config.json"), "utf8"));
|
|
47
46
|
} catch {
|
|
48
|
-
return
|
|
47
|
+
return null;
|
|
49
48
|
}
|
|
50
49
|
}
|
|
50
|
+
function clean(v) {
|
|
51
|
+
return v && !String(v).includes("${") ? v : undefined; // drop unresolved ${...} markers
|
|
52
|
+
}
|
|
53
|
+
function fileApiKey() { return clean(readFileConfig()?.apiKey); }
|
|
54
|
+
function fileApiUrl() { return clean(readFileConfig()?.apiUrl); }
|
|
51
55
|
|
|
52
56
|
function currentApiKey() {
|
|
53
57
|
return apiKeyStore.getStore()?.apiKey ?? resolvedEnv("NOUS_API_KEY") ?? fileApiKey();
|
|
54
58
|
}
|
|
55
59
|
|
|
60
|
+
// Resolve the API base per call: env → ~/.nous/config.json (set by `nous login
|
|
61
|
+
// --url` on self-host) → cloud default. So a self-hoster who logs in via the CLI
|
|
62
|
+
// gets the MCP pointed at their own instance automatically.
|
|
63
|
+
function currentApiUrl() {
|
|
64
|
+
return resolvedEnv("NOUS_API_URL") ?? fileApiUrl() ?? "https://api.opennous.cloud";
|
|
65
|
+
}
|
|
66
|
+
|
|
56
67
|
// stdio-only preflight. A key may come from the env OR from `nous login`'s
|
|
57
68
|
// credential file. This is advisory — the server still starts without one so
|
|
58
69
|
// the user can run the login command after installing the plugin, and the key
|
|
@@ -72,7 +83,7 @@ async function request(method, path, { body, query } = {}) {
|
|
|
72
83
|
throw new Error("Missing Nous API key. Pass it as an Authorization: Bearer header.");
|
|
73
84
|
}
|
|
74
85
|
|
|
75
|
-
const url = new URL(path,
|
|
86
|
+
const url = new URL(path, currentApiUrl());
|
|
76
87
|
|
|
77
88
|
if (query) {
|
|
78
89
|
for (const [key, value] of Object.entries(query)) {
|
package/src/server.js
CHANGED
|
@@ -39,7 +39,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
39
39
|
import { z } from "zod";
|
|
40
40
|
import { get, post } from "./client.js";
|
|
41
41
|
|
|
42
|
-
export const SERVER_VERSION = "0.
|
|
42
|
+
export const SERVER_VERSION = "0.28.0";
|
|
43
43
|
|
|
44
44
|
// ─── helpers ──────────────────────────────────────────────────────────────────
|
|
45
45
|
|
|
@@ -571,6 +571,12 @@ export function createServer() {
|
|
|
571
571
|
lines.push(`WORKSPACE: ${ws.name || "(unnamed)"}${ws.website ? ` · ${ws.website}` : ""}${ws.business_type ? ` · ${ws.business_type}` : ""}`);
|
|
572
572
|
const pl = s.plan ?? {};
|
|
573
573
|
lines.push(`PLAN: ${pl.name || pl.id || "free"}${pl.crm_sync === false ? " (CRM sync not included — do not offer it)" : ""}`);
|
|
574
|
+
if (s.self_hosted) {
|
|
575
|
+
const e = s.env_integrations ?? {};
|
|
576
|
+
const mk = (b) => (b ? "✓ set" : "✗ NOT set");
|
|
577
|
+
lines.push("SELF-HOSTED — these channels are wired via nous.env (you can't set env vars; tell the operator to set + restart):");
|
|
578
|
+
lines.push(` LinkedIn/Unipile: ${mk(e.linkedin_unipile)} Email/Resend: ${mk(e.email_resend)} Gmail OAuth: ${mk(e.gmail_oauth)}`);
|
|
579
|
+
}
|
|
574
580
|
lines.push("");
|
|
575
581
|
|
|
576
582
|
const mark = (b) => (b ? "✓" : "✗");
|