Skip to main content
Glama

Cursor MCP Server

by johnneerdael
main.cc7.56 kB
#include <cmath> #include <cstdint> #include <napi.h> #include <iostream> #include <shtypes.h> #include <string> #include <windows.h> #include <psapi.h> #include <version> #include <dwmapi.h> #include <algorithm> typedef int(__stdcall *lp_GetScaleFactorForMonitor)(HMONITOR, DEVICE_SCALE_FACTOR *); struct OwnerWindowInfo { std::string path; std::string name; }; template <typename T> T getValueFromCallbackData(const Napi::CallbackInfo &info, unsigned handleIndex) { return reinterpret_cast<T>(info[handleIndex].As<Napi::Number>().Int64Value()); } // Get wstring from string std::wstring get_wstring(const std::string str) { return std::wstring(str.begin(), str.end()); } std::string getFileName(const std::string &value) { char separator = '/'; #ifdef _WIN32 separator = '\\'; #endif size_t index = value.rfind(separator, value.length()); if (index != std::string::npos) { return (value.substr(index + 1, value.length() - index)); } return (""); } // Convert wstring into utf8 string std::string toUtf8(const std::wstring &str) { std::string ret; int len = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0, NULL, NULL); if (len > 0) { ret.resize(len); WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.length(), &ret[0], len, NULL, NULL); } return ret; } // Return window title in utf8 string std::string getWindowTitle(const HWND hwnd) { int bufsize = GetWindowTextLengthW(hwnd) + 1; LPWSTR t = new WCHAR[bufsize]; GetWindowTextW(hwnd, t, bufsize); std::wstring ws(t); std::string title = toUtf8(ws); return title; } // Return description from file version info std::string getDescriptionFromFileVersionInfo(const BYTE *pBlock) { UINT bufLen = 0; struct LANGANDCODEPAGE { WORD wLanguage; WORD wCodePage; } * lpTranslate; LANGANDCODEPAGE codePage{0x040904E4}; // Get language struct if (VerQueryValueW((LPVOID *)pBlock, (LPCWSTR)L"\\VarFileInfo\\Translation", (LPVOID *)&lpTranslate, &bufLen)) { codePage = lpTranslate[0]; } wchar_t fileDescriptionKey[256]; wsprintfW(fileDescriptionKey, L"\\StringFileInfo\\%04x%04x\\FileDescription", codePage.wLanguage, codePage.wCodePage); wchar_t *fileDescription = NULL; UINT fileDescriptionSize; // Get description file if (VerQueryValueW((LPVOID *)pBlock, fileDescriptionKey, (LPVOID *)&fileDescription, &fileDescriptionSize)) { return toUtf8(fileDescription); } return ""; } // Return process path and name OwnerWindowInfo getProcessPathAndName(const HANDLE &phlde) { DWORD dwSize{MAX_PATH}; wchar_t exeName[MAX_PATH]{}; QueryFullProcessImageNameW(phlde, 0, exeName, &dwSize); std::string path = toUtf8(exeName); std::string name = getFileName(path); DWORD dwHandle = 0; wchar_t *wspath(exeName); DWORD infoSize = GetFileVersionInfoSizeW(wspath, &dwHandle); if (infoSize != 0) { BYTE *pVersionInfo = new BYTE[infoSize]; std::unique_ptr<BYTE[]> skey_automatic_cleanup(pVersionInfo); if (GetFileVersionInfoW(wspath, NULL, infoSize, pVersionInfo) != 0) { std::string nname = getDescriptionFromFileVersionInfo(pVersionInfo); if (nname != "") { name = nname; } } } return {path, name}; } OwnerWindowInfo newOwner; BOOL CALLBACK EnumChildWindowsProc(HWND hwnd, LPARAM lParam) { // Get process ID DWORD processId{0}; GetWindowThreadProcessId(hwnd, &processId); OwnerWindowInfo *ownerInfo = (OwnerWindowInfo *)lParam; // Get process Handler HANDLE phlde{OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, processId)}; if (phlde != NULL) { newOwner = getProcessPathAndName(phlde); CloseHandle(hwnd); if (ownerInfo->path != newOwner.path) { return FALSE; } } return TRUE; } // Return window information Napi::Value getWindowInformation(const HWND &hwnd, const Napi::CallbackInfo &info) { Napi::Env env{info.Env()}; if (hwnd == NULL) { return env.Null(); } // Get process ID DWORD processId{0}; GetWindowThreadProcessId(hwnd, &processId); // Get process Handler HANDLE phlde{OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, processId)}; if (phlde == NULL) { return env.Null(); } OwnerWindowInfo ownerInfo = getProcessPathAndName(phlde); // ApplicationFrameHost & Universal Windows Platform Support if (getFileName(ownerInfo.path) == "ApplicationFrameHost.exe") { newOwner = (OwnerWindowInfo) * new OwnerWindowInfo(); BOOL result = EnumChildWindows(hwnd, (WNDENUMPROC)EnumChildWindowsProc, (LPARAM)&ownerInfo); if (result == FALSE && newOwner.name.size()) { ownerInfo = newOwner; } } if (ownerInfo.name == "Widgets.exe") { return env.Null(); } PROCESS_MEMORY_COUNTERS memoryCounter; BOOL memoryResult = GetProcessMemoryInfo(phlde, &memoryCounter, sizeof(memoryCounter)); CloseHandle(phlde); if (memoryResult == 0) { return env.Null(); } RECT lpRect; BOOL rectResult = GetWindowRect(hwnd, &lpRect); if (rectResult == 0) { return env.Null(); } Napi::Object owner = Napi::Object::New(env); owner.Set(Napi::String::New(env, "processId"), processId); owner.Set(Napi::String::New(env, "path"), ownerInfo.path); owner.Set(Napi::String::New(env, "name"), ownerInfo.name); Napi::Object bounds = Napi::Object::New(env); bounds.Set(Napi::String::New(env, "x"), lpRect.left); bounds.Set(Napi::String::New(env, "y"), lpRect.top); bounds.Set(Napi::String::New(env, "width"), lpRect.right - lpRect.left); bounds.Set(Napi::String::New(env, "height"), lpRect.bottom - lpRect.top); Napi::Object activeWinObj = Napi::Object::New(env); activeWinObj.Set(Napi::String::New(env, "platform"), Napi::String::New(env, "windows")); activeWinObj.Set(Napi::String::New(env, "id"), (LONG)hwnd); activeWinObj.Set(Napi::String::New(env, "title"), getWindowTitle(hwnd)); activeWinObj.Set(Napi::String::New(env, "owner"), owner); activeWinObj.Set(Napi::String::New(env, "bounds"), bounds); activeWinObj.Set(Napi::String::New(env, "memoryUsage"), memoryCounter.WorkingSetSize); return activeWinObj; } // List of HWND used for EnumDesktopWindows callback std::vector<HWND> _windows; // EnumDesktopWindows callback BOOL CALLBACK EnumDekstopWindowsProc(HWND hwnd, LPARAM lParam) { if (IsWindow(hwnd) && IsWindowEnabled(hwnd) && IsWindowVisible(hwnd)) { WINDOWINFO winInfo{}; GetWindowInfo(hwnd, &winInfo); if ( (winInfo.dwExStyle & WS_EX_TOOLWINDOW) == 0 && (winInfo.dwStyle & WS_CAPTION) == WS_CAPTION && (winInfo.dwStyle & WS_CHILD) == 0 ) { int ClockedVal; DwmGetWindowAttribute(hwnd, DWMWA_CLOAKED, (PVOID)&ClockedVal, sizeof(ClockedVal)); if (ClockedVal == 0) { _windows.push_back(hwnd); } } } return TRUE; }; // Method to get active window Napi::Value getActiveWindow(const Napi::CallbackInfo &info) { HWND hwnd = GetForegroundWindow(); Napi::Value value = getWindowInformation(hwnd, info); return value; } // Method to get an array of open windows Napi::Array getOpenWindows(const Napi::CallbackInfo &info) { Napi::Env env{info.Env()}; Napi::Array values = Napi::Array::New(env); _windows.clear(); if (EnumDesktopWindows(NULL, (WNDENUMPROC)EnumDekstopWindowsProc, NULL)) { uint32_t i = 0; for (HWND _win : _windows) { Napi::Value value = getWindowInformation(_win, info); if (value != env.Null()) { values.Set(i++, value); } } } return values; } Napi::Object Init(Napi::Env env, Napi::Object exports) { exports.Set(Napi::String::New(env, "getActiveWindow"), Napi::Function::New(env, getActiveWindow)); exports.Set(Napi::String::New(env, "getOpenWindows"), Napi::Function::New(env, getOpenWindows)); return exports; } NODE_API_MODULE(addon, Init)

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/johnneerdael/multiplatform-cursor-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server