Skip to content

Instantly share code, notes, and snippets.

@kordless
Created September 18, 2025 19:21
Show Gist options
  • Save kordless/ad5a8625762bd75060dfad1ad95a7e9c to your computer and use it in GitHub Desktop.
Save kordless/ad5a8625762bd75060dfad1ad95a7e9c to your computer and use it in GitHub Desktop.
Sticky howto-dynamic-simple-tool-proxy
Created: 2025-09-18T19:13:19.306879Z
Last modified: 2025-09-18T19:13:19.306879Z
Last accessed: 2025-09-18T19:20:57.994597Z
URL: app://sticky/howto-dynamic-simple-tool-proxy
Dynamic MCP Proxy (Hot‑Reload) — How‑To
Overview
- Expose a tool via an MCP server that dynamically imports the underlying implementation from a target file.
- Detect file changes via mtime and reload on demand; no server restarts required.
Files
- MCP/dynamic_simple_tool_proxy_mcp.py — dynamic proxy server (already added).
- MCP/simple-tool.py — underlying tool implementation; must define `simple_tool` (async or sync).
Pseudocode (core idea)
class DynamicLoader:
def __init__(self, path):
self.path = os.path.abspath(path)
self.loaded = None # LoadedModule(module, mtime)
def stat_mtime(self):
try: return os.path.getmtime(self.path)
except OSError: return None
def _load_fresh(self):
spec = importlib.util.spec_from_file_location(unique_name(), self.path)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return LoadedModule(mod, self.stat_mtime())
def clear(self):
self.loaded = None
def get_module(self, force_reload=False):
m = self.stat_mtime()
if m is None: raise FileNotFoundError(self.path)
if force_reload or self.loaded is None or self.loaded.mtime < m:
self.loaded = self._load_fresh()
return self.loaded
# MCP tools
@mcp.tool()
async def simple_tool():
loaded = loader.get_module()
fn = getattr(loaded.module, "simple_tool") # async or sync
return await fn() if asyncio.iscoroutinefunction(fn) else str(fn())
@mcp.tool()
async def reload_wrapped():
loader.clear(); loader.get_module(force_reload=True)
return "reloaded"
@mcp.tool()
async def proxy_status():
return f"target={loader.target_path} mtime={loader.stat_mtime()} cached={(loader._loaded.mtime if loader._loaded else None)}"
Config (Codex MCP)
[mcp_servers.simple_tool_proxy]
command = "python3"
args = ["MCP/dynamic_simple_tool_proxy_mcp.py", "--target", "MCP/simple-tool.py"]
working_directory = "/mnt/c/Users/kord/Code/Gnosis"
Usage
- Connect your MCP client to `simple_tool_proxy`.
- Call `proxy_status` to verify target + mtime.
- Call `simple_tool` to execute the underlying tool.
- Edit MCP/simple-tool.py and save; call `simple_tool` again to see changes.
- Use `reload_wrapped` to force a clear+reload if needed.
Requirements & Notes
- Python 3.10+; `mcp.server.fastmcp` installed for the proxy server.
- Underlying module should not start its own server at import-time (the included file is safe).
- Exceptions inside the underlying tool propagate through the proxy.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment