@withpica/mcp-server
Version:
MCP Server for withPICA — enables AI assistants to interact with your withPICA music catalog
66 lines • 3.66 kB
JavaScript
// Copyright (c) 2025-2026 Withpica Ltd. All rights reserved.
export function buildWrappedArgsMissingEnvelope(params) {
const { toolName, required, missingRequired, requiredOneOf, args, knownProps, aliasesApplied, } = params;
const allMissing = Object.keys(args).length === 0;
const unrecognisedFields = Object.keys(args).filter((k) => !knownProps.includes(k));
const hasOneOf = Array.isArray(requiredOneOf) && requiredOneOf.length > 0;
const unmetGroup = hasOneOf
? requiredOneOf.find((group) => Array.isArray(group) &&
group.length > 0 &&
!group.some((f) => f in args))
: undefined;
// What the empty-args ("received none") message names as required — the
// plain list, or (for a oneOf-only tool, whose `required` is `[]`) the
// unmet group's members.
const requirementLabel = required.length > 0 ? required.join(", ") : (unmetGroup ?? []).join(", ");
const stubArgs = required.length > 0
? Object.fromEntries(required.map((f) => [f, "<value>"]))
: unmetGroup
? { [unmetGroup[0]]: "<value>" }
: {};
// Empty args really is a transport question — there is nothing else an
// empty resolved-args object could be — so this branch keeps asserting
// that, verbatim, for both guards.
//
// A NON-empty args object still missing what it needs is NOT necessarily
// transport loss: it was wrong in all 36 logged cases since July (the
// caller sent the tool's own id under a plausible name that per-tool
// aliasing resolves when unambiguous, or a misspelled/foreign key that
// aliasing correctly leaves alone). Neither guard can tell "transport
// loss" apart from "wrong key sent" from here, so both name what
// pica_execute actually saw instead of asserting a cause they can't know.
const message = allMissing
? `${toolName} requires arguments [${requirementLabel}] but pica_execute received none. Pass them as \`args: {...}\` (canonical) or as top-level keys (FLAT). Do NOT pass them under \`arguments:\` — claude.ai web silently strips that field as a wire-protocol token, which is why the wrapped tool sees nothing.`
: unmetGroup
? `${toolName} requires one of [${unmetGroup.join(", ")}] but none was present in the resolved args. Unrecognised fields sent: [${unrecognisedFields.join(", ") || "none"}]. Check the schema with pica_tool_details({ tool: "${toolName}" }).`
: `${toolName} requires [${required.join(", ")}] — missing: [${missingRequired.join(", ")}]. Unrecognised fields sent: [${unrecognisedFields.join(", ") || "none"}]. Check the schema with pica_tool_details({ tool: "${toolName}" }).`;
const shared = {
error_code: "WRAPPED_ARGS_MISSING",
tool: toolName,
required_fields: required,
missing_required_fields: missingRequired,
...(hasOneOf ? { required_one_of: requiredOneOf } : {}),
unrecognised_fields: unrecognisedFields,
aliases_applied: aliasesApplied,
next_tool: "pica_tool_details",
retry_eligible: false,
};
const exampleCallShapes = {
canonical: { tool: toolName, args: stubArgs },
flat: { tool: toolName, ...stubArgs },
};
const envelope = {
...shared,
message,
example_call_shapes: exampleCallShapes,
};
return {
text: JSON.stringify(envelope, null, 2),
structuredContent: {
...shared,
error_message: message,
example_call_shapes: exampleCallShapes,
},
};
}
//# sourceMappingURL=wrapped-args-envelope.js.map