caplets 0.2.0 → 0.2.1
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/index.js +54 -12
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -19847,7 +19847,7 @@ const EMPTY_COMPLETION_RESULT = { completion: {
|
|
|
19847
19847
|
} };
|
|
19848
19848
|
//#endregion
|
|
19849
19849
|
//#region package.json
|
|
19850
|
-
var version = "0.2.
|
|
19850
|
+
var version = "0.2.1";
|
|
19851
19851
|
//#endregion
|
|
19852
19852
|
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
|
|
19853
19853
|
/**
|
|
@@ -20001,6 +20001,7 @@ const FORBIDDEN_HEADERS = new Set([
|
|
|
20001
20001
|
]);
|
|
20002
20002
|
join(homedir(), ".caplets", "config.json");
|
|
20003
20003
|
join(homedir(), ".caplets", "auth");
|
|
20004
|
+
const PROJECT_CONFIG_FILE = join(".caplets", "config.json");
|
|
20004
20005
|
const remoteAuthSchema = discriminatedUnion("type", [
|
|
20005
20006
|
object({ type: literal("none") }).strict(),
|
|
20006
20007
|
object({
|
|
@@ -20111,15 +20112,43 @@ const configFileSchema = object({
|
|
|
20111
20112
|
function resolveConfigPath(path) {
|
|
20112
20113
|
return path ?? join(homedir(), ".caplets", "config.json");
|
|
20113
20114
|
}
|
|
20114
|
-
function
|
|
20115
|
-
|
|
20115
|
+
function resolveProjectConfigPath(cwd = process.cwd()) {
|
|
20116
|
+
return join(cwd, PROJECT_CONFIG_FILE);
|
|
20117
|
+
}
|
|
20118
|
+
function loadConfig(path = resolveConfigPath(), projectPath = resolveProjectConfigPath()) {
|
|
20119
|
+
const hasUserConfig = existsSync(path);
|
|
20120
|
+
const hasProjectConfig = existsSync(projectPath);
|
|
20121
|
+
if (!hasUserConfig && !hasProjectConfig) throw new CapletsError("CONFIG_NOT_FOUND", `Caplets config not found at ${path} or ${projectPath}`);
|
|
20116
20122
|
try {
|
|
20117
|
-
return parseConfig(
|
|
20123
|
+
return parseConfig(mergeConfigInputs(hasProjectConfig ? readConfigFile(projectPath) : void 0, hasUserConfig ? readConfigFile(path) : void 0));
|
|
20118
20124
|
} catch (error) {
|
|
20119
20125
|
if (error instanceof CapletsError) throw error;
|
|
20120
20126
|
throw new CapletsError("CONFIG_INVALID", "Caplets config is not valid JSON", redactSecrets(error));
|
|
20121
20127
|
}
|
|
20122
20128
|
}
|
|
20129
|
+
function readConfigFile(path) {
|
|
20130
|
+
try {
|
|
20131
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
20132
|
+
} catch (error) {
|
|
20133
|
+
throw new CapletsError("CONFIG_INVALID", `Caplets config at ${path} is not valid JSON`, redactSecrets(error));
|
|
20134
|
+
}
|
|
20135
|
+
}
|
|
20136
|
+
function mergeConfigInputs(projectConfig, userConfig) {
|
|
20137
|
+
if (projectConfig === void 0) return userConfig;
|
|
20138
|
+
if (userConfig === void 0) return projectConfig;
|
|
20139
|
+
if (!isPlainConfigObject(projectConfig) || !isPlainConfigObject(userConfig)) return userConfig;
|
|
20140
|
+
return {
|
|
20141
|
+
...userConfig,
|
|
20142
|
+
...projectConfig,
|
|
20143
|
+
mcpServers: {
|
|
20144
|
+
...userConfig.mcpServers,
|
|
20145
|
+
...projectConfig.mcpServers
|
|
20146
|
+
}
|
|
20147
|
+
};
|
|
20148
|
+
}
|
|
20149
|
+
function isPlainConfigObject(value) {
|
|
20150
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
20151
|
+
}
|
|
20123
20152
|
function parseConfig(input) {
|
|
20124
20153
|
const parsed = configFileSchema.safeParse(interpolateServer(input));
|
|
20125
20154
|
if (!parsed.success) throw new CapletsError("CONFIG_INVALID", "Caplets config is invalid", parsed.error.issues);
|
|
@@ -23477,11 +23506,11 @@ var FileOAuthProvider = class {
|
|
|
23477
23506
|
codeVerifier() {
|
|
23478
23507
|
return this.verifier;
|
|
23479
23508
|
}
|
|
23480
|
-
async
|
|
23509
|
+
addClientAuthentication = async (headers, params) => {
|
|
23481
23510
|
if (this.server.auth?.type !== "oauth2" || !this.server.auth.clientSecret) return;
|
|
23482
23511
|
params.set("client_secret", this.server.auth.clientSecret);
|
|
23483
23512
|
headers.set("content-type", "application/x-www-form-urlencoded");
|
|
23484
|
-
}
|
|
23513
|
+
};
|
|
23485
23514
|
};
|
|
23486
23515
|
async function runOAuthFlow(server, options = {}) {
|
|
23487
23516
|
if (server.transport === "stdio" || !server.url || server.auth?.type !== "oauth2") throw new CapletsError("REQUEST_INVALID", `${server.server} is not a configured OAuth remote server`);
|
|
@@ -23815,7 +23844,16 @@ var ServerRegistry = class {
|
|
|
23815
23844
|
}
|
|
23816
23845
|
};
|
|
23817
23846
|
function capabilityDescription(server) {
|
|
23818
|
-
const hint =
|
|
23847
|
+
const hint = [
|
|
23848
|
+
`Use this Caplets wrapper to inspect and call tools from ${server.server}.`,
|
|
23849
|
+
"",
|
|
23850
|
+
"Recommended flow:",
|
|
23851
|
+
"- Discover tools: {\"operation\":\"list_tools\"} or {\"operation\":\"search_tools\",\"query\":\"<what you need>\"}",
|
|
23852
|
+
"- Read one tool schema: {\"operation\":\"get_tool\",\"tool\":\"<tool name>\"}",
|
|
23853
|
+
"- Invoke one downstream tool: {\"operation\":\"call_tool\",\"tool\":\"<tool name>\",\"arguments\":{...}}",
|
|
23854
|
+
"",
|
|
23855
|
+
"Important: call_tool requires a top-level \"arguments\" JSON object containing the downstream tool inputs. Do not put downstream arguments at the top level of this wrapper request."
|
|
23856
|
+
].join("\n");
|
|
23819
23857
|
return `${server.name}\n\n${server.description}\n\n${hint}`;
|
|
23820
23858
|
}
|
|
23821
23859
|
//#endregion
|
|
@@ -23829,11 +23867,15 @@ const operations = [
|
|
|
23829
23867
|
"call_tool"
|
|
23830
23868
|
];
|
|
23831
23869
|
const generatedToolInputSchema = object({
|
|
23832
|
-
operation: _enum(operations).describe(
|
|
23833
|
-
|
|
23834
|
-
|
|
23835
|
-
|
|
23836
|
-
|
|
23870
|
+
operation: _enum(operations).describe([
|
|
23871
|
+
"Caplets wrapper operation to perform for this configured MCP server.",
|
|
23872
|
+
"Use list_tools or search_tools to discover downstream tools, get_tool to read a downstream input schema, and call_tool to run one downstream tool.",
|
|
23873
|
+
"For call_tool, pass downstream inputs only inside the top-level \"arguments\" object."
|
|
23874
|
+
].join(" ")),
|
|
23875
|
+
query: string().optional().describe("Required only for search_tools. Example: {\"operation\":\"search_tools\",\"query\":\"web search\",\"limit\":5}. Do not use query for call_tool; put downstream query values under arguments.query."),
|
|
23876
|
+
limit: number$1().int().positive().optional().describe("Optional only for search_tools; defaults to the configured search limit. For downstream result limits, use call_tool.arguments with the downstream schema field name."),
|
|
23877
|
+
tool: string().optional().describe("Exact downstream tool name for get_tool or call_tool. Example: {\"operation\":\"get_tool\",\"tool\":\"web_search_exa\"} before calling it."),
|
|
23878
|
+
arguments: record(string(), unknown()).optional().describe("Required JSON object only for call_tool. Put every downstream tool input inside this object. Example: {\"operation\":\"call_tool\",\"tool\":\"web_search_exa\",\"arguments\":{\"query\":\"latest MCP docs\",\"numResults\":3}}. Do not send downstream inputs as top-level query, limit, url, path, or other fields.")
|
|
23837
23879
|
}).strict();
|
|
23838
23880
|
async function handleServerTool(server, request, registry, downstream) {
|
|
23839
23881
|
const parsed = validateOperationRequest(request, registry.config.options.maxSearchLimit);
|