Skip to content

Instantly share code, notes, and snippets.

@vlaaad
Last active January 31, 2026 05:05
Show Gist options
  • Select an option

  • Save vlaaad/395bd021e8a4ba6561fd4f8d3562456f to your computer and use it in GitHub Desktop.

Select an option

Save vlaaad/395bd021e8a4ba6561fd4f8d3562456f to your computer and use it in GitHub Desktop.
Defold MCP server

Steps to try it out:

  1. Add mcp.editor_script to a Defold project
  2. Project -> Reload Editor Scripts
  3. It will print something like MCP running on http://localhost:50489/mcp — your port will be different
  4. Ensure that npx mcp-remote http://localhost:50489/mcp --transport http-only successfully runs in your terminal.
  5. Edit Claude desktop config to refer to the server (see claude_desktop_config.json for reference)
  6. Restart Claude and enjoy!
{
"mcpServers": {
"defold": {
"command": "npx",
"args": ["mcp-remote", "http://localhost:50489/mcp", "--transport", "http-only"]
}
}
}
local M = {}
print(("MCP running on %s/mcp"):format(http.server.local_url))
function M.get_http_server_routes()
return {
http.server.route("/mcp", "POST", "json", function(request)
local method = request.body.method
if method == "initialize" then
return http.server.json_response({
jsonrpc = "2.0",
id = request.body.id,
result = {
protocolVersion = "2024-11-05",
serverInfo = {
name = ("Defold (%s)"):format(editor.get("/game.project", "project.title")),
version = editor.version or "dev"
},
capabilities = {
logging = {},
prompts = {listChanged = true},
resources = {
subscribe = true,
listChanged = true
},
tools = {listChanged = true}
}
}
})
elseif method == "tools/list" then
return http.server.json_response({
jsonrpc = "2.0",
id = request.body.id,
result = {tools = {
{
name = "eval_editor_script",
title = "Eval editor script",
description = "Eval lua code as editor script. Documentation: https://defold.com/ref/stable/editor-lua/ Some examples: `editor.get('/', 'children')`, `editor.get('/game.project', 'bootstrap.main_collection')`, `return editor.get('/logic.lua', 'text')`",
inputSchema = {
type = "object",
properties = {lua_code = {type = "string"}},
required = {"lua_code"}
}
}
}}
})
elseif method == "tools/call" then
local tool_name = request.body.params.name
if tool_name == "eval_editor_script" then
local code = request.body.params.arguments.lua_code
local content = {}
local print_fn = function(...)
local s = ""
for i = 1, select("#", ...) do
if i ~= 1 then
s = s .. " "
end
s = s .. tostring(select(i, ...))
end
content[#content+1] = {type = "text", text = s}
end
local env = {}
for key, value in pairs(_G) do
env[key] = value
end
env.print = print_fn
local f, err = load(code, "eval", "t", env)
local success, result
if f then
success, result = pcall(f)
else
success, result = false, err
end
content[#content+1] = {type = "text", text = tostring(result)}
return http.server.json_response({
jsonrpc = "2.0",
id = request.body.id,
result = {
isError = not success,
content = content
}
})
end
elseif method == "resources/list" then
return http.server.json_response({
jsonrpc = "2.0",
id = request.body.id,
result = {}
})
elseif method == "prompts/list" then
return http.server.json_response({
jsonrpc = "2.0",
id = request.body.id,
result = {}
})
elseif method == "notifications/initialized" then
return http.server.response()
else
pprint(request)
end
end)
}
end
return M
@akarca
Copy link

akarca commented Jan 30, 2026

What is the purpose of this mcp? Please explain how to use it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment