MCP gateway server that lets you call multiple MCP servers from Lua scripts.
This proxy acts as a gateway between AI agents and multiple MCP (Model Context Protocol) servers. Instead of connecting to each MCP server individually, agents connect to this single proxy and gain access to all configured servers through a unified interface.
Progressive Tool Discovery: Agents start with zero knowledge about what servers or tools are available. They build context progressively:
- Call
list-servers- The agent's context now includes names and descriptions of all available MCP servers (e.g., "github", "slack", "database") - Call
list-server-tools(server_name)- The agent's context expands to include all tool names and descriptions for that specific server - Call
tool-details(server_name, tool_name)- The agent's context now has complete parameter schemas, return types (if available), and usage examples for a specific tool - Call
execute(lua_script)- With full context, the agent can write Lua scripts that call the discovered tools
Rather than loading all tools and tool descriptions into the context upfront, this defers loading tools until the agent determines those tools are needed.
Tool Chaining with Lua: Once an agent knows what tools exist, they can compose complex multi-step workflows in a single execute() call. The Lua runtime provides access to all discovered servers as globals, with tools callable as async functions.
Sequential tool chaining:
local raw_data = api_server.fetch({ id = 123 }):await()
local processed = processor.transform({ input = raw_data }):await()
result(processed)Conditional logic:
local status = checker.validate({}):await()
if status.ok then
result(processor.run({}):await())
else
result(error_handler.notify({ error = status.message }):await())
endIteration with loops:
local results = {}
for i = 1, 5 do
results[i] = worker.process({ index = i }):await()
end
result({ total = #results, data = results })Install globally to use as a CLI tool:
npm install -g @karashiiro/my-cool-proxyOr run directly without installing:
# Using pnpm (recommended)
pnpm dlx @karashiiro/my-cool-proxy
# Using npx
npx @karashiiro/my-cool-proxyClone and build for development:
git clone https://github.com/karashiiro/my-cool-proxy.git
cd my-cool-proxy
pnpm install
pnpm buildThe gateway auto-creates a default config on first run. Just run it once to generate the config file:
my-cool-proxy # Creates config and starts (with no servers)Then edit the config to add your MCP servers:
# Find your config location
my-cool-proxy --config-path
# Edit to add servers (see docs/configuration.md for all options)Example config structure:
{
"port": 3000,
"host": "localhost",
"mcpClients": {
"my-server": {
"type": "http",
"url": "https://example.com/mcp"
}
}
}Or, copy the example config for a more complete starting point:
# Linux
mkdir -p ~/.config/my-cool-proxy
cp config.example.json ~/.config/my-cool-proxy/config.json
# macOS
mkdir -p ~/Library/Preferences/my-cool-proxy
cp config.example.json ~/Library/Preferences/my-cool-proxy/config.json
# Windows (PowerShell)
mkdir "$env:APPDATA\my-cool-proxy"
Copy-Item config.example.json "$env:APPDATA\my-cool-proxy\config.json"# If installed globally
my-cool-proxy
# If running from source
pnpm devAdd to your MCP client config (e.g., Claude Desktop):
{
"mcpServers": {
"my-cool-proxy": {
"url": "http://localhost:3000/mcp"
}
}
}The proxy exposes these tools:
execute- Run Lua scripts that can call your configured MCP serverslist-servers- See available serverslist-server-tools- See tools for a servertool-details- Get full tool documentationinspect-tool-response- Make a sample call to see response structuresummary-stats- Get aggregate counts of servers, tools, resources, and promptslist-resources- See available resources from all serversread-resource- Read a specific resource by its namespaced URIinvoke-gateway-skill-script- Execute scripts from skill packages (when skills enabled)write-gateway-skill- Create or modify skills (when skills mutable)
Example Lua script:
-- Call a tool and return the result directly
result(my_server.some_tool({ arg = "value" }):await())
-- Or store in a variable first if you need to process it
local data = my_server.some_tool({ arg = "value" }):await()
result({ processed = data.something })Skills are reusable process documents that agents can load as MCP resources. When enabled, agents can:
- Discover skills via
list-resources(look forgw-skill://URIs) - Read skill content via
read-resource - Execute skill scripts via
invoke-gateway-skill-script
Skills are disabled by default. See the Configuration Guide for setup options.
The gateway supports two modes for how it exposes itself to MCP clients.
Run the gateway as an HTTP server that clients connect to remotely:
Configure - Set transport: "http" in config.json (or omit for default):
{
"port": 3000,
"host": "localhost",
"transport": "http",
"mcpClients": { ... }
}Connect from MCP client:
{
"mcpServers": {
"my-cool-proxy": {
"url": "http://localhost:3000/mcp"
}
}
}Run the gateway as a stdio-based MCP server that clients launch directly. This is ideal when:
- You want the MCP client to manage the gateway process's lifecycle
- You're running everything locally and don't need a persistent server
- You prefer simpler deployment without managing an HTTP server, or your client doesn't support localhost HTTP (e.g. Claude Desktop)
Key differences from HTTP mode:
- Single session only (no multi-client support)
- All upstream MCP clients initialize at startup (not lazily)
- Must build before running (
pnpm devwon't work - stdout is used for MCP protocol)
The gateway auto-creates a config on first run, but for stdio mode you'll need to edit it to set transport: "stdio". You can find your config location with my-cool-proxy --config-path.
Example config (port and host are ignored in stdio mode):
{
"transport": "stdio",
"mcpClients": {
"filesystem": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-everything"]
}
}
}Tip: Run
my-cool-proxy --config-pathto see exactly where your config should be located.
Add to your MCP client config (e.g., Claude Desktop's claude_desktop_config.json):
If installed globally via npm:
{
"mcpServers": {
"my-cool-proxy": {
"command": "my-cool-proxy"
}
}
}If running from source (macOS/Linux):
{
"mcpServers": {
"my-cool-proxy": {
"command": "node",
"args": ["/absolute/path/to/my-cool-proxy/dist/index.js"]
}
}
}If running from source (Windows):
{
"mcpServers": {
"my-cool-proxy": {
"command": "node",
"args": ["C:\\Users\\yourname\\path\\to\\my-cool-proxy\\dist\\index.js"]
}
}
}Restart Claude Desktop (or your MCP client) to pick up the new config. The gateway will start automatically when you begin a conversation.
Gateway not starting?
- Check your MCP client's logs for error messages
- Verify the path to
dist/index.jsis correct and absolute - Ensure you ran
pnpm buildafter any code changes
Config not found?
- Run
my-cool-proxy --config-pathto see expected location - Or set
CONFIG_PATHenvironment variable to override:
{
"mcpServers": {
"my-cool-proxy": {
"command": "node",
"args": ["path/to/my-cool-proxy/dist/index.js"],
"env": {
"CONFIG_PATH": "/path/to/your/config.json"
}
}
}
}Upstream servers failing to connect?
- All configured MCP clients must connect successfully at startup in stdio mode
- Check that commands in your config are correct and dependencies are installed
- Try running the upstream servers individually first to verify they work
Stderr output from stdio MCP servers is redirected to log files. Log location varies by platform:
- Windows:
%LOCALAPPDATA%\my-cool-proxy\Log\servers\ - macOS:
~/Library/Logs/my-cool-proxy/servers/ - Linux:
~/.local/state/my-cool-proxy/servers/
Each server gets its own log file: {server-name}-{session-id}.log. In stdio mode, the session ID is always default (e.g., calculator-default.log).
These logs are useful for debugging when upstream MCP servers encounter errors or when you want to see what stderr output they produce during operation.
HTTP - Connect to remote MCP servers:
{
"type": "http",
"url": "https://api.example.com/mcp",
"headers": {
"Authorization": "Bearer token"
}
}Stdio - Launch local MCP servers:
{
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-everything"]
}See the Configuration Guide for full configuration reference.
pnpm test