import os from pathlib import Path from dotenv import load_dotenv from mcp.server.fastmcp import FastMCP load_dotenv();mcp=FastMCP("Alfred Files") READ=[Path(x).resolve() for x in os.getenv('READ_ROOTS','').split(':') if x]; WRITE=Path(os.getenv('WRITE_ROOT','/home/hermes/alfred-data')).resolve();WRITE.mkdir(parents=True,exist_ok=True) def safe_read(p): p=Path(p).resolve(); if not any(p==r or r in p.parents for r in READ): raise PermissionError('Hors des zones de lecture autorisées') return p def safe_write(name): p=(WRITE/name).resolve(); if not (p==WRITE or WRITE in p.parents): raise PermissionError('Écriture hors workspace interdite') return p @mcp.tool() def list_directory(path:str): return [{'name':p.name,'is_dir':p.is_dir()} for p in safe_read(path).iterdir()] @mcp.tool() def search_files(query:str): out=[] for r in READ: for p in r.rglob('*'): if query.lower() in p.name.lower(): out.append(str(p)) if len(out)>=100:return out return out @mcp.tool() def read_text(path:str, max_chars:int=50000): return safe_read(path).read_text(errors='replace')[:max_chars] @mcp.tool() def write_workspace_file(name:str, content:str): p=safe_write(name);p.parent.mkdir(parents=True,exist_ok=True);p.write_text(content);return str(p) if __name__=='__main__':mcp.run()