Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,31 @@
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "externalTerminal",
"stopAtEntry": false
},
},
{
"name": "MCP server console app - .NET Core Launch",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build mcp server",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/src/utils/Highbyte.DotNet6502.Util.MCPServer/bin/Debug/net9.0/Highbyte.DotNet6502.Util.MCPServer.dll",
"args": [],
"cwd": "${workspaceFolder}/src/utils/Highbyte.DotNet6502.Util.MCPServer/bin/Debug/net9.0/",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "externalTerminal",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
},
{
"name": ".NET Core Attach MCPServer (Windows)",
"type": "coreclr",
"request": "attach",
"processName": "Highbyte.DotNet6502.Util.MCPServer.exe"
}
]
}
50 changes: 50 additions & 0 deletions .vscode/mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"inputs": [],
"servers": {
// "DotNet6502-Embedded-Windows": {
// "type": "stdio",
// "command": "dotnet",
// "args": [
// "run",
// "--project",
// "C:\\Users\\highb\\source\\repos\\dotnet-6502\\src\\utils\\Highbyte.DotNet6502.Util.MCPServer\\Highbyte.DotNet6502.Util.MCPServer.csproj"
// ],
// "cwd": "C:\\Users\\highb\\source\\repos\\dotnet-6502\\src\\utils\\Highbyte.DotNet6502.Util.MCPServer"
// }

// "DotNet6502-Embedded-Mac": {
// "type": "stdio",
// "command": "dotnet",
// "args": [
// "run",
// "--project",
// "/Users/highbyte/source/repos/dotnet-6502/src/utils/Highbyte.DotNet6502.Util.MCPServer/Highbyte.DotNet6502.Util.MCPServer.csproj"
// ],
// "cwd": "/Users/highbyte/source/repos/dotnet-6502/src/utils/Highbyte.DotNet6502.Util.MCPServer"
// }

"DotNet6502-SadConsole-Windows": {
"type": "stdio",
"command": "C:\\Users\\highb\\source\\repos\\dotnet-6502\\src\\apps\\Highbyte.DotNet6502.App.SadConsole\\bin\\Debug\\net9.0\\Highbyte.DotNet6502.App.SadConsole.exe",
"cwd": "C:\\Users\\highb\\source\\repos\\dotnet-6502\\src\\apps\\Highbyte.DotNet6502.App.SadConsole\\bin\\Debug\\net9.0"
}

// "DotNet6502-SadConsole-Mac": {
// "type": "stdio",
// "command": "/Users/highbyte/source/repos/dotnet-6502/src/apps/Highbyte.DotNet6502.App.SadConsole/bin/Debug/net9.0/Highbyte.DotNet6502.App.SadConsole",
// "cwd": "/Users/highbyte/source/repos/dotnet-6502/src/apps/Highbyte.DotNet6502.App.SadConsole/bin/Debug/net9.0"
// }

//"DotNet6502-SilkNet-Windows": {
// "type": "stdio",
// "command": "C:\\Users\\highb\\source\\repos\\dotnet-6502\\src\\apps\\Highbyte.DotNet6502.App.SilkNetNative\\bin\\Debug\\net9.0\\Highbyte.DotNet6502.App.SilkNetNative.exe",
// "cwd": "C:\\Users\\highb\\source\\repos\\dotnet-6502\\src\\apps\\Highbyte.DotNet6502.App.SilkNetNative\\bin\\Debug\\net9.0"
//}

// "DotNet6502-SilkNet-Mac": {
// "type": "stdio",
// "command": "/Users/highbyte/source/repos/dotnet-6502/src/apps/Highbyte.DotNet6502.App.SilkNetNative/bin/Debug/net9.0/Highbyte.DotNet6502.App.SilkNetNative",
// "cwd": "/Users/highbyte/source/repos/dotnet-6502/src/apps/Highbyte.DotNet6502.App.SilkNetNative/bin/Debug/net9.0"
// }
}
}
16 changes: 16 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,22 @@
"kind": "test",
"isDefault": true
}
},
{
"label": "build mcp server",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/src/utils/Highbyte.DotNet6502.Util.MCPServer/Highbyte.DotNet6502.Util.MCPServer.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
17 changes: 17 additions & 0 deletions dotnet-6502.sln
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Highbyte.DotNet6502.Systems
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Highbyte.DotNet6502.AI", "src\libraries\Highbyte.DotNet6502.AI\Highbyte.DotNet6502.AI.csproj", "{B04E0DA2-F0EB-4E71-BFF9-3D3B17E30688}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utils", "Utils", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Highbyte.DotNet6502.Util.MCPServer", "src\utils\Highbyte.DotNet6502.Util.MCPServer\Highbyte.DotNet6502.Util.MCPServer.csproj", "{1AB6BB50-42BF-44ED-8B5B-40266C9ED016}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -273,6 +277,18 @@ Global
{B04E0DA2-F0EB-4E71-BFF9-3D3B17E30688}.Release|x64.Build.0 = Release|Any CPU
{B04E0DA2-F0EB-4E71-BFF9-3D3B17E30688}.Release|x86.ActiveCfg = Release|Any CPU
{B04E0DA2-F0EB-4E71-BFF9-3D3B17E30688}.Release|x86.Build.0 = Release|Any CPU
{1AB6BB50-42BF-44ED-8B5B-40266C9ED016}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1AB6BB50-42BF-44ED-8B5B-40266C9ED016}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1AB6BB50-42BF-44ED-8B5B-40266C9ED016}.Debug|x64.ActiveCfg = Debug|Any CPU
{1AB6BB50-42BF-44ED-8B5B-40266C9ED016}.Debug|x64.Build.0 = Debug|Any CPU
{1AB6BB50-42BF-44ED-8B5B-40266C9ED016}.Debug|x86.ActiveCfg = Debug|Any CPU
{1AB6BB50-42BF-44ED-8B5B-40266C9ED016}.Debug|x86.Build.0 = Debug|Any CPU
{1AB6BB50-42BF-44ED-8B5B-40266C9ED016}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1AB6BB50-42BF-44ED-8B5B-40266C9ED016}.Release|Any CPU.Build.0 = Release|Any CPU
{1AB6BB50-42BF-44ED-8B5B-40266C9ED016}.Release|x64.ActiveCfg = Release|Any CPU
{1AB6BB50-42BF-44ED-8B5B-40266C9ED016}.Release|x64.Build.0 = Release|Any CPU
{1AB6BB50-42BF-44ED-8B5B-40266C9ED016}.Release|x86.ActiveCfg = Release|Any CPU
{1AB6BB50-42BF-44ED-8B5B-40266C9ED016}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -296,6 +312,7 @@ Global
{4E078F4C-9C1B-4C17-A2AE-6BF2345DC791} = {B406AD5D-CB8D-45F2-A5A2-4C0AD82A410A}
{A52EFEC2-FD60-453E-AC55-703AD2F2A895} = {B406AD5D-CB8D-45F2-A5A2-4C0AD82A410A}
{B04E0DA2-F0EB-4E71-BFF9-3D3B17E30688} = {B406AD5D-CB8D-45F2-A5A2-4C0AD82A410A}
{1AB6BB50-42BF-44ED-8B5B-40266C9ED016} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0F55B6C2-E4B4-4F2C-9D2A-D63A17F3B5C4}
Expand Down
2 changes: 2 additions & 0 deletions src/apps/Highbyte.DotNet6502.App.SadConsole/EmulatorConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public class EmulatorConfig
/// </summary>
public GenericComputerHostConfig GenericComputerHostConfig { get; set; }

public bool MCPServerEnabled { get; set; }

public EmulatorConfig()
{
UIFont = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@
<ProjectReference Include="..\..\libraries\Highbyte.DotNet6502\Highbyte.DotNet6502.csproj" />
<ProjectReference Include="..\..\libraries\Highbyte.DotNet6502.Impl.SadConsole\Highbyte.DotNet6502.Impl.SadConsole.csproj" />
<ProjectReference Include="..\..\libraries\Highbyte.DotNet6502.Systems\Highbyte.DotNet6502.Systems.csproj" />
<ProjectReference Include="..\..\utils\Highbyte.DotNet6502.Util.MCPServer\Highbyte.DotNet6502.Util.MCPServer.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.6" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.6" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.6" />
<PackageReference Include="ModelContextProtocol" Version="0.3.0-preview.1" />
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.2.1105" />
<PackageReference Include="SadConsole.Extended" Version="10.5.0" />
<PackageReference Include="TextCopy" Version="6.2.1" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.ComponentModel;
using Highbyte.DotNet6502.Systems;
using Highbyte.DotNet6502.Util.MCPServer;
using ModelContextProtocol.Protocol;
using ModelContextProtocol.Server;

namespace Highbyte.DotNet6502.App.SadConsole.MCP;

[McpServerToolType]
public static class C64SadConsoleTools
{
[McpServerTool, Description("Get C64 emulator log messages")]
public static async Task<CallToolResult> GetLogMessages(IHostApp hostApp, int numberOfLogMessages)
{
try
{
List<string> logs = null!;
await hostApp.ExternalControlInvokeOnUIThread(async () =>
{
C64ToolHelper.AssertC64EmulatorIsRunningOrPaused(hostApp);
var logStore = ((SadConsoleHostApp)hostApp).LogStore;
logs = logStore.GetLogMessages().Take(numberOfLogMessages).ToList();
});

return C64ToolHelper.BuildCallToolDataResult(logs);

}
catch (Exception ex)
{
return C64ToolHelper.BuildCallToolErrorResult(ex);
}
}
}
30 changes: 25 additions & 5 deletions src/apps/Highbyte.DotNet6502.App.SadConsole/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
using Highbyte.DotNet6502.Systems;
using Highbyte.DotNet6502.Systems.Logging.InMem;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Hosting;
using Highbyte.DotNet6502.Util.MCPServer;

// ----------
// Get config file
Expand All @@ -22,17 +25,16 @@
builder.AddUserSecrets<Program>();
}


IConfiguration Configuration = builder.Build();

// ----------
// Create logging
// ----------
DotNet6502InMemLogStore logStore = new() { WriteDebugMessage = true };
var logConfig = new DotNet6502InMemLoggerConfiguration(logStore);
logConfig.LogLevel = LogLevel.Information; // LogLevel.Debug, LogLevel.Information
var loggerFactory = LoggerFactory.Create(builder =>
{
logConfig.LogLevel = LogLevel.Information; // LogLevel.Debug, LogLevel.Information,
builder.AddInMem(logConfig);
builder.SetMinimumLevel(LogLevel.Trace);
});
Expand All @@ -54,10 +56,28 @@
var genericComputerSetup = new GenericComputerSetup(loggerFactory, Configuration);
systemList.AddSystem(genericComputerSetup);


// ----------
// Start SadConsoleHostApp
// Init SadConsoleHostApp
// ----------
emulatorConfig.Validate(systemList);
var sadConsoleHostApp = new SadConsoleHostApp(systemList, loggerFactory, emulatorConfig, logStore, logConfig, Configuration);

var silkNetHostApp = new SadConsoleHostApp(systemList, loggerFactory, emulatorConfig, logStore, logConfig, Configuration);
silkNetHostApp.Run();
// ----------
// Start MCP server as a background host if enabled
// ----------
if (emulatorConfig.MCPServerEnabled)
{
Task.Run(async () =>
{
var mcpBuilder = Host.CreateApplicationBuilder();
mcpBuilder.ConfigureDotNet6502McpServerTools(sadConsoleHostApp,
additionalToolsAssembly: typeof(Highbyte.DotNet6502.App.SadConsole.MCP.C64SadConsoleTools).Assembly);
await mcpBuilder.Build().RunAsync();
});
}

// ----------
// Start SadConsoleHostApp
// ----------
sadConsoleHostApp.Run();
20 changes: 19 additions & 1 deletion src/apps/Highbyte.DotNet6502.App.SadConsole/SadConsoleHostApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class SadConsoleHostApp : HostApp<SadConsoleRenderContext, SadConsoleInpu
public EmulatorConfig EmulatorConfig => _emulatorConfig;

private readonly DotNet6502InMemLogStore _logStore;
public DotNet6502InMemLogStore LogStore => _logStore;
private readonly DotNet6502InMemLoggerConfiguration _logConfig;
private readonly IConfiguration _configuration;
private readonly ILoggerFactory _loggerFactory;
Expand Down Expand Up @@ -75,7 +76,6 @@ protected virtual void OnMonitorStateChange(bool monitorEnabled)
private int _logsFrameCount = 0;
private DrawImage _logoDrawImage;


/// <summary>
/// Constructor
/// </summary>
Expand Down Expand Up @@ -610,4 +610,22 @@ private async Task HandleUIKeyboardInput()
}
}
}

public override void ExternalControlRefreshUI()
{
// Refresh UI controls
if (_menuConsole != null)
_menuConsole.IsDirty = true;
if (_systemMenuConsole != null)
_systemMenuConsole.IsDirty = true;
if (_sadConsoleEmulatorConsole != null)
_sadConsoleEmulatorConsole.IsDirty = true;

//if (_monitorConsole != null)
// _monitorConsole.IsDirty = true;
//if (_monitorStatusConsole != null)
// _monitorStatusConsole.IsDirty = true;
//if (_infoConsole != null)
// _infoConsole.IsDirty = true;
}
}
4 changes: 3 additions & 1 deletion src/apps/Highbyte.DotNet6502.App.SadConsole/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
"UIFont": null, // UI Console font. Leave blank for default SadConsole font.
"UIFontSize": "One", // UI consoles font (not Emulator console). Possible values: "Quarter", "Half, "One", "Two", "Three", "Four", "Five"

"DefaultAudioVolumePercent": 20
"DefaultAudioVolumePercent": 20,

"MCPServerEnabled": true
},

"Highbyte.DotNet6502.C64.SadConsole": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class EmulatorConfig
public float DefaultDrawScale { get; set; }
public float CurrentDrawScale { get; set; }
public MonitorConfig Monitor { get; set; }
public bool MCPServerEnabled { get; set; }

public EmulatorConfig()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@
<ProjectReference Include="..\..\libraries\Highbyte.DotNet6502.Impl.Skia\Highbyte.DotNet6502.Impl.Skia.csproj" />
<ProjectReference Include="..\..\libraries\Highbyte.DotNet6502.Impl.SilkNet\Highbyte.DotNet6502.Impl.SilkNet.csproj" />
<ProjectReference Include="..\..\libraries\Highbyte.DotNet6502.Systems\Highbyte.DotNet6502.Systems.csproj" />
<ProjectReference Include="..\..\utils\Highbyte.DotNet6502.Util.MCPServer\Highbyte.DotNet6502.Util.MCPServer.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.6" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.6" />
<PackageReference Include="NativeFileDialogSharp" Version="0.6.0-alpha" />
<PackageReference Include="Silk.NET.Input" Version="2.22.0" />
<PackageReference Include="Silk.NET.OpenGL" Version="2.22.0" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.ComponentModel;
using Highbyte.DotNet6502.Systems;
using Highbyte.DotNet6502.Util.MCPServer;
using ModelContextProtocol.Protocol;
using ModelContextProtocol.Server;

namespace Highbyte.DotNet6502.App.SilkNetNative.MCP;

[McpServerToolType]
public static class C64SilkNetNativeTools
{
[McpServerTool, Description("Get C64 emulator log messages")]
public static async Task<CallToolResult> GetLogMessages(IHostApp hostApp, int numberOfLogMessages)
{
try
{
List<string> logs = null!;
await hostApp.ExternalControlInvokeOnUIThread(async () =>
{
C64ToolHelper.AssertC64EmulatorIsRunningOrPaused(hostApp);
var logStore = ((SilkNetHostApp)hostApp).LogStore;
logs = logStore.GetLogMessages().Take(numberOfLogMessages).ToList();
});

return C64ToolHelper.BuildCallToolDataResult(logs);

}
catch (Exception ex)
{
return C64ToolHelper.BuildCallToolErrorResult(ex);
}
}
}
Loading
Loading