Difference Between MCP Resources and Tools in Unity MCP
MCP resources are read-only endpoints that expose Unity state data without side effects, while MCP tools are read-write operations that modify the Unity editor, distinguished by separate decorators (@mcp_for_unity_resource vs @mcp_for_unity_tool) and invocation patterns in the CoplayDev/unity-mcp server.
The CoplayDev/unity-mcp repository implements the Model Context Protocol (MCP) to bridge AI assistants with the Unity editor. Understanding the difference between MCP resources and tools is essential for developers building integrations, as these two entity types serve fundamentally different purposes in the server architecture.
Core Architectural Distinctions
Purpose and Side Effects
MCP Resources provide read-only exposure of Unity state. They retrieve information such as the list of running Unity instances, current selection data, or project metadata without altering the editor. Because they produce no side effects, resources are safe to invoke repeatedly.
MCP Tools perform read-write actions that mutate the Unity editor. These operations create GameObjects, edit materials, run tests, or modify scene assets. Unlike resources, tools change project state and may require specific permissions or user confirmation.
Registration Patterns
Resources are declared with the @mcp_for_unity_resource decorator in Server/src/services/resources/. Tools use the @mcp_for_unity_tool decorator in Server/src/services/tools/. This separation ensures the MCP server correctly categorizes capabilities for discovery and permission management.
How MCP Resources Expose Unity State
Resources are invoked via resource URIs such as mcpforunity://instances. The client sends a simple request and receives a JSON payload containing the requested data.
In HTTP mode, the implementation queries the central PluginHub. For stdio mode, it queries the local connection pool. The return structure typically includes fields like success, instance_count, and data arrays, with no mutations occurring in the editor.
The unity_instances resource in Server/src/services/resources/unity_instances.py demonstrates this pattern:
import json
from fastmcp import Context
from services.registry import mcp_for_unity_resource
async def list_instances(ctx: Context):
# Resources are invoked via their URI; the client library builds the request.
result = await ctx.invoke_resource("mcpforunity://instances")
print(json.dumps(result, indent=2))
# In a real MCP session `ctx` is supplied by the server; the call returns:
# {
# "success": true,
# "transport": "http",
# "instance_count": 2,
# "instances": [
# {"id": "MyGame@a1b2c3d4", "name": "MyGame", "hash": "a1b2c3d4", ...},
# {"id": "AnotherProj@e5f6g7h8", "name": "AnotherProj", "hash": "e5f6g7h8", ...}
# ]
# }
How MCP Tools Modify the Editor
Tools are invoked by tool name (e.g., manage_material) with a structured argument list. The request is routed to a C# handler that may mutate the editor state. Unlike resources, tools always forward requests to a specific Unity instance via send_with_unity_instance (or a legacy retry helper).
The return value typically includes success, message, and the outcome of the performed action, such as a created material ID.
The manage_material tool in Server/src/services/tools/manage_material.py illustrates this behavior:
import json
from fastmcp import Context
from services.tools.manage_material import manage_material
async def create_material(ctx: Context):
result = await manage_material(
ctx,
action="create",
shader="Standard",
material_path="Assets/Materials/NewMat.mat",
properties={"_Glossiness": 0.5, "_Metallic": 0.2},
)
print(json.dumps(result, indent=2))
# Expected output (simplified)
# {
# "address": true,
# "message": "Material created.",
# "materialId": "12345"
# }
Implementation File Structure
The unity-mcp server organizes resources and tools into separate directories with auto-discovery mechanisms:
- Resource Implementation:
Server/src/services/resources/unity_instances.py— Provides the read-onlyunity_instancesresource. - Tool Implementation:
Server/src/services/tools/manage_material.py— Implements themanage_materialcommand for creating or editing Unity materials. - Resource Registry:
Server/src/services/resources/__init__.py— Auto-discovers all resources under theresources/package. - Tool Registry:
Server/src/services/tools/__init__.py— Auto-discovers all tools under thetools/package.
This architecture enforces a clear separation: resources expose Unity state without side effects, while tools perform actions that change the editor.
Summary
- MCP resources are read-only queries that expose Unity state (instances, selection, project info) without side effects, while MCP tools are read-write operations that modify assets, scenes, or editor settings.
- Resources use the
@mcp_for_unity_resourcedecorator inServer/src/services/resources/; tools use@mcp_for_unity_toolinServer/src/services/tools/. - Resources are accessed via URI (e.g.,
mcpforunity://instances) and query thePluginHubor connection pool; tools are invoked by name with arguments and usesend_with_unity_instanceto target specific Unity instances. - Resources appear under the Resources pane in MCP documentation and are always available; tools appear under the Tools pane and may require specific permissions (only the
coretool group is enabled by default).
Frequently Asked Questions
Can MCP resources modify Unity project files?
No. According to the CoplayDev/unity-mcp source code, resources are strictly read-only and designed to expose state data without side effects. They retrieve information such as running instances or current selection but cannot create, edit, or delete assets. Only MCP tools can modify the editor state.
How do I register a new MCP tool in unity-mcp?
Define your tool function in a file under Server/src/services/tools/ and decorate it with @mcp_for_unity_tool. The Server/src/services/tools/__init__.py registry will auto-discover your tool during server initialization. Your implementation should forward requests to Unity using send_with_unity_instance and return a result object with success and message fields.
What transport mechanism does unity-mcp use for resources vs tools?
Resources use different transport handling depending on the mode: in HTTP mode, they query the central PluginHub, while in stdio mode, they query the local connection pool. Tools always forward requests to a specific Unity instance via send_with_unity_instance, ensuring that mutating operations target the correct editor process.
Are MCP resources always available while tools require permission?
Yes. Resources are always available to AI assistants because they are read-only and safe to invoke. Tools, however, follow a permission model where only specific groups are enabled by default (typically the core group). This distinction prevents accidental modifications to the Unity project while allowing free access to state information.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →