Skip to content

Commit c4bb1bf

Browse files
committed
Initial MCP server implementation
1 parent 4583df0 commit c4bb1bf

29 files changed

Lines changed: 1684 additions & 0 deletions

Makefile.common

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2404,6 +2404,15 @@ ifeq ($(HAVE_NETWORKING), 1)
24042404
network/netplay/netplay_frontend.o \
24052405
network/netplay/netplay_room_parse.o
24062406

2407+
# MCP Server
2408+
ifeq ($(HAVE_MCP), 1)
2409+
DEFINES += -DHAVE_MCP
2410+
OBJ += network/mcp/mcp_server.o \
2411+
network/mcp/mcp_http_transport.o \
2412+
network/mcp/mcp_adapter.o \
2413+
network/mcp/mcp_adapter_tool_list.o
2414+
endif
2415+
24072416
# RetroAchievements
24082417
ifeq ($(HAVE_CHEEVOS), 1)
24092418
DEFINES += -DHAVE_CHEEVOS -DRC_CLIENT_SUPPORTS_HASH

config.def.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1469,6 +1469,11 @@
14691469
#define DEFAULT_NETWORK_REMOTE_BASE_PORT 55400
14701470
#define DEFAULT_STDIN_CMD_ENABLE false
14711471

1472+
/* Enable MCP (Model Context Protocol) server. */
1473+
#define DEFAULT_MCP_SERVER_ENABLE false
1474+
#define DEFAULT_MCP_SERVER_ADDRESS "127.0.0.1"
1475+
#define DEFAULT_MCP_SERVER_PORT 7878
1476+
14721477
#define DEFAULT_NETWORK_BUILDBOT_AUTO_EXTRACT_ARCHIVE true
14731478
#define DEFAULT_NETWORK_BUILDBOT_SHOW_EXPERIMENTAL_CORES false
14741479

configuration.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,6 +1602,10 @@ static struct config_array_setting *populate_settings_array(
16021602

16031603
#ifdef HAVE_NETWORKING
16041604
SETTING_ARRAY("netplay_mitm_server", settings->arrays.netplay_mitm_server, false, NULL, true);
1605+
#ifdef HAVE_MCP
1606+
SETTING_ARRAY("mcp_server_address", settings->arrays.mcp_server_address, true, DEFAULT_MCP_SERVER_ADDRESS, false);
1607+
SETTING_ARRAY("mcp_server_password", settings->arrays.mcp_server_password, false, NULL, true);
1608+
#endif
16051609
SETTING_ARRAY("webdav_url", settings->arrays.webdav_url, false, NULL, true);
16061610
SETTING_ARRAY("webdav_username", settings->arrays.webdav_username, false, NULL, true);
16071611
SETTING_ARRAY("webdav_password", settings->arrays.webdav_password, false, NULL, true);
@@ -2226,6 +2230,10 @@ static struct config_bool_setting *populate_settings_bool(
22262230
SETTING_BOOL("stdin_cmd_enable", &settings->bools.stdin_cmd_enable, true, DEFAULT_STDIN_CMD_ENABLE, false);
22272231
#endif
22282232

2233+
#ifdef HAVE_MCP
2234+
SETTING_BOOL("mcp_server_enable", &settings->bools.mcp_server_enable, true, DEFAULT_MCP_SERVER_ENABLE, false);
2235+
#endif
2236+
22292237
#ifdef HAVE_NETWORKING
22302238
SETTING_BOOL("netplay_show_only_connectable", &settings->bools.netplay_show_only_connectable, true, DEFAULT_NETPLAY_SHOW_ONLY_CONNECTABLE, false);
22312239
SETTING_BOOL("netplay_show_only_installed_cores", &settings->bools.netplay_show_only_installed_cores, true, DEFAULT_NETPLAY_SHOW_ONLY_INSTALLED_CORES, false);
@@ -2624,6 +2632,9 @@ static struct config_uint_setting *populate_settings_uint(
26242632
#ifdef HAVE_COMMAND
26252633
SETTING_UINT("network_cmd_port", &settings->uints.network_cmd_port, true, DEFAULT_NETWORK_CMD_PORT, false);
26262634
#endif
2635+
#ifdef HAVE_MCP
2636+
SETTING_UINT("mcp_server_port", &settings->uints.mcp_server_port, true, DEFAULT_MCP_SERVER_PORT, false);
2637+
#endif
26272638
#ifdef HAVE_NETWORKGAMEPAD
26282639
SETTING_UINT("network_remote_base_port", &settings->uints.network_remote_base_port, true, DEFAULT_NETWORK_REMOTE_BASE_PORT, false);
26292640
#endif

configuration.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,9 @@ typedef struct settings
243243
unsigned replay_max_keep;
244244
unsigned savestate_max_keep;
245245
unsigned network_cmd_port;
246+
#ifdef HAVE_MCP
247+
unsigned mcp_server_port;
248+
#endif
246249
unsigned network_remote_base_port;
247250
unsigned keymapper_port;
248251
unsigned cloud_sync_sync_mode;
@@ -539,6 +542,10 @@ typedef struct settings
539542
char audio_device[NAME_MAX_LENGTH];
540543
char camera_device[NAME_MAX_LENGTH];
541544
char netplay_mitm_server[NAME_MAX_LENGTH];
545+
#ifdef HAVE_MCP
546+
char mcp_server_address[64];
547+
char mcp_server_password[NAME_MAX_LENGTH];
548+
#endif
542549
char webdav_url[NAME_MAX_LENGTH];
543550
char webdav_username[NAME_MAX_LENGTH];
544551
char webdav_password[NAME_MAX_LENGTH];
@@ -1061,6 +1068,9 @@ typedef struct settings
10611068
bool save_file_compression;
10621069
bool savestate_file_compression;
10631070
bool network_cmd_enable;
1071+
#ifdef HAVE_MCP
1072+
bool mcp_server_enable;
1073+
#endif
10641074
bool stdin_cmd_enable;
10651075
bool keymapper_enable;
10661076
bool network_remote_enable;

griffin/griffin.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,6 +1708,16 @@ STEAM INTEGRATION USING MIST
17081708
#include "../network/presence.c"
17091709
#endif
17101710

1711+
/*============================================================
1712+
MCP SERVER
1713+
============================================================ */
1714+
#ifdef HAVE_MCP
1715+
#include "../network/mcp/mcp_server.c"
1716+
#include "../network/mcp/mcp_http_transport.c"
1717+
#include "../network/mcp/mcp_adapter.c"
1718+
#include "../network/mcp/mcp_adapter_tool_list.c"
1719+
#endif
1720+
17111721
/*============================================================
17121722
CLOUD SYNC
17131723
============================================================ */

intl/msg_hash_lbl.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2506,6 +2506,22 @@ MSG_HASH(
25062506
MENU_ENUM_LABEL_NETWORK_CMD_PORT,
25072507
"network_cmd_port"
25082508
)
2509+
MSG_HASH(
2510+
MENU_ENUM_LABEL_MCP_SERVER_ENABLE,
2511+
"mcp_server_enable"
2512+
)
2513+
MSG_HASH(
2514+
MENU_ENUM_LABEL_MCP_SERVER_ADDRESS,
2515+
"mcp_server_address"
2516+
)
2517+
MSG_HASH(
2518+
MENU_ENUM_LABEL_MCP_SERVER_PORT,
2519+
"mcp_server_port"
2520+
)
2521+
MSG_HASH(
2522+
MENU_ENUM_LABEL_MCP_SERVER_PASSWORD,
2523+
"mcp_server_password"
2524+
)
25092525
MSG_HASH(
25102526
MENU_ENUM_LABEL_NETWORK_INFORMATION,
25112527
"network_information"

intl/msg_hash_us.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7606,6 +7606,38 @@ MSG_HASH(
76067606
MENU_ENUM_LABEL_VALUE_NETWORK_CMD_PORT,
76077607
"Network Command Port"
76087608
)
7609+
MSG_HASH(
7610+
MENU_ENUM_LABEL_VALUE_MCP_SERVER_ENABLE,
7611+
"MCP Server"
7612+
)
7613+
MSG_HASH(
7614+
MENU_ENUM_SUBLABEL_MCP_SERVER_ENABLE,
7615+
"Enable the Model Context Protocol (MCP) server for AI assistant integration."
7616+
)
7617+
MSG_HASH(
7618+
MENU_ENUM_LABEL_VALUE_MCP_SERVER_ADDRESS,
7619+
"MCP Server Address"
7620+
)
7621+
MSG_HASH(
7622+
MENU_ENUM_SUBLABEL_MCP_SERVER_ADDRESS,
7623+
"Bind address for the MCP HTTP server (e.g. 127.0.0.1)."
7624+
)
7625+
MSG_HASH(
7626+
MENU_ENUM_LABEL_VALUE_MCP_SERVER_PORT,
7627+
"MCP Server Port"
7628+
)
7629+
MSG_HASH(
7630+
MENU_ENUM_SUBLABEL_MCP_SERVER_PORT,
7631+
"Port for the MCP HTTP server to listen on."
7632+
)
7633+
MSG_HASH(
7634+
MENU_ENUM_LABEL_VALUE_MCP_SERVER_PASSWORD,
7635+
"MCP Server Password"
7636+
)
7637+
MSG_HASH(
7638+
MENU_ENUM_SUBLABEL_MCP_SERVER_PASSWORD,
7639+
"Password for MCP server authentication (Bearer token). Leave empty to disable auth."
7640+
)
76097641
MSG_HASH(
76107642
MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_ENABLE,
76117643
"Network RetroPad"

menu/cbs/menu_cbs_sublabel.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,12 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_require_slaves, MENU_
944944
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_check_frames, MENU_ENUM_SUBLABEL_NETPLAY_CHECK_FRAMES)
945945
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_nat_traversal, MENU_ENUM_SUBLABEL_NETPLAY_NAT_TRAVERSAL)
946946
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_stdin_cmd_enable, MENU_ENUM_SUBLABEL_STDIN_CMD_ENABLE)
947+
#ifdef HAVE_MCP
948+
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_mcp_server_enable, MENU_ENUM_SUBLABEL_MCP_SERVER_ENABLE)
949+
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_mcp_server_address, MENU_ENUM_SUBLABEL_MCP_SERVER_ADDRESS)
950+
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_mcp_server_port, MENU_ENUM_SUBLABEL_MCP_SERVER_PORT)
951+
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_mcp_server_password, MENU_ENUM_SUBLABEL_MCP_SERVER_PASSWORD)
952+
#endif
947953
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_mouse_enable, MENU_ENUM_SUBLABEL_MOUSE_ENABLE)
948954
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_pointer_enable, MENU_ENUM_SUBLABEL_POINTER_ENABLE)
949955
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_icon_thumbnails, MENU_ENUM_SUBLABEL_ICON_THUMBNAILS)
@@ -3769,6 +3775,20 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
37693775
case MENU_ENUM_LABEL_STDIN_CMD_ENABLE:
37703776
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_stdin_cmd_enable);
37713777
break;
3778+
#ifdef HAVE_MCP
3779+
case MENU_ENUM_LABEL_MCP_SERVER_ENABLE:
3780+
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_mcp_server_enable);
3781+
break;
3782+
case MENU_ENUM_LABEL_MCP_SERVER_ADDRESS:
3783+
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_mcp_server_address);
3784+
break;
3785+
case MENU_ENUM_LABEL_MCP_SERVER_PORT:
3786+
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_mcp_server_port);
3787+
break;
3788+
case MENU_ENUM_LABEL_MCP_SERVER_PASSWORD:
3789+
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_mcp_server_password);
3790+
break;
3791+
#endif
37723792
case MENU_ENUM_LABEL_NETPLAY_PUBLIC_ANNOUNCE:
37733793
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_public_announce);
37743794
break;

menu/menu_displaylist.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9474,6 +9474,29 @@ unsigned menu_displaylist_build_list(
94749474
MENU_ENUM_LABEL_STDIN_CMD_ENABLE,
94759475
PARSE_ONLY_BOOL, false) == 0)
94769476
count++;
9477+
9478+
#ifdef HAVE_MCP
9479+
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
9480+
MENU_ENUM_LABEL_MCP_SERVER_ENABLE,
9481+
PARSE_ONLY_BOOL, false) == 0)
9482+
count++;
9483+
9484+
if (settings->bools.mcp_server_enable)
9485+
{
9486+
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
9487+
MENU_ENUM_LABEL_MCP_SERVER_ADDRESS,
9488+
PARSE_ONLY_STRING, false) == 0)
9489+
count++;
9490+
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
9491+
MENU_ENUM_LABEL_MCP_SERVER_PORT,
9492+
PARSE_ONLY_UINT, false) == 0)
9493+
count++;
9494+
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
9495+
MENU_ENUM_LABEL_MCP_SERVER_PASSWORD,
9496+
PARSE_ONLY_STRING, false) == 0)
9497+
count++;
9498+
}
9499+
#endif
94779500
}
94789501
break;
94799502
case DISPLAYLIST_NETPLAY_LOBBY_FILTERS_LIST:

menu/menu_setting.c

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@
127127
#endif
128128
#endif
129129

130+
#ifdef HAVE_MCP
131+
#include "../network/mcp/mcp_server.h"
132+
#endif
133+
130134
#if defined(HAVE_OVERLAY)
131135
#include "../input/input_overlay.h"
132136
#endif
@@ -9606,6 +9610,22 @@ static void timezone_change_handler(rarch_setting_t *setting)
96069610
}
96079611
#endif
96089612

9613+
#ifdef HAVE_MCP
9614+
static void mcp_setting_change_handler(rarch_setting_t *setting)
9615+
{
9616+
(void)setting;
9617+
mcp_server_deinit();
9618+
}
9619+
9620+
static size_t setting_get_string_representation_mcp_password(
9621+
rarch_setting_t *setting, char *s, size_t len)
9622+
{
9623+
if (setting && !string_is_empty(setting->value.target.string))
9624+
return strlcpy(s, "********", len);
9625+
return 0;
9626+
}
9627+
#endif
9628+
96099629
static void appicon_change_handler(rarch_setting_t *setting)
96109630
{
96119631
uico_driver_state_t *uico_st = uico_state_get_ptr();
@@ -23911,6 +23931,79 @@ static bool setting_append_list(
2391123931
general_write_handler,
2391223932
general_read_handler,
2391323933
SD_FLAG_ADVANCED);
23934+
23935+
#ifdef HAVE_MCP
23936+
CONFIG_BOOL(
23937+
list, list_info,
23938+
&settings->bools.mcp_server_enable,
23939+
MENU_ENUM_LABEL_MCP_SERVER_ENABLE,
23940+
MENU_ENUM_LABEL_VALUE_MCP_SERVER_ENABLE,
23941+
DEFAULT_MCP_SERVER_ENABLE,
23942+
MENU_ENUM_LABEL_VALUE_OFF,
23943+
MENU_ENUM_LABEL_VALUE_ON,
23944+
&group_info,
23945+
&subgroup_info,
23946+
parent_group,
23947+
general_write_handler,
23948+
general_read_handler,
23949+
SD_FLAG_NONE);
23950+
(*list)[list_info->index - 1].action_ok = &setting_bool_action_left_with_refresh;
23951+
(*list)[list_info->index - 1].action_left = &setting_bool_action_left_with_refresh;
23952+
(*list)[list_info->index - 1].action_right = &setting_bool_action_right_with_refresh;
23953+
23954+
CONFIG_STRING(
23955+
list, list_info,
23956+
settings->arrays.mcp_server_address,
23957+
sizeof(settings->arrays.mcp_server_address),
23958+
MENU_ENUM_LABEL_MCP_SERVER_ADDRESS,
23959+
MENU_ENUM_LABEL_VALUE_MCP_SERVER_ADDRESS,
23960+
"",
23961+
&group_info,
23962+
&subgroup_info,
23963+
parent_group,
23964+
NULL,
23965+
NULL);
23966+
SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_ALLOW_INPUT);
23967+
(*list)[list_info->index - 1].ui_type = ST_UI_TYPE_STRING_LINE_EDIT;
23968+
(*list)[list_info->index - 1].action_start = setting_generic_action_start_default;
23969+
(*list)[list_info->index - 1].change_handler = mcp_setting_change_handler;
23970+
23971+
CONFIG_UINT(
23972+
list, list_info,
23973+
&settings->uints.mcp_server_port,
23974+
MENU_ENUM_LABEL_MCP_SERVER_PORT,
23975+
MENU_ENUM_LABEL_VALUE_MCP_SERVER_PORT,
23976+
DEFAULT_MCP_SERVER_PORT,
23977+
&group_info,
23978+
&subgroup_info,
23979+
parent_group,
23980+
NULL,
23981+
NULL);
23982+
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
23983+
(*list)[list_info->index - 1].offset_by = 1;
23984+
menu_settings_list_current_add_range(list, list_info, 0, 65535, 1, true, true);
23985+
SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_ALLOW_INPUT);
23986+
(*list)[list_info->index - 1].change_handler = mcp_setting_change_handler;
23987+
23988+
CONFIG_STRING(
23989+
list, list_info,
23990+
settings->arrays.mcp_server_password,
23991+
sizeof(settings->arrays.mcp_server_password),
23992+
MENU_ENUM_LABEL_MCP_SERVER_PASSWORD,
23993+
MENU_ENUM_LABEL_VALUE_MCP_SERVER_PASSWORD,
23994+
"",
23995+
&group_info,
23996+
&subgroup_info,
23997+
parent_group,
23998+
NULL,
23999+
NULL);
24000+
(*list)[list_info->index - 1].get_string_representation =
24001+
&setting_get_string_representation_mcp_password;
24002+
SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_ALLOW_INPUT);
24003+
(*list)[list_info->index - 1].ui_type = ST_UI_TYPE_PASSWORD_LINE_EDIT;
24004+
(*list)[list_info->index - 1].action_start = setting_generic_action_start_default;
24005+
(*list)[list_info->index - 1].change_handler = mcp_setting_change_handler;
24006+
#endif
2391424007
#endif
2391524008
CONFIG_BOOL(
2391624009
list, list_info,

0 commit comments

Comments
 (0)