merge: schema fix for Value-typed metadata/policy MCP args

This commit is contained in:
Kayos 2026-05-09 09:23:45 -07:00
commit 8af9f2e238

View file

@ -167,6 +167,29 @@ use rmcp::{
};
use serde::Deserialize;
/// Schema-shape helper for `serde_json::Value` arg fields that
/// expect a JSON object (CIP-25 / CIP-68 metadata, multisig
/// PolicySpec dicts). schemars's default for `Option<Value>` /
/// `Value` emits a schema with no `type`, which Claude Code's MCP
/// client interprets as "string-encoded" — it then JSON-stringifies
/// the user's `{...}` before sending, and the server-side
/// validation `value.is_object()` returns false. Force
/// `type: object` so the client passes the value through as a
/// proper JSON object on the wire. (`additionalProperties: true`
/// keeps the schema permissive — these args really do accept
/// arbitrary keys.)
fn json_object_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
use schemars::schema::{InstanceType, ObjectValidation, Schema, SchemaObject, SingleOrVec};
Schema::Object(SchemaObject {
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Object))),
object: Some(Box::new(ObjectValidation {
additional_properties: Some(Box::new(Schema::Bool(true))),
..Default::default()
})),
..Default::default()
})
}
/// MCP-facing asset spec — separate from `aldabra_core::AssetSpec`
/// so the JsonSchema derive doesn't bleed schemars into the
/// security-boundary crate.
@ -518,9 +541,11 @@ pub struct MintUnsignedArgs {
/// single-sig policy bound to this wallet's payment key (same as
/// `wallet_mint`).
#[serde(default)]
#[schemars(schema_with = "json_object_schema")]
pub policy: Option<serde_json::Value>,
/// Optional CIP-25 v2 metadata.
#[serde(default)]
#[schemars(schema_with = "json_object_schema")]
pub metadata: Option<serde_json::Value>,
/// Hex of the pkh to disclose as a required signer in the tx
/// body. Defaults to this wallet's payment key hash. For
@ -665,6 +690,7 @@ pub struct Cip68NftArgs {
/// CIP-68 metadata JSON object (`name`, `image`, `description`,
/// `mediaType`, `files`, etc.). Encoded as Plutus Data and
/// attached as the inline datum on the ref-NFT output.
#[schemars(schema_with = "json_object_schema")]
pub metadata: serde_json::Value,
/// Optional address where the reference NFT lives. Defaults to
/// the wallet's own address — keeps the NFT *mutable* (the
@ -722,6 +748,7 @@ pub struct MintArgs {
/// `files`, etc.). Wallets and explorers display this when
/// rendering the asset.
#[serde(default)]
#[schemars(schema_with = "json_object_schema")]
pub metadata: Option<serde_json::Value>,
/// Bypass the configured `max_send_lovelace` hard cap on
/// `dest_lovelace`. Only pass `true` for an intentional,