cheap-llm-mcp 0.1.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/.env.example +10 -0
- package/CHANGELOG.md +9 -0
- package/CONTRIBUTING.md +21 -0
- package/LICENSE +21 -0
- package/README.md +243 -0
- package/README.zh-CN.md +161 -0
- package/SECURITY.md +17 -0
- package/codex-config.example.toml +16 -0
- package/dist/accounting.d.ts +39 -0
- package/dist/accounting.js +79 -0
- package/dist/accounting.js.map +1 -0
- package/dist/chat.d.ts +4 -0
- package/dist/chat.js +82 -0
- package/dist/chat.js.map +1 -0
- package/dist/doctor.d.ts +1 -0
- package/dist/doctor.js +49 -0
- package/dist/doctor.js.map +1 -0
- package/dist/env.d.ts +3 -0
- package/dist/env.js +20 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +64 -0
- package/dist/index.js.map +1 -0
- package/dist/providers.d.ts +43 -0
- package/dist/providers.js +133 -0
- package/dist/providers.js.map +1 -0
- package/dist/safety.d.ts +10 -0
- package/dist/safety.js +62 -0
- package/dist/safety.js.map +1 -0
- package/dist/server.d.ts +5 -0
- package/dist/server.js +115 -0
- package/dist/server.js.map +1 -0
- package/dist/setup.d.ts +22 -0
- package/dist/setup.js +133 -0
- package/dist/setup.js.map +1 -0
- package/dist/types.d.ts +45 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +63 -0
package/dist/chat.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { envNumber } from "./env.js";
|
|
2
|
+
import { apiKeyFor, endpointFor, resolveProvider } from "./providers.js";
|
|
3
|
+
import { assertSafeToSend, buildMessages, redactError } from "./safety.js";
|
|
4
|
+
import { recordUsage } from "./accounting.js";
|
|
5
|
+
export function buildRequestBody(input, source = process.env) {
|
|
6
|
+
const provider = resolveProvider(input.provider, source);
|
|
7
|
+
return {
|
|
8
|
+
...provider.defaultBody,
|
|
9
|
+
...input.extraBody,
|
|
10
|
+
model: input.model ?? provider.model,
|
|
11
|
+
messages: buildMessages(input, source),
|
|
12
|
+
temperature: input.temperature ?? 0.2,
|
|
13
|
+
max_tokens: input.maxTokens ?? 800,
|
|
14
|
+
response_format: input.responseFormat ? { type: input.responseFormat } : undefined
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function stringifyResult(response, includeUsage) {
|
|
18
|
+
const choice = response.choices?.[0];
|
|
19
|
+
const content = choice?.message?.content ?? "";
|
|
20
|
+
const reasoning = choice?.message?.reasoning_content;
|
|
21
|
+
const parts = [content.trim()];
|
|
22
|
+
if (includeUsage && response.usage) {
|
|
23
|
+
parts.push([
|
|
24
|
+
"",
|
|
25
|
+
"---",
|
|
26
|
+
`model: ${response.model ?? "unknown"}`,
|
|
27
|
+
`finish_reason: ${choice?.finish_reason ?? "unknown"}`,
|
|
28
|
+
`prompt_tokens: ${response.usage.prompt_tokens ?? "unknown"}`,
|
|
29
|
+
`completion_tokens: ${response.usage.completion_tokens ?? "unknown"}`,
|
|
30
|
+
`total_tokens: ${response.usage.total_tokens ?? "unknown"}`
|
|
31
|
+
].join("\n"));
|
|
32
|
+
}
|
|
33
|
+
if (reasoning && includeUsage) {
|
|
34
|
+
parts.push(["", "---", "reasoning_content:", reasoning.trim()].join("\n"));
|
|
35
|
+
}
|
|
36
|
+
return parts.filter(Boolean).join("\n");
|
|
37
|
+
}
|
|
38
|
+
export async function callChatCompletion(input, source = process.env) {
|
|
39
|
+
assertSafeToSend(input, source);
|
|
40
|
+
const provider = resolveProvider(input.provider, source);
|
|
41
|
+
const apiKey = apiKeyFor(provider, source);
|
|
42
|
+
const body = buildRequestBody(input, source);
|
|
43
|
+
const controller = new AbortController();
|
|
44
|
+
const timeoutMs = input.requestTimeoutMs ?? provider.timeoutMs ?? envNumber("SIMPLE_LLM_TIMEOUT_MS", 60000, source);
|
|
45
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
46
|
+
let response;
|
|
47
|
+
try {
|
|
48
|
+
response = await fetch(endpointFor(provider), {
|
|
49
|
+
method: "POST",
|
|
50
|
+
headers: {
|
|
51
|
+
Authorization: `Bearer ${apiKey}`,
|
|
52
|
+
"Content-Type": "application/json",
|
|
53
|
+
...provider.headers
|
|
54
|
+
},
|
|
55
|
+
body: JSON.stringify(body),
|
|
56
|
+
signal: controller.signal
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
61
|
+
throw new Error(`Provider "${provider.name}" request timed out after ${timeoutMs}ms.`);
|
|
62
|
+
}
|
|
63
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
64
|
+
throw new Error(`Provider "${provider.name}" request failed: ${redactError(message, provider, apiKey, source)}`);
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
clearTimeout(timeout);
|
|
68
|
+
}
|
|
69
|
+
if (!response.ok) {
|
|
70
|
+
const text = await response.text();
|
|
71
|
+
throw new Error(`Provider "${provider.name}" returned HTTP ${response.status}: ${redactError(text, provider, apiKey, source).slice(0, 1000)}`);
|
|
72
|
+
}
|
|
73
|
+
const data = (await response.json());
|
|
74
|
+
recordUsage({
|
|
75
|
+
provider: provider.name,
|
|
76
|
+
requestedModel: input.model ?? provider.model,
|
|
77
|
+
response: data,
|
|
78
|
+
source
|
|
79
|
+
});
|
|
80
|
+
return stringifyResult(data, input.includeUsage ?? false);
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=chat.js.map
|
package/dist/chat.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../src/chat.ts"],"names":[],"mappings":"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"}
|
package/dist/doctor.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runDoctor(): Promise<number>;
|
package/dist/doctor.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
|
+
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
3
|
+
import { spawnSync } from "node:child_process";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { providerSetupStatus } from "./providers.js";
|
|
6
|
+
function hasCommand(command) {
|
|
7
|
+
const result = spawnSync(process.platform === "win32" ? "where.exe" : "which", [command], { encoding: "utf8" });
|
|
8
|
+
return result.status === 0;
|
|
9
|
+
}
|
|
10
|
+
export async function runDoctor() {
|
|
11
|
+
const checks = [];
|
|
12
|
+
const major = Number(process.versions.node.split(".")[0]);
|
|
13
|
+
checks.push(["Node.js >= 20", major >= 20, process.version, true]);
|
|
14
|
+
checks.push(["npx available", hasCommand("npx"), "needed by Claude Code/Codex install commands", true]);
|
|
15
|
+
checks.push(["claude available", hasCommand("claude"), "optional, needed for Claude Code auto setup", false]);
|
|
16
|
+
checks.push(["codex available", hasCommand("codex"), "optional, needed for Codex auto setup", false]);
|
|
17
|
+
let providersOk = false;
|
|
18
|
+
let providerText = "";
|
|
19
|
+
try {
|
|
20
|
+
const providers = providerSetupStatus();
|
|
21
|
+
providersOk = providers.some((provider) => provider.hasApiKey);
|
|
22
|
+
providerText = JSON.stringify(providers, null, 2);
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
providerText = error instanceof Error ? error.message : String(error);
|
|
26
|
+
}
|
|
27
|
+
checks.push(["provider API key configured", providersOk, providerText, true]);
|
|
28
|
+
let mcpOk = false;
|
|
29
|
+
let mcpText = "";
|
|
30
|
+
try {
|
|
31
|
+
const transport = new StdioClientTransport({ command: process.execPath, args: [fileURLToPath(new URL("./index.js", import.meta.url))] });
|
|
32
|
+
const client = new Client({ name: "cheap-llm-mcp-doctor", version: "0.0.0" });
|
|
33
|
+
await client.connect(transport);
|
|
34
|
+
const tools = await client.listTools();
|
|
35
|
+
await client.close();
|
|
36
|
+
const names = tools.tools.map((tool) => tool.name);
|
|
37
|
+
mcpOk = ["ask_simple_model", "list_simple_model_providers", "check_simple_model_setup"].every((name) => names.includes(name));
|
|
38
|
+
mcpText = names.join(", ");
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
mcpText = error instanceof Error ? error.message : String(error);
|
|
42
|
+
}
|
|
43
|
+
checks.push(["stdio MCP server starts", mcpOk, mcpText, true]);
|
|
44
|
+
for (const [name, ok, detail] of checks) {
|
|
45
|
+
process.stdout.write(`${ok ? "OK" : "WARN"} ${name}: ${detail}\n`);
|
|
46
|
+
}
|
|
47
|
+
return checks.every(([, ok, , required]) => ok || !required) ? 0 : 1;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/env.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function env(name: string, source?: NodeJS.ProcessEnv): string | undefined;
|
|
2
|
+
export declare function envFlag(name: string, defaultValue?: boolean, source?: NodeJS.ProcessEnv): boolean;
|
|
3
|
+
export declare function envNumber(name: string, defaultValue: number, source?: NodeJS.ProcessEnv): number;
|
package/dist/env.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function env(name, source = process.env) {
|
|
2
|
+
const value = source[name];
|
|
3
|
+
return value && value.trim().length > 0 ? value.trim() : undefined;
|
|
4
|
+
}
|
|
5
|
+
export function envFlag(name, defaultValue = false, source = process.env) {
|
|
6
|
+
const value = env(name, source);
|
|
7
|
+
if (!value) {
|
|
8
|
+
return defaultValue;
|
|
9
|
+
}
|
|
10
|
+
return ["1", "true", "yes", "on", "enabled"].includes(value.toLowerCase());
|
|
11
|
+
}
|
|
12
|
+
export function envNumber(name, defaultValue, source = process.env) {
|
|
13
|
+
const value = env(name, source);
|
|
14
|
+
if (!value) {
|
|
15
|
+
return defaultValue;
|
|
16
|
+
}
|
|
17
|
+
const parsed = Number(value);
|
|
18
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : defaultValue;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=env.js.map
|
package/dist/env.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,SAA4B,OAAO,CAAC,GAAG;IACvE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,YAAY,GAAG,KAAK,EAAE,SAA4B,OAAO,CAAC,GAAG;IACjG,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;AAC7E,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,YAAoB,EAAE,SAA4B,OAAO,CAAC,GAAG;IACnG,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC;AACvE,CAAC"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runDoctor } from "./doctor.js";
|
|
3
|
+
import { printConfig, runSetup } from "./setup.js";
|
|
4
|
+
import { startStdioServer } from "./server.js";
|
|
5
|
+
function printHelp() {
|
|
6
|
+
process.stdout.write(`cheap-llm-mcp
|
|
7
|
+
|
|
8
|
+
Save premium-model tokens by routing simple tasks to cheap OpenAI-compatible LLMs.
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
cheap-llm-mcp Start the stdio MCP server
|
|
12
|
+
cheap-llm-mcp setup Interactive Claude Code/Codex setup
|
|
13
|
+
cheap-llm-mcp doctor Check local setup and MCP startup
|
|
14
|
+
cheap-llm-mcp config Print manual config snippets
|
|
15
|
+
cheap-llm-mcp --help Show this help
|
|
16
|
+
|
|
17
|
+
Examples:
|
|
18
|
+
npx -y cheap-llm-mcp@latest setup
|
|
19
|
+
npx -y cheap-llm-mcp@latest doctor
|
|
20
|
+
`);
|
|
21
|
+
}
|
|
22
|
+
async function main() {
|
|
23
|
+
const command = process.argv[2];
|
|
24
|
+
if (!command) {
|
|
25
|
+
await startStdioServer();
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
if (command === "--help" || command === "-h" || command === "help") {
|
|
29
|
+
printHelp();
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
if (command === "setup") {
|
|
33
|
+
if (process.argv.includes("--help") || process.argv.includes("-h")) {
|
|
34
|
+
process.stdout.write("Usage: cheap-llm-mcp setup\n\nRuns an interactive setup wizard for Claude Code and Codex.\n");
|
|
35
|
+
return 0;
|
|
36
|
+
}
|
|
37
|
+
return runSetup();
|
|
38
|
+
}
|
|
39
|
+
if (command === "doctor") {
|
|
40
|
+
if (process.argv.includes("--help") || process.argv.includes("-h")) {
|
|
41
|
+
process.stdout.write("Usage: cheap-llm-mcp doctor\n\nChecks Node, npx, provider env vars, and MCP startup.\n");
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
return runDoctor();
|
|
45
|
+
}
|
|
46
|
+
if (command === "config") {
|
|
47
|
+
printConfig();
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
process.stderr.write(`Unknown command: ${command}\n\n`);
|
|
51
|
+
printHelp();
|
|
52
|
+
return 1;
|
|
53
|
+
}
|
|
54
|
+
main()
|
|
55
|
+
.then((code) => {
|
|
56
|
+
if (code !== 0) {
|
|
57
|
+
process.exitCode = code;
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
.catch((error) => {
|
|
61
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
62
|
+
process.exitCode = 1;
|
|
63
|
+
});
|
|
64
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,SAAS,SAAS;IAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;;;;;;;;;;;;;;CActB,CAAC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,gBAAgB,EAAE,CAAC;QACzB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACnE,SAAS,EAAE,CAAC;QACZ,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QACxB,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACnE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6FAA6F,CAAC,CAAC;YACpH,OAAO,CAAC,CAAC;QACX,CAAC;QACD,OAAO,QAAQ,EAAE,CAAC;IACpB,CAAC;IAED,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACnE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wFAAwF,CAAC,CAAC;YAC/G,OAAO,CAAC,CAAC;QACX,CAAC;QACD,OAAO,SAAS,EAAE,CAAC;IACrB,CAAC;IAED,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,WAAW,EAAE,CAAC;QACd,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,OAAO,MAAM,CAAC,CAAC;IACxD,SAAS,EAAE,CAAC;IACZ,OAAO,CAAC,CAAC;AACX,CAAC;AAED,IAAI,EAAE;KACH,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;IACb,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QACf,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAC1B,CAAC;AACH,CAAC,CAAC;KACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACpF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ProviderConfig } from "./types.js";
|
|
3
|
+
export declare const providerJsonSchema: z.ZodArray<z.ZodObject<{
|
|
4
|
+
name: z.ZodString;
|
|
5
|
+
baseUrl: z.ZodString;
|
|
6
|
+
chatPath: z.ZodOptional<z.ZodString>;
|
|
7
|
+
apiKey: z.ZodOptional<z.ZodString>;
|
|
8
|
+
apiKeyEnv: z.ZodOptional<z.ZodString>;
|
|
9
|
+
model: z.ZodString;
|
|
10
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
11
|
+
defaultBody: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
12
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
13
|
+
}, "strip", z.ZodTypeAny, {
|
|
14
|
+
model: string;
|
|
15
|
+
name: string;
|
|
16
|
+
baseUrl: string;
|
|
17
|
+
chatPath?: string | undefined;
|
|
18
|
+
apiKey?: string | undefined;
|
|
19
|
+
apiKeyEnv?: string | undefined;
|
|
20
|
+
headers?: Record<string, string> | undefined;
|
|
21
|
+
defaultBody?: Record<string, unknown> | undefined;
|
|
22
|
+
timeoutMs?: number | undefined;
|
|
23
|
+
}, {
|
|
24
|
+
model: string;
|
|
25
|
+
name: string;
|
|
26
|
+
baseUrl: string;
|
|
27
|
+
chatPath?: string | undefined;
|
|
28
|
+
apiKey?: string | undefined;
|
|
29
|
+
apiKeyEnv?: string | undefined;
|
|
30
|
+
headers?: Record<string, string> | undefined;
|
|
31
|
+
defaultBody?: Record<string, unknown> | undefined;
|
|
32
|
+
timeoutMs?: number | undefined;
|
|
33
|
+
}>, "many">;
|
|
34
|
+
export declare function normalizeBaseUrl(baseUrl: string): string;
|
|
35
|
+
export declare function normalizePath(path: string | undefined): string;
|
|
36
|
+
export declare function endpointFor(provider: ProviderConfig): string;
|
|
37
|
+
export declare function builtInProviders(source?: NodeJS.ProcessEnv): ProviderConfig[];
|
|
38
|
+
export declare function customProviders(source?: NodeJS.ProcessEnv): ProviderConfig[];
|
|
39
|
+
export declare function validateProvider(provider: ProviderConfig, source?: NodeJS.ProcessEnv): void;
|
|
40
|
+
export declare function allProviders(source?: NodeJS.ProcessEnv): ProviderConfig[];
|
|
41
|
+
export declare function resolveProvider(name?: string, source?: NodeJS.ProcessEnv): ProviderConfig;
|
|
42
|
+
export declare function apiKeyFor(provider: ProviderConfig, source?: NodeJS.ProcessEnv): string;
|
|
43
|
+
export declare function providerSetupStatus(source?: NodeJS.ProcessEnv): Array<Record<string, unknown>>;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { env, envFlag, envNumber } from "./env.js";
|
|
3
|
+
export const providerJsonSchema = z.array(z.object({
|
|
4
|
+
name: z.string().min(1),
|
|
5
|
+
baseUrl: z.string().url(),
|
|
6
|
+
chatPath: z.string().optional(),
|
|
7
|
+
apiKey: z.string().optional(),
|
|
8
|
+
apiKeyEnv: z.string().optional(),
|
|
9
|
+
model: z.string().min(1),
|
|
10
|
+
headers: z.record(z.string()).optional(),
|
|
11
|
+
defaultBody: z.record(z.unknown()).optional(),
|
|
12
|
+
timeoutMs: z.number().int().positive().optional()
|
|
13
|
+
}));
|
|
14
|
+
export function normalizeBaseUrl(baseUrl) {
|
|
15
|
+
return baseUrl.replace(/\/+$/, "");
|
|
16
|
+
}
|
|
17
|
+
export function normalizePath(path) {
|
|
18
|
+
const selected = path ?? "/chat/completions";
|
|
19
|
+
return selected.startsWith("/") ? selected : `/${selected}`;
|
|
20
|
+
}
|
|
21
|
+
export function endpointFor(provider) {
|
|
22
|
+
return `${normalizeBaseUrl(provider.baseUrl)}${normalizePath(provider.chatPath)}`;
|
|
23
|
+
}
|
|
24
|
+
export function builtInProviders(source = process.env) {
|
|
25
|
+
const providers = [
|
|
26
|
+
{
|
|
27
|
+
name: "cheap",
|
|
28
|
+
baseUrl: env("CHEAP_LLM_BASE_URL", source) ?? "https://api.deepseek.com",
|
|
29
|
+
chatPath: env("CHEAP_LLM_CHAT_PATH", source),
|
|
30
|
+
apiKeyEnv: "CHEAP_LLM_API_KEY",
|
|
31
|
+
model: env("CHEAP_LLM_MODEL", source) ?? "deepseek-chat",
|
|
32
|
+
timeoutMs: envNumber("CHEAP_LLM_TIMEOUT_MS", envNumber("SIMPLE_LLM_TIMEOUT_MS", 60000, source), source)
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: "deepseek",
|
|
36
|
+
baseUrl: env("DEEPSEEK_BASE_URL", source) ?? "https://api.deepseek.com",
|
|
37
|
+
chatPath: env("DEEPSEEK_CHAT_PATH", source),
|
|
38
|
+
apiKeyEnv: "DEEPSEEK_API_KEY",
|
|
39
|
+
model: env("DEEPSEEK_MODEL", source) ?? "deepseek-chat",
|
|
40
|
+
timeoutMs: envNumber("DEEPSEEK_TIMEOUT_MS", envNumber("SIMPLE_LLM_TIMEOUT_MS", 60000, source), source),
|
|
41
|
+
defaultBody: env("DEEPSEEK_THINKING", source) === "enabled"
|
|
42
|
+
? { thinking: { type: "enabled", reasoning_effort: env("DEEPSEEK_REASONING_EFFORT", source) ?? "high" } }
|
|
43
|
+
: { thinking: { type: "disabled" } }
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: "qwen",
|
|
47
|
+
baseUrl: env("QWEN_BASE_URL", source) ?? "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
48
|
+
chatPath: env("QWEN_CHAT_PATH", source),
|
|
49
|
+
apiKey: env("QWEN_API_KEY", source) ?? env("DASHSCOPE_API_KEY", source),
|
|
50
|
+
apiKeyEnv: "QWEN_API_KEY",
|
|
51
|
+
model: env("QWEN_MODEL", source) ?? "qwen-plus",
|
|
52
|
+
timeoutMs: envNumber("QWEN_TIMEOUT_MS", envNumber("SIMPLE_LLM_TIMEOUT_MS", 60000, source), source)
|
|
53
|
+
}
|
|
54
|
+
];
|
|
55
|
+
const mimoBaseUrl = env("MIMO_BASE_URL", source);
|
|
56
|
+
const mimoModel = env("MIMO_MODEL", source);
|
|
57
|
+
if (mimoBaseUrl && mimoModel) {
|
|
58
|
+
providers.push({
|
|
59
|
+
name: "mimo",
|
|
60
|
+
baseUrl: mimoBaseUrl,
|
|
61
|
+
chatPath: env("MIMO_CHAT_PATH", source),
|
|
62
|
+
apiKeyEnv: "MIMO_API_KEY",
|
|
63
|
+
model: mimoModel,
|
|
64
|
+
timeoutMs: envNumber("MIMO_TIMEOUT_MS", envNumber("SIMPLE_LLM_TIMEOUT_MS", 60000, source), source)
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return providers;
|
|
68
|
+
}
|
|
69
|
+
export function customProviders(source = process.env) {
|
|
70
|
+
const raw = env("SIMPLE_LLM_PROVIDERS", source);
|
|
71
|
+
if (!raw) {
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
let json;
|
|
75
|
+
try {
|
|
76
|
+
json = JSON.parse(raw);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
throw new Error(`Invalid SIMPLE_LLM_PROVIDERS JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
80
|
+
}
|
|
81
|
+
const parsed = providerJsonSchema.safeParse(json);
|
|
82
|
+
if (!parsed.success) {
|
|
83
|
+
throw new Error(`Invalid SIMPLE_LLM_PROVIDERS: ${parsed.error.message}`);
|
|
84
|
+
}
|
|
85
|
+
return parsed.data;
|
|
86
|
+
}
|
|
87
|
+
export function validateProvider(provider, source = process.env) {
|
|
88
|
+
const url = new URL(provider.baseUrl);
|
|
89
|
+
if (url.protocol !== "https:" && !envFlag("SIMPLE_LLM_ALLOW_HTTP", false, source)) {
|
|
90
|
+
throw new Error(`Provider "${provider.name}" must use https. Set SIMPLE_LLM_ALLOW_HTTP=true only for local testing.`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export function allProviders(source = process.env) {
|
|
94
|
+
const byName = new Map();
|
|
95
|
+
for (const provider of [...builtInProviders(source), ...customProviders(source)]) {
|
|
96
|
+
validateProvider(provider, source);
|
|
97
|
+
byName.set(provider.name, provider);
|
|
98
|
+
}
|
|
99
|
+
return [...byName.values()];
|
|
100
|
+
}
|
|
101
|
+
export function resolveProvider(name, source = process.env) {
|
|
102
|
+
const providers = allProviders(source);
|
|
103
|
+
const selectedName = name ?? env("SIMPLE_LLM_DEFAULT_PROVIDER", source) ?? "cheap";
|
|
104
|
+
const provider = providers.find((candidate) => candidate.name === selectedName);
|
|
105
|
+
if (!provider) {
|
|
106
|
+
throw new Error(`Unknown provider "${selectedName}". Available providers: ${providers.map((p) => p.name).join(", ")}`);
|
|
107
|
+
}
|
|
108
|
+
return provider;
|
|
109
|
+
}
|
|
110
|
+
export function apiKeyFor(provider, source = process.env) {
|
|
111
|
+
const key = provider.apiKey ?? (provider.apiKeyEnv ? env(provider.apiKeyEnv, source) : undefined);
|
|
112
|
+
if (!key) {
|
|
113
|
+
const hint = provider.apiKeyEnv ? ` Set ${provider.apiKeyEnv}.` : "";
|
|
114
|
+
throw new Error(`Missing API key for provider "${provider.name}".${hint}`);
|
|
115
|
+
}
|
|
116
|
+
return key;
|
|
117
|
+
}
|
|
118
|
+
export function providerSetupStatus(source = process.env) {
|
|
119
|
+
return allProviders(source).map((provider) => {
|
|
120
|
+
const apiKey = provider.apiKey ?? (provider.apiKeyEnv ? env(provider.apiKeyEnv, source) : undefined);
|
|
121
|
+
const url = new URL(provider.baseUrl);
|
|
122
|
+
return {
|
|
123
|
+
name: provider.name,
|
|
124
|
+
model: provider.model,
|
|
125
|
+
endpoint: endpointFor(provider),
|
|
126
|
+
apiKeyEnv: provider.apiKeyEnv,
|
|
127
|
+
hasApiKey: Boolean(apiKey),
|
|
128
|
+
https: url.protocol === "https:",
|
|
129
|
+
timeoutMs: provider.timeoutMs ?? envNumber("SIMPLE_LLM_TIMEOUT_MS", 60000, source)
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=providers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"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"}
|
package/dist/safety.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AskSimpleModelInput, ChatMessage, ProviderConfig } from "./types.js";
|
|
2
|
+
export declare const CHINESE_DEFAULT_SYSTEM_PROMPT = "\u9ED8\u8BA4\u4F7F\u7528\u7B80\u4F53\u4E2D\u6587\u56DE\u7B54\u3002\u4FDD\u7559\u4EE3\u7801\u3001\u547D\u4EE4\u3001\u6587\u4EF6\u8DEF\u5F84\u3001API \u540D\u79F0\u3001\u6A21\u578B\u540D\u79F0\u3001\u9519\u8BEF\u4FE1\u606F\u3001\u914D\u7F6E\u952E\u3001\u82F1\u6587\u4E13\u6709\u540D\u8BCD\u7684\u539F\u6587\uFF1B\u4E0D\u8981\u4E3A\u4E86\u4E2D\u6587\u5316\u800C\u6539\u5199\u4EE3\u7801\u6216\u547D\u4EE4\u3002\u56DE\u7B54\u5E94\u7B80\u6D01\u3001\u76F4\u63A5\u3001\u9002\u5408\u4E2D\u6587\u6280\u672F\u534F\u4F5C\u8BED\u5883\u3002\u82E5\u7528\u6237\u660E\u786E\u8981\u6C42\u82F1\u6587\u6216\u53CC\u8BED\uFF0C\u5219\u9075\u5FAA\u7528\u6237\u8981\u6C42\u3002";
|
|
3
|
+
export declare const STABILITY_DEFAULT_SYSTEM_PROMPT = "You are a cheap subtask model. Return a concise draft only. Do not make final decisions, claim to edit files, or assume missing facts. If the task is ambiguous or unsupported, say UNCERTAIN and why in one short sentence. The host AI will review your output before use.";
|
|
4
|
+
export declare function maxPromptChars(source?: NodeJS.ProcessEnv): number;
|
|
5
|
+
export declare function shouldUseChineseDefault(source?: NodeJS.ProcessEnv): boolean;
|
|
6
|
+
export declare function shouldUseStabilityDefault(source?: NodeJS.ProcessEnv): boolean;
|
|
7
|
+
export declare function buildMessages(input: Pick<AskSimpleModelInput, "system" | "prompt">, source?: NodeJS.ProcessEnv): ChatMessage[];
|
|
8
|
+
export declare function findSecretLikeText(text: string): string | undefined;
|
|
9
|
+
export declare function assertSafeToSend(input: AskSimpleModelInput, source?: NodeJS.ProcessEnv): void;
|
|
10
|
+
export declare function redactError(text: string, provider: ProviderConfig, apiKey: string, source?: NodeJS.ProcessEnv): string;
|
package/dist/safety.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { envFlag, envNumber } from "./env.js";
|
|
2
|
+
export const CHINESE_DEFAULT_SYSTEM_PROMPT = "默认使用简体中文回答。保留代码、命令、文件路径、API 名称、模型名称、错误信息、配置键、英文专有名词的原文;不要为了中文化而改写代码或命令。回答应简洁、直接、适合中文技术协作语境。若用户明确要求英文或双语,则遵循用户要求。";
|
|
3
|
+
export const STABILITY_DEFAULT_SYSTEM_PROMPT = "You are a cheap subtask model. Return a concise draft only. Do not make final decisions, claim to edit files, or assume missing facts. If the task is ambiguous or unsupported, say UNCERTAIN and why in one short sentence. The host AI will review your output before use.";
|
|
4
|
+
export function maxPromptChars(source = process.env) {
|
|
5
|
+
return envNumber("SIMPLE_LLM_MAX_PROMPT_CHARS", 12000, source);
|
|
6
|
+
}
|
|
7
|
+
export function shouldUseChineseDefault(source = process.env) {
|
|
8
|
+
return envFlag("SIMPLE_LLM_CHINESE_DEFAULT", true, source);
|
|
9
|
+
}
|
|
10
|
+
export function shouldUseStabilityDefault(source = process.env) {
|
|
11
|
+
return envFlag("SIMPLE_LLM_STABILITY_DEFAULT", true, source);
|
|
12
|
+
}
|
|
13
|
+
export function buildMessages(input, source = process.env) {
|
|
14
|
+
return [
|
|
15
|
+
...(shouldUseStabilityDefault(source) ? [{ role: "system", content: STABILITY_DEFAULT_SYSTEM_PROMPT }] : []),
|
|
16
|
+
...(shouldUseChineseDefault(source) ? [{ role: "system", content: CHINESE_DEFAULT_SYSTEM_PROMPT }] : []),
|
|
17
|
+
...(input.system ? [{ role: "system", content: input.system }] : []),
|
|
18
|
+
{ role: "user", content: input.prompt }
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
export function findSecretLikeText(text) {
|
|
22
|
+
const patterns = [
|
|
23
|
+
["OpenAI-style API key", /\bsk-[A-Za-z0-9_\-]{20,}\b/],
|
|
24
|
+
["Bearer token", /\bBearer\s+[A-Za-z0-9._\-]{20,}\b/i],
|
|
25
|
+
["API key assignment", /\b(api[_-]?key|secret|token|password)\b\s*[:=]\s*['"]?[^'"\s]{8,}/i],
|
|
26
|
+
["AWS access key", /\bAKIA[0-9A-Z]{16}\b/],
|
|
27
|
+
["private key block", /-----BEGIN [A-Z ]*PRIVATE KEY-----/]
|
|
28
|
+
];
|
|
29
|
+
return patterns.find(([, pattern]) => pattern.test(text))?.[0];
|
|
30
|
+
}
|
|
31
|
+
export function assertSafeToSend(input, source = process.env) {
|
|
32
|
+
if (input.approvedForExternalApi !== true) {
|
|
33
|
+
throw new Error("Refusing to call external provider: approvedForExternalApi must be true after confirming the prompt is safe to send to a third-party API.");
|
|
34
|
+
}
|
|
35
|
+
if (!input.dataClassification) {
|
|
36
|
+
throw new Error("Refusing to call external provider: dataClassification must be public, internal, private, or sensitive.");
|
|
37
|
+
}
|
|
38
|
+
if (input.dataClassification === "sensitive") {
|
|
39
|
+
throw new Error("Refusing to call external provider with dataClassification=sensitive.");
|
|
40
|
+
}
|
|
41
|
+
const combined = [input.system, input.prompt, input.extraBody ? JSON.stringify(input.extraBody) : undefined].filter(Boolean).join("\n\n");
|
|
42
|
+
if (combined.length > maxPromptChars(source)) {
|
|
43
|
+
throw new Error(`Refusing to call external provider: prompt is ${combined.length} chars, limit is ${maxPromptChars(source)}.`);
|
|
44
|
+
}
|
|
45
|
+
const secretMatch = findSecretLikeText(combined);
|
|
46
|
+
if (secretMatch) {
|
|
47
|
+
throw new Error(`Refusing to call external provider: prompt appears to contain ${secretMatch}.`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export function redactError(text, provider, apiKey, source = process.env) {
|
|
51
|
+
let redacted = text.replaceAll(apiKey, "[REDACTED_API_KEY]");
|
|
52
|
+
if (provider.apiKeyEnv) {
|
|
53
|
+
const envKey = source[provider.apiKeyEnv];
|
|
54
|
+
if (envKey) {
|
|
55
|
+
redacted = redacted.replaceAll(envKey, "[REDACTED_API_KEY]");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
redacted = redacted.replace(/\bsk-[A-Za-z0-9_\-]{12,}\b/g, "sk-[REDACTED]");
|
|
59
|
+
redacted = redacted.replace(/\bBearer\s+[A-Za-z0-9._\-]{12,}\b/gi, "Bearer [REDACTED]");
|
|
60
|
+
return redacted;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=safety.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safety.js","sourceRoot":"","sources":["../src/safety.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
export declare const SERVER_NAME = "cheap-llm-mcp";
|
|
3
|
+
export declare const SERVER_VERSION = "0.1.0";
|
|
4
|
+
export declare function createServer(source?: NodeJS.ProcessEnv): McpServer;
|
|
5
|
+
export declare function startStdioServer(source?: NodeJS.ProcessEnv): Promise<void>;
|