feat: Expose NBT/component data in inventory MCP tools

feat(inventory): expose NBT/component data in inventory MCP tools
This commit is contained in:
Anon 2026-07-04 21:53:42 +02:00 committed by GitHub
commit 99f5744715
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 33 additions and 3 deletions

View file

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
using MinecraftClient.Inventory.ItemPalettes;
namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Core;
@ -12,8 +13,15 @@ public abstract class StructuredComponent(DataTypes dataTypes, ItemPalette itemP
/// <summary>
/// The registry type ID assigned during parsing, used for round-trip serialization.
/// </summary>
[JsonIgnore]
public int TypeId { get; set; } = -1;
/// <summary>
/// The registry name assigned during parsing (e.g. "minecraft:custom_data"), used for NBT serialization.
/// </summary>
[JsonIgnore]
public string ComponentName { get; set; } = string.Empty;
public abstract void Parse(Queue<byte> data);
public abstract Queue<byte> Serialize();
}

View file

@ -37,6 +37,7 @@ public abstract class StructuredComponentRegistry(DataTypes dataTypes, ItemPalet
?? throw new InvalidOperationException($"Could not instantiate a parser for a structured component type {name}");
component.TypeId = id;
component.ComponentName = name;
component.Parse(data);
return component;
}

View file

@ -795,7 +795,8 @@ public sealed class MccGameApi
{
Slot = item.Key,
Type = item.Value.Type.ToString(),
Count = item.Value.Count
Count = item.Value.Count,
Nbt = MccGameCommon.BuildNbt(item.Value)
})
.ToArray();
@ -856,7 +857,8 @@ public sealed class MccGameApi
TypeLabel = pair.Value.GetTypeString(),
Count = pair.Value.Count,
IsPlayerInventory = entry.Key == 0,
HotbarSlot = isHotbar ? hotbar + 1 : null
HotbarSlot = isHotbar ? hotbar + 1 : null,
Nbt = MccGameCommon.BuildNbt(pair.Value)
};
});
})

View file

@ -35,6 +35,7 @@ public sealed class MccItemStackSnapshot
{
public required string Type { get; init; }
public required int Count { get; init; }
public Dictionary<string, object>? Nbt { get; init; }
}
/// <summary>
@ -177,10 +178,26 @@ public static class MccGameCommon
return new MccItemStackSnapshot
{
Type = item.Type.ToString(),
Count = item.Count
Count = item.Count,
Nbt = BuildNbt(item)
};
}
public static Dictionary<string, object>? BuildNbt(Item item)
{
if (item.Components is { Count: > 0 })
{
return item.Components
.Where(c => !string.IsNullOrEmpty(c.ComponentName))
.ToDictionary(
c => c.ComponentName,
c => (object)System.Text.Json.JsonSerializer.SerializeToElement(c, c.GetType())
);
}
return item.NBT is { Count: > 0 } ? item.NBT : null;
}
public static bool TryParseBlockQuery(string? query, out int? blockId, out int? blockMeta)
{
blockId = null;

View file

@ -216,6 +216,7 @@ public sealed class MccInventorySnapshotSlot
public required int Slot { get; init; }
public required string Type { get; init; }
public required int Count { get; init; }
public Dictionary<string, object>? Nbt { get; init; }
}
public sealed class MccInventorySnapshotResult
@ -239,6 +240,7 @@ public sealed class MccInventorySearchMatch
public required int Count { get; init; }
public required bool IsPlayerInventory { get; init; }
public int? HotbarSlot { get; init; }
public Dictionary<string, object>? Nbt { get; init; }
}
public sealed class MccInventorySearchResult