@akiojin/unity-editor-mcp
Version:
MCP server for Unity Editor integration - enables AI assistants to control Unity Editor
556 lines (524 loc) • 17.1 kB
JavaScript
// Tool definitions for Input Actions editing
// Action Map Management
export const createActionMapToolDefinition = {
name: 'create_action_map',
description: 'Create a new Action Map in an Input Actions asset',
inputSchema: {
type: 'object',
properties: {
assetPath: {
type: 'string',
description: 'Path to the Input Actions asset file'
},
mapName: {
type: 'string',
description: 'Name for the new Action Map'
},
actions: {
type: 'array',
description: 'Optional array of actions to add',
items: {
type: 'object',
properties: {
name: { type: 'string' },
type: { type: 'string', enum: ['Button', 'Value', 'PassThrough'] }
}
}
}
},
required: ['assetPath', 'mapName']
}
};
export const removeActionMapToolDefinition = {
name: 'remove_action_map',
description: 'Remove an Action Map from an Input Actions asset',
inputSchema: {
type: 'object',
properties: {
assetPath: {
type: 'string',
description: 'Path to the Input Actions asset file'
},
mapName: {
type: 'string',
description: 'Name of the Action Map to remove'
}
},
required: ['assetPath', 'mapName']
}
};
// Action Management
export const addInputActionToolDefinition = {
name: 'add_input_action',
description: 'Add a new Action to an Action Map',
inputSchema: {
type: 'object',
properties: {
assetPath: {
type: 'string',
description: 'Path to the Input Actions asset file'
},
mapName: {
type: 'string',
description: 'Name of the Action Map'
},
actionName: {
type: 'string',
description: 'Name for the new Action'
},
actionType: {
type: 'string',
description: 'Type of the action',
enum: ['Button', 'Value', 'PassThrough'],
default: 'Button'
}
},
required: ['assetPath', 'mapName', 'actionName']
}
};
export const removeInputActionToolDefinition = {
name: 'remove_input_action',
description: 'Remove an Action from an Action Map',
inputSchema: {
type: 'object',
properties: {
assetPath: {
type: 'string',
description: 'Path to the Input Actions asset file'
},
mapName: {
type: 'string',
description: 'Name of the Action Map'
},
actionName: {
type: 'string',
description: 'Name of the Action to remove'
}
},
required: ['assetPath', 'mapName', 'actionName']
}
};
// Binding Management
export const addInputBindingToolDefinition = {
name: 'add_input_binding',
description: 'Add a new Binding to an Action',
inputSchema: {
type: 'object',
properties: {
assetPath: {
type: 'string',
description: 'Path to the Input Actions asset file'
},
mapName: {
type: 'string',
description: 'Name of the Action Map'
},
actionName: {
type: 'string',
description: 'Name of the Action'
},
path: {
type: 'string',
description: 'Binding path (e.g., "<Keyboard>/space", "<Gamepad>/buttonSouth")'
},
groups: {
type: 'string',
description: 'Control scheme groups (e.g., "Keyboard&Mouse")'
},
interactions: {
type: 'string',
description: 'Interactions (e.g., "press", "hold")'
},
processors: {
type: 'string',
description: 'Processors (e.g., "scale", "invert")'
}
},
required: ['assetPath', 'mapName', 'actionName', 'path']
}
};
export const removeInputBindingToolDefinition = {
name: 'remove_input_binding',
description: 'Remove a Binding from an Action',
inputSchema: {
type: 'object',
properties: {
assetPath: {
type: 'string',
description: 'Path to the Input Actions asset file'
},
mapName: {
type: 'string',
description: 'Name of the Action Map'
},
actionName: {
type: 'string',
description: 'Name of the Action'
},
bindingIndex: {
type: 'number',
description: 'Index of the binding to remove'
},
bindingPath: {
type: 'string',
description: 'Path of the binding to remove (alternative to bindingIndex)'
}
},
required: ['assetPath', 'mapName', 'actionName']
}
};
export const removeAllBindingsToolDefinition = {
name: 'remove_all_bindings',
description: 'Remove all Bindings from an Action',
inputSchema: {
type: 'object',
properties: {
assetPath: {
type: 'string',
description: 'Path to the Input Actions asset file'
},
mapName: {
type: 'string',
description: 'Name of the Action Map'
},
actionName: {
type: 'string',
description: 'Name of the Action'
}
},
required: ['assetPath', 'mapName', 'actionName']
}
};
export const createCompositeBindingToolDefinition = {
name: 'create_composite_binding',
description: 'Create a composite binding (e.g., 2D Vector for WASD movement)',
inputSchema: {
type: 'object',
properties: {
assetPath: {
type: 'string',
description: 'Path to the Input Actions asset file'
},
mapName: {
type: 'string',
description: 'Name of the Action Map'
},
actionName: {
type: 'string',
description: 'Name of the Action'
},
compositeType: {
type: 'string',
description: 'Type of composite',
enum: ['2DVector', '1DAxis'],
default: '2DVector'
},
name: {
type: 'string',
description: 'Name for the composite binding'
},
bindings: {
type: 'object',
description: 'Binding paths for composite parts',
properties: {
up: { type: 'string' },
down: { type: 'string' },
left: { type: 'string' },
right: { type: 'string' },
negative: { type: 'string' },
positive: { type: 'string' }
}
},
groups: {
type: 'string',
description: 'Control scheme groups'
}
},
required: ['assetPath', 'mapName', 'actionName', 'bindings']
}
};
// Control Scheme Management
export const manageControlSchemesToolDefinition = {
name: 'manage_control_schemes',
description: 'Manage Control Schemes in an Input Actions asset',
inputSchema: {
type: 'object',
properties: {
assetPath: {
type: 'string',
description: 'Path to the Input Actions asset file'
},
operation: {
type: 'string',
description: 'Operation to perform',
enum: ['add', 'remove', 'modify']
},
schemeName: {
type: 'string',
description: 'Name of the control scheme'
},
devices: {
type: 'array',
description: 'List of device types (e.g., ["Keyboard", "Mouse", "Gamepad"])',
items: { type: 'string' }
}
},
required: ['assetPath', 'operation']
}
};
// Helper function to format Unity response
function formatUnityResponse(result, successMessage) {
if (!result || typeof result === 'string') {
return {
content: [{
type: 'text',
text: `Failed: Invalid response format`
}],
isError: true
};
}
if (result.error) {
return {
content: [{
type: 'text',
text: `Failed: ${result.error}`
}],
isError: true
};
}
if (result.success) {
let text = result.message || successMessage;
// Add any additional info from result
Object.keys(result).forEach(key => {
if (key !== 'success' && key !== 'message' && key !== 'error') {
text += `\n${key}: ${result[key]}`;
}
});
return {
content: [{
type: 'text',
text: text
}],
isError: false
};
}
return {
content: [{
type: 'text',
text: 'Operation completed'
}],
isError: false
};
}
// Handlers for Action Map Management
export async function createActionMapHandler(unityConnection, args) {
try {
if (!unityConnection.isConnected()) {
return {
content: [{
type: 'text',
text: 'Failed to create Action Map: Unity connection not available'
}],
isError: true
};
}
const result = await unityConnection.sendCommand('create_action_map', args);
return formatUnityResponse(result, `Created Action Map: ${args.mapName}`);
} catch (error) {
return {
content: [{
type: 'text',
text: `Failed to create Action Map: ${error.message}`
}],
isError: true
};
}
}
export async function removeActionMapHandler(unityConnection, args) {
try {
if (!unityConnection.isConnected()) {
return {
content: [{
type: 'text',
text: 'Failed to remove Action Map: Unity connection not available'
}],
isError: true
};
}
const result = await unityConnection.sendCommand('remove_action_map', args);
return formatUnityResponse(result, `Removed Action Map: ${args.mapName}`);
} catch (error) {
return {
content: [{
type: 'text',
text: `Failed to remove Action Map: ${error.message}`
}],
isError: true
};
}
}
// Handlers for Action Management
export async function addInputActionHandler(unityConnection, args) {
try {
if (!unityConnection.isConnected()) {
return {
content: [{
type: 'text',
text: 'Failed to add Input Action: Unity connection not available'
}],
isError: true
};
}
const result = await unityConnection.sendCommand('add_input_action', args);
return formatUnityResponse(result, `Added Action: ${args.actionName}`);
} catch (error) {
return {
content: [{
type: 'text',
text: `Failed to add Input Action: ${error.message}`
}],
isError: true
};
}
}
export async function removeInputActionHandler(unityConnection, args) {
try {
if (!unityConnection.isConnected()) {
return {
content: [{
type: 'text',
text: 'Failed to remove Input Action: Unity connection not available'
}],
isError: true
};
}
const result = await unityConnection.sendCommand('remove_input_action', args);
return formatUnityResponse(result, `Removed Action: ${args.actionName}`);
} catch (error) {
return {
content: [{
type: 'text',
text: `Failed to remove Input Action: ${error.message}`
}],
isError: true
};
}
}
// Handlers for Binding Management
export async function addInputBindingHandler(unityConnection, args) {
try {
if (!unityConnection.isConnected()) {
return {
content: [{
type: 'text',
text: 'Failed to add Input Binding: Unity connection not available'
}],
isError: true
};
}
const result = await unityConnection.sendCommand('add_input_binding', args);
return formatUnityResponse(result, `Added Binding: ${args.path}`);
} catch (error) {
return {
content: [{
type: 'text',
text: `Failed to add Input Binding: ${error.message}`
}],
isError: true
};
}
}
export async function removeInputBindingHandler(unityConnection, args) {
try {
if (!unityConnection.isConnected()) {
return {
content: [{
type: 'text',
text: 'Failed to remove Input Binding: Unity connection not available'
}],
isError: true
};
}
const result = await unityConnection.sendCommand('remove_input_binding', args);
return formatUnityResponse(result, 'Removed Binding');
} catch (error) {
return {
content: [{
type: 'text',
text: `Failed to remove Input Binding: ${error.message}`
}],
isError: true
};
}
}
export async function removeAllBindingsHandler(unityConnection, args) {
try {
if (!unityConnection.isConnected()) {
return {
content: [{
type: 'text',
text: 'Failed to remove all bindings: Unity connection not available'
}],
isError: true
};
}
const result = await unityConnection.sendCommand('remove_all_bindings', args);
return formatUnityResponse(result, `Removed all bindings from ${args.actionName}`);
} catch (error) {
return {
content: [{
type: 'text',
text: `Failed to remove all bindings: ${error.message}`
}],
isError: true
};
}
}
export async function createCompositeBindingHandler(unityConnection, args) {
try {
if (!unityConnection.isConnected()) {
return {
content: [{
type: 'text',
text: 'Failed to create composite binding: Unity connection not available'
}],
isError: true
};
}
const result = await unityConnection.sendCommand('create_composite_binding', args);
return formatUnityResponse(result, `Created composite binding: ${args.name || args.compositeType}`);
} catch (error) {
return {
content: [{
type: 'text',
text: `Failed to create composite binding: ${error.message}`
}],
isError: true
};
}
}
// Handler for Control Scheme Management
export async function manageControlSchemesHandler(unityConnection, args) {
try {
if (!unityConnection.isConnected()) {
return {
content: [{
type: 'text',
text: 'Failed to manage control schemes: Unity connection not available'
}],
isError: true
};
}
const result = await unityConnection.sendCommand('manage_control_schemes', args);
const operationText = args.operation === 'add' ? 'Added' : args.operation === 'remove' ? 'Removed' : 'Modified';
return formatUnityResponse(result, `${operationText} control scheme: ${args.schemeName}`);
} catch (error) {
return {
content: [{
type: 'text',
text: `Failed to manage control schemes: ${error.message}`
}],
isError: true
};
}
}