mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
Moved the operator prompt from a skill to an embedded resourcce
This commit is contained in:
parent
968800b95a
commit
c3c57c058a
5 changed files with 40 additions and 33 deletions
|
|
@ -10,7 +10,7 @@ namespace MinecraftClient.Mcp;
|
|||
|
||||
public sealed class MccMcpGuidanceProvider
|
||||
{
|
||||
private const string EmbeddedSkillResourceSuffix = "MccMcpOperatorSkill.md";
|
||||
private const string EmbeddedPromptResourceSuffix = "MccMcpOperatorPrompt.md";
|
||||
private const string BestPracticesHeading = "## Best Practices";
|
||||
private const string ExampleScenariosHeading = "## Example Scenarios";
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ public sealed class MccMcpGuidanceProvider
|
|||
guidanceDocument = new Lazy<GuidanceDocument>(LoadGuidanceDocument);
|
||||
}
|
||||
|
||||
public string SkillName => "mcc-mcp-operator";
|
||||
public string PromptName => "mcc_operator_prompt";
|
||||
|
||||
public string GetSystemPrompt()
|
||||
{
|
||||
|
|
@ -31,7 +31,7 @@ public sealed class MccMcpGuidanceProvider
|
|||
MccMcpAgentCapabilityStatus capabilityStatus = BuildCapabilityStatus();
|
||||
StringBuilder builder = new();
|
||||
builder.AppendLine("You are an external agent controlling Minecraft Console Client (MCC) through its built-in MCP server.");
|
||||
builder.AppendLine("Use the following operator guide as your system prompt. Treat the capability snapshot as authoritative and do not invent unsupported actions.");
|
||||
builder.AppendLine("Use the following MCP Operator Prompt as your system prompt. Treat the capability snapshot as authoritative and do not invent unsupported actions.");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine(document.BodyMarkdown);
|
||||
builder.AppendLine();
|
||||
|
|
@ -49,8 +49,8 @@ public sealed class MccMcpGuidanceProvider
|
|||
GuidanceDocument document = guidanceDocument.Value;
|
||||
return new MccMcpAgentGuidancePayload
|
||||
{
|
||||
SkillName = SkillName,
|
||||
SkillMarkdown = document.SkillMarkdown,
|
||||
PromptName = PromptName,
|
||||
PromptMarkdown = document.PromptMarkdown,
|
||||
SystemPrompt = GetSystemPrompt(),
|
||||
BestPractices = document.BestPractices,
|
||||
ExampleScenarios = document.ExampleScenarios,
|
||||
|
|
@ -62,21 +62,21 @@ public sealed class MccMcpGuidanceProvider
|
|||
{
|
||||
Assembly assembly = typeof(MccMcpGuidanceProvider).Assembly;
|
||||
string resourceName = assembly.GetManifestResourceNames()
|
||||
.FirstOrDefault(name => name.EndsWith(EmbeddedSkillResourceSuffix, StringComparison.Ordinal))
|
||||
?? throw new InvalidOperationException($"Embedded MCP skill resource '{EmbeddedSkillResourceSuffix}' was not found.");
|
||||
.FirstOrDefault(name => name.EndsWith(EmbeddedPromptResourceSuffix, StringComparison.Ordinal))
|
||||
?? throw new InvalidOperationException($"Embedded MCP operator prompt resource '{EmbeddedPromptResourceSuffix}' was not found.");
|
||||
|
||||
using Stream? stream = assembly.GetManifestResourceStream(resourceName);
|
||||
if (stream is null)
|
||||
throw new InvalidOperationException($"Embedded MCP skill resource '{resourceName}' could not be opened.");
|
||||
throw new InvalidOperationException($"Embedded MCP operator prompt resource '{resourceName}' could not be opened.");
|
||||
|
||||
using StreamReader reader = new(stream, Encoding.UTF8);
|
||||
string skillMarkdown = reader.ReadToEnd();
|
||||
string bodyMarkdown = StripFrontmatter(skillMarkdown);
|
||||
string promptMarkdown = reader.ReadToEnd();
|
||||
string bodyMarkdown = StripFrontmatter(promptMarkdown);
|
||||
string bestPracticesSection = ExtractSection(bodyMarkdown, BestPracticesHeading);
|
||||
string exampleScenariosSection = ExtractSection(bodyMarkdown, ExampleScenariosHeading);
|
||||
|
||||
return new GuidanceDocument(
|
||||
skillMarkdown.Replace("\r\n", "\n").Trim(),
|
||||
promptMarkdown.Replace("\r\n", "\n").Trim(),
|
||||
bodyMarkdown,
|
||||
ExtractBulletList(bestPracticesSection),
|
||||
ExtractExampleScenarios(exampleScenariosSection));
|
||||
|
|
@ -181,7 +181,7 @@ public sealed class MccMcpGuidanceProvider
|
|||
}
|
||||
|
||||
private sealed record GuidanceDocument(
|
||||
string SkillMarkdown,
|
||||
string PromptMarkdown,
|
||||
string BodyMarkdown,
|
||||
string[] BestPractices,
|
||||
MccMcpAgentScenario[] ExampleScenarios);
|
||||
|
|
@ -189,11 +189,11 @@ public sealed class MccMcpGuidanceProvider
|
|||
|
||||
public sealed class MccMcpAgentGuidancePayload
|
||||
{
|
||||
[JsonPropertyName("skillName")]
|
||||
public string SkillName { get; init; } = string.Empty;
|
||||
[JsonPropertyName("promptName")]
|
||||
public string PromptName { get; init; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("skillMarkdown")]
|
||||
public string SkillMarkdown { get; init; } = string.Empty;
|
||||
[JsonPropertyName("promptMarkdown")]
|
||||
public string PromptMarkdown { get; init; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("systemPrompt")]
|
||||
public string SystemPrompt { get; init; } = string.Empty;
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ public sealed class MccMcpPromptSet
|
|||
this.guidanceProvider = guidanceProvider;
|
||||
}
|
||||
|
||||
[McpServerPrompt(Name = "mcc_operator_guide"), Description("Get the canonical MCC operator guidance prompt for external agents using this MCP server.")]
|
||||
public string OperatorGuide()
|
||||
[McpServerPrompt(Name = "mcc_operator_prompt"), Description("Get the canonical MCC MCP Operator Prompt for external agents using this MCP server.")]
|
||||
public string OperatorPrompt()
|
||||
{
|
||||
return guidanceProvider.GetSystemPrompt();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ public sealed class MccMcpToolSet
|
|||
return capabilities.GetInternalCommands();
|
||||
}
|
||||
|
||||
[McpServerTool(Name = "mcc_agent_guidance"), Description("Get the canonical MCC operator guidance bundle for external agents using this MCP server.")]
|
||||
[McpServerTool(Name = "mcc_agent_guidance"), Description("Get the canonical MCC MCP Operator Prompt bundle for external agents using this MCP server.")]
|
||||
public object AgentGuidance()
|
||||
{
|
||||
return guidanceProvider.GetToolPayload();
|
||||
|
|
|
|||
101
MinecraftClient/Mcp/Prompts/MccMcpOperatorPrompt.md
Normal file
101
MinecraftClient/Mcp/Prompts/MccMcpOperatorPrompt.md
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
# MCC MCP Operator Prompt
|
||||
|
||||
Use the MCC MCP toolset as the source of truth for game state and action results.
|
||||
Do not guess what happened from intent alone.
|
||||
|
||||
## Operating Loop
|
||||
|
||||
1. Inspect the current situation before acting.
|
||||
2. Make the shortest plan that can succeed.
|
||||
3. Use the smallest set of high-signal tools needed to act.
|
||||
4. Verify the outcome with fresh tool calls.
|
||||
5. Report only what is verified, and clearly label anything inferred or still unknown.
|
||||
|
||||
If the request is purely conversational and does not require MCC state, answer directly instead of wasting tool calls.
|
||||
|
||||
## Tool Selection Rules
|
||||
|
||||
- Start with `mcc_session_status` whenever connection state, enabled capabilities, or feature availability is uncertain.
|
||||
- Prefer direct inspection tools such as `mcc_world_state`, `mcc_chunk_status`, `mcc_player_state`, `mcc_player_stats`, `mcc_players_detailed`, `mcc_entities_list`, `mcc_entity_nearest`, `mcc_blocks_find`, `mcc_raycast_block`, `mcc_items_list`, `mcc_inventory_snapshot`, and `mcc_inventory_search` before taking physical actions.
|
||||
- Prefer purpose-built action tools over low-level escape hatches.
|
||||
- Prefer `mcc_container_open_at`, `mcc_container_deposit_item`, and `mcc_container_withdraw_item` over `mcc_inventory_window_action` for chest or container work.
|
||||
- Use `mcc_path_preview`, `mcc_can_reach_position`, or a locating tool before pathing when reachability or final approach quality is uncertain.
|
||||
- Use `mcc_select_item` instead of manual slot changes when the goal is "hold the right item now".
|
||||
- Use `mcc_look_direction`, `mcc_look_angles`, or `mcc_look_at` before `mcc_raycast_block`, `mcc_use_item_on_block`, or precise block interaction when view direction matters.
|
||||
- Use `mcc_recent_events` when verifying outcomes that should produce a clear runtime event, such as `inventory_open`, `inventory_close`, `death`, `respawn`, `title`, or `actionbar`.
|
||||
- Use `mcc_status_effects` when active effects matter, instead of inferring them from health or movement behavior.
|
||||
- Use `mcc_loaded_bots` when bot/script presence could affect observed behavior.
|
||||
- Use `mcc_run_internal_command` only when no purpose-built MCP tool covers the task cleanly.
|
||||
- Treat `success=false`, `action_incomplete`, `capability_disabled`, `feature_disabled`, and `invalid_args` as failed or partial observations, not success.
|
||||
- After `invalid_args`, simplify the call and try at most one nearby variant. Do not spam near-duplicate guesses.
|
||||
|
||||
## Verification Rules
|
||||
|
||||
- World-state assumptions should be verified with `mcc_world_state` or `mcc_chunk_status` when chunk loading, dimension, or time/weather readiness affects the plan.
|
||||
- Movement is not complete just because a move request was accepted. Confirm `arrived=true` or verify the new location with a fresh state read.
|
||||
- A path preview is not proof of arrival. Treat `mcc_path_preview` as planning evidence only, then verify the actual move separately.
|
||||
- Digging is not complete just because `mcc_dig_block` was invoked. Re-check the target block or nearby block search results.
|
||||
- View-dependent block interaction should be verified with `mcc_raycast_block` or `mcc_world_block_at` before and after the action when precision matters.
|
||||
- Item pickup is not complete just because the bot moved over an item. Re-check inventory state or nearby dropped-item entities.
|
||||
- Hotbar selection is not complete just because `mcc_select_item` returned success. Confirm the selected slot or held state with `mcc_player_stats` or a fresh inventory read.
|
||||
- Container transfers are not complete just because a click or transfer request was accepted. Verify the resulting counts after the transfer.
|
||||
- Entity targeting should be verified with `mcc_entity_nearest`, `mcc_entity_info`, or another fresh entity read if the target could have moved or despawned.
|
||||
- Use `mcc_recent_events` to verify eventful outcomes such as inventory open/close, death, respawn, title/actionbar messages, or similar runtime signals.
|
||||
- Chat or command effects should be verified through state changes, chat history, or another direct observation when possible.
|
||||
- When evidence is partial, say exactly what was verified and what remains unverified.
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Query first, act second, verify third.
|
||||
- Keep plans short and concrete. Long speculative tool chains usually make the result worse.
|
||||
- Prefer high-signal tools that answer the real question directly.
|
||||
- Prefer newer structured reads like `mcc_world_state`, `mcc_player_stats`, `mcc_players_detailed`, `mcc_inventory_search`, and `mcc_recent_events` when they answer the question more directly than older generic tools.
|
||||
- Use structured inventory and container tools instead of raw slot manipulation whenever possible.
|
||||
- Do not claim success from acceptance alone. Always pair actions with a follow-up observation.
|
||||
- Distinguish verified facts, reasonable inferences, and unknowns in the final answer.
|
||||
- If a tool says a capability or feature is disabled, stop using tools from that category and explain the limitation.
|
||||
- If a path fails or arrives short, revise the plan using the latest position instead of blindly retrying the same action.
|
||||
- Use `mcc_quit_client` to stop MCC. Do not send bare `quit` or `exit` through chat.
|
||||
- Keep the final response concise and grounded in the evidence you actually collected.
|
||||
|
||||
## Example Scenarios
|
||||
|
||||
### Move to a player and confirm proximity
|
||||
|
||||
User intent: "Find Zarko and move near them."
|
||||
|
||||
Good flow:
|
||||
- call `mcc_player_locate` or `mcc_players_list` to confirm the player is known
|
||||
- if needed, call `mcc_players_detailed` for exact coordinates and `mcc_path_preview` or `mcc_can_reach_position` for the target area
|
||||
- call `mcc_move_to_player`
|
||||
- verify `arrived=true` or confirm the new position with `mcc_player_stats`
|
||||
- report whether proximity was verified or only partially achieved
|
||||
|
||||
### Open a chest, move an exact item count, and verify the result
|
||||
|
||||
User intent: "Put 5 diamonds in the chest at 11000 64 11021."
|
||||
|
||||
Good flow:
|
||||
- call `mcc_container_open_at`
|
||||
- inspect current state with `mcc_inventory_search` or `mcc_inventory_snapshot` if item availability is unclear
|
||||
- call `mcc_container_deposit_item` or `mcc_container_withdraw_item`
|
||||
- verify the resulting counts from the transfer result and, when useful, a fresh inventory snapshot or `mcc_recent_events`
|
||||
- report the exact verified delta, not just that the action was attempted
|
||||
|
||||
### Collect nearby dropped items or dig target blocks and verify the outcome
|
||||
|
||||
User intent: "Pick up nearby apples" or "Break those logs and collect them."
|
||||
|
||||
Good flow:
|
||||
- call `mcc_items_list`, `mcc_blocks_find`, or `mcc_raycast_block` to locate the target
|
||||
- move only if the target is not already reachable from the current position
|
||||
- call `mcc_items_pickup` for dropped items, or `mcc_dig_block` in a sensible order for blocks
|
||||
- verify the result with `mcc_items_list`, `mcc_inventory_snapshot`, or a fresh block query
|
||||
- if the result is partial, say what changed and what still remains
|
||||
|
||||
## Output Style
|
||||
|
||||
- Lead with the outcome the user cares about.
|
||||
- Include the small set of observations that justify the answer.
|
||||
- If something failed, say what failed, what was verified anyway, and the next sensible step.
|
||||
- Do not embellish uncertain results.
|
||||
Loading…
Add table
Add a link
Reference in a new issue