Come creare un server MCP locale per Claude: file, comandi, screenshot e controllo delle app

@hrswatigupta
INGLESE1 mese fa · 04 giu 2026
1.0M
72
16
2
224

TL;DR

Questa guida illustra come creare un server MCP locale basato su Python per Claude, consentendo un accesso sicuro e controllato a file locali, comandi e strumenti desktop tramite un'architettura basata su allowlist.

Claude diventa molto più utile quando smette di essere solo un'interfaccia di chat.

Un server MCP locale permette a Claude di interagire con la tua macchina reale: file locali, comandi approvati, screenshot e avvio di applicazioni. La parte importante non è l'accesso diretto. È l'accesso controllato.

In questa guida, costruiremo un server MCP locale per Claude che sia pratico, mirato e abbastanza sicuro da essere usato in flussi di lavoro reali.

Una nota rapida prima di costruire qualsiasi cosa

Questo articolo evita intenzionalmente la versione irresponsabile del "controllo del computer."

Non daremo a Claude accesso illimitato alla shell, autorità completa sul filesystem o il permesso di modificare la tua macchina senza protezioni. Il modo più veloce per costruire un server MCP locale scadente è esporre un enorme strumento run_anything() e chiamarlo innovazione.

Il modello migliore è:

  • directory consentite
  • comandi consentiti
  • impostazioni predefinite sicure
  • log leggibili dall'uomo
  • risposte esplicite
  • chiara separazione tra strumenti di sola lettura e strumenti d'azione

Se Claude può fare tutto, hai costruito una demo.

Se Claude può fare le cose giuste in modo sicuro, hai costruito qualcosa di utilizzabile.

Perché vale la pena imparare questa architettura

Il valore di un server MCP locale non è la novità. È la riduzione dell'attrito.

Senza un livello di strumenti locale, il tuo flusso di lavoro è così:

  1. Chiedi a Claude cosa fare
  2. Copia la risposta
  3. Apri tu la cartella
  4. Esegui tu il comando
  5. Fai tu lo screenshot
  6. Incolla il risultato nella chat

Con un server MCP locale, quel ciclo diventa molto più stretto. Claude può ispezionare il contesto di cui ha bisogno, usare strumenti con ambito limitato e restituire una risposta basata sullo stato effettivo della tua macchina.

Questo è utile per:

  • flussi di lavoro di sviluppo
  • ispezione dei log
  • operazioni sui contenuti
  • pipeline di ricerca
  • automazione del desktop
  • attività amministrative ripetitive

E poiché il livello degli strumenti è tuo, scegli esattamente dove si ferma il modello.

Vuoi imparare l'IA e rimanere al passo nella tua carriera?

Condivido:

Oltre 1.000 prompt IA

Strumenti IA e automazioni

Consigli di carriera e crescita su LinkedIn

Risorse curate su tecnologia e produttività

Iscriviti qui:

https://bytebuilders.beehiiv.com/subscribe

Seguimi per altri consigli sull'IA

👇

Il design che stiamo costruendo

Swati Gupta - inline image

Costruiremo un server locale con cinque strumenti:

  1. list_files — vedere cosa esiste all'interno delle cartelle approvate
  2. read_file — aprire file di testo sicuri
  3. run_command — eseguire un piccolo insieme di comandi locali approvati
  4. take_screenshot — salvare uno screenshot in una posizione nota
  5. open_target — aprire un'app, un file, una cartella o un URL
Swati Gupta - inline image

Quell'ambito è deliberato.

È abbastanza per rendere Claude significativamente utile su una macchina locale senza cadere in un'automazione generica e insicura.

Il modello mentale dovrebbe essere questo:

Claude → client MCP → server MCP locale → strumenti mirati → sistema operativo

Claude non dovrebbe mai parlare direttamente al tuo sistema operativo. Il tuo server MCP è il piano di controllo nel mezzo.

Lo stack

Per una build locale, Python è una scelta pulita perché l'SDK MCP ufficiale è maturo, l'astrazione FastMCP è concisa e Python rimane il linguaggio più semplice per lavori di scripting su filesystem, subprocess e desktop 4 2.

Useremo:

  • Python 3.11+
  • mcp[cli] per il runtime del server MCP
  • mss per screenshot multipiattaforma
  • moduli della libreria standard per accesso ai file, chiamate subprocess e gestione del sistema operativo

Imposta un nuovo progetto:

bash
1mkdir local-mcp-server
2cd local-mcp-server
3uv init --python 3.11
4uv add "mcp[cli]>=1.0,<2.0" "mss>=9.0,<10.0"

Lo stile FastMCP basato su decorator tiene il livello del protocollo fuori dai piedi in modo che tu possa concentrarti sulla qualità degli strumenti invece che sul cablaggio 4 5.

Una struttura di progetto semplice funziona bene:

text
1mkdir local-mcp-server
2cd local-mcp-server
3uv init --python 3.11
4uv add "mcp[cli]>=1.0,<2.0" "mss>=9.0,<10.0"

Non hai bisogno di un'architettura complessa per la v1. Ciò di cui hai bisogno è chiarezza.

Il server vero e proprio

Crea server.py e inizia con un'implementazione basata su policy.

python
1from __future__ import annotations
2
3import json
4import os
5import platform
6import shlex
7import subprocess
8from pathlib import Path
9from typing import Any
10
11import mss
12from mcp.server.fastmcp import FastMCP
13
14app = FastMCP("local-computer-control", json_response=True)
15
16HOME = Path.home()
17PROJECT_ROOT = Path(__file__).parent.resolve()
18CAPTURE_DIR = PROJECT_ROOT / "captures"
19CAPTURE_DIR.mkdir(exist_ok=True)
20
21ALLOWED_ROOTS = [
22 HOME / "Documents",
23 HOME / "Desktop",
24 PROJECT_ROOT,
25]
26
27ALLOWED_COMMANDS = {
28 "pwd",
29 "ls",
30 "git status",
31 "git diff --stat",
32 "python --version",
33 "node --version",
34 "npm --version",
35}
36
37READABLE_EXTENSIONS = {
38 ".txt",
39 ".md",
40 ".json",
41 ".py",
42 ".js",
43 ".ts",
44 ".tsx",
45 ".jsx",
46 ".yaml",
47 ".yml",
48 ".toml",
49 ".csv",
50 ".log",
51}
52
53def _resolve_path(raw_path: str) -> Path:
54 path = Path(raw_path).expanduser().resolve()
55 for root in ALLOWED_ROOTS:
56 root = root.resolve()
57 if path == root or root in path.parents:
58 return path
59 raise ValueError(f"Percorso non consentito: {path}")
60
61def _ensure_safe_command(command: str) -> str:
62 normalized = " ".join(shlex.split(command))
63 if normalized not in ALLOWED_COMMANDS:
64 raise ValueError(
65 "Comando non consentito. Aggiungilo esplicitamente a ALLOWED_COMMANDS se ne hai davvero bisogno."
66 )
67 return normalized
68
69@app.tool()
70def list_files(path: str = "~") -> dict[str, Any]:
71 """Elenca file e cartelle all'interno di una directory approvata."""
72 target = _resolve_path(path)
73 if not target.is_dir():
74 raise ValueError(f"Non è una directory: {target}")
75
76 items = []
77 for child in sorted(target.iterdir(), key=lambda p: (not p.is_dir(), p.name.lower())):
78 items.append(
79 {
80 "name": child.name,
81 "path": str(child),
82 "type": "directory" if child.is_dir() else "file",
83 }
84 )
85
86 return {
87 "path": str(target),
88 "count": len(items),
89 "items": items,
90 }
91
92@app.tool()
93def read_file(path: str, max_chars: int = 12000) -> dict[str, Any]:
94 """Legge un file di testo sicuro da una posizione approvata."""
95 target = _resolve_path(path)
96 if not target.is_file():
97 raise ValueError(f"Non è un file: {target}")
98 if target.suffix.lower() not in READABLE_EXTENSIONS:
99 raise ValueError(f"Tipo di file non supportato: {target.suffix}")
100
101 content = target.read_text(encoding="utf-8", errors="replace")
102 truncated = len(content) > max_chars
103 content = content[:max_chars]
104
105 return {
106 "path": str(target),
107 "truncated": truncated,
108 "content": content,
109 }
110
111@app.tool()
112def run_command(command: str, cwd: str | None = None, timeout: int = 15) -> dict[str, Any]:
113 """Esegue un comando locale consentito."""
114 safe_command = _ensure_safe_command(command)
115 working_dir = _resolve_path(cwd) if cwd else PROJECT_ROOT
116
117 completed = subprocess.run(
118 safe_command,
119 shell=True,
120 cwd=str(working_dir),
121 capture_output=True,
122 text=True,
123 timeout=timeout,
124 )
125
126 return {
127 "command": safe_command,
128 "cwd": str(working_dir),
129 "returncode": completed.returncode,
130 "stdout": completed.stdout.strip(),
131 "stderr": completed.stderr.strip(),
132 }
133
134@app.tool()
135def take_screenshot(name: str = "latest") -> dict[str, Any]:
136 """Cattura uno screenshot e lo salva localmente."""
137 output_path = CAPTURE_DIR / f"{name}.png"
138
139 with mss.mss() as sct:
140 sct.shot(output=str(output_path))
141
142 return {
143 "saved": True,
144 "path": str(output_path),
145 }
146
147@app.tool()
148def open_target(target: str) -> dict[str, Any]:
149 """Apre un file, una cartella, un'app o un URL approvato usando il sistema operativo locale."""
150 system = platform.system().lower()
151
152 if target.startswith("http://") or target.startswith("https://"):
153 resolved = target
154 else:
155 resolved = str(_resolve_path(target))
156
157 if system == "darwin":
158 subprocess.run(["open", resolved], check=True)
159 elif system == "windows":
160 os.startfile(resolved) # type: ignore[attr-defined]
161 else:
162 subprocess.run(["xdg-open", resolved], check=True)
163
164 return {
165 "opened": True,
166 "target": resolved,
167 }
168
169if __name__ == "__main__":
170 app.run(transport="stdio")

Questo è un server compatto, ma la parte importante non è la sua lunghezza. La parte importante è la forma dell'interfaccia:

  • ogni strumento ha un compito molto chiaro
  • ogni strumento restituisce dati strutturati
  • l'esecuzione dei comandi è limitata
  • l'accesso ai file è radicato
  • gli screenshot vanno in una cartella nota

Questo è esattamente ciò che vuoi in un server MCP locale.

Perché questi strumenti sono progettati in questo modo

I contenuti avanzati sugli strumenti per agenti non dovrebbero mai fermarsi a "ecco il codice." La forma dello strumento è la vera lezione.

list_files

Questo strumento dà a Claude una superficie di scoperta sicura. Dovrebbe essere in grado di rispondere a domande come:

  • Cosa c'è in questa cartella di progetto?
  • Quali note esistono in Documents?
  • Esiste già un file di log che posso ispezionare?

Ma non dovrebbe diventare un crawler ricorsivo dell'intero disco.

read_file

Questo è spesso lo strumento locale più utile di tutti. Una percentuale enorme del lavoro reale è ancora nascosta in note Markdown locali, log, CSV, documenti e file di progetto.

Il limite max_chars è importante. I file di grandi dimensioni sono un problema di contesto e latenza. Restituire l'intero contenuto di un file di log enorme è raramente utile.

run_command

Qui è dove la maggior parte delle persone diventa sciatta.

Il modello sicuro non è "consenti l'accesso alla shell, poi spera per il meglio." Il modello sicuro è "consenti un minuscolo insieme di comandi esatti e verificabili." Ecco perché l'esempio usa una lista di consentiti rigorosa.

take_screenshot

Uno strumento per screenshot è prezioso perché permette a Claude di partecipare ai flussi di lavoro del desktop. Anche se la tua prima versione salva solo l'immagine su disco, è già utile per report, debug dell'interfaccia utente, cattura di documentazione e passaggi di consegne strutturati.

open_target

Il controllo delle app non deve iniziare con l'automazione dell'interfaccia grafica. Per molti flussi di lavoro, "apri la cartella, il file o l'URL giusto" è sufficiente.

Questa è una v1 più duratura che fingere di aver bisogno della piena automazione del cursore dal primo giorno.

Connettere il server a Claude

I server MCP locali sono comunemente eseguiti su stdio, il che significa che Claude avvia il processo localmente e comunica con esso direttamente tramite stdin/stdout. Per un server di controllo del computer locale, questa è l'impostazione predefinita corretta perché evita inutili esposizioni di rete 4 5.

Claude Desktop supporta i server MCP locali tramite configurazione, dove avvia il processo del server per te. In pratica, usare percorsi assoluti per l'interprete e lo script è la configurazione meno fragile perché gli ambienti delle app GUI locali sono spesso più restrittivi del tuo terminale 2.

Una configurazione minima è questa:

json
1{
2 "mcpServers": {
3 "local-computer-control": {
4 "command": "/percorso/assoluto/per/python",
5 "args": [
6 "/percorso/assoluto/per/local-mcp-server/server.py"
7 ]
8 }
9 }
10}

Se preferisci uv, va bene anche quello:

json
1{
2 "mcpServers": {
3 "local-computer-control": {
4 "command": "/percorso/assoluto/per/uv",
5 "args": [
6 "--directory",
7 "/percorso/assoluto/per/local-mcp-server",
8 "run",
9 "python",
10 "server.py"
11 ]
12 }
13 }
14}

Dopo aver salvato la configurazione e riavviato Claude, gli strumenti del server dovrebbero apparire nell'elenco degli strumenti MCP locali. La configurazione MCP locale di Claude Desktop è costruita esattamente su questo modello: avvia un processo locale, connettiti tramite stdio ed esponi gli strumenti al modello 2 3.

Swati Gupta - inline image

Prompt che sono effettivamente utili per i test

Una volta che il server è connesso, non iniziare con orchestrazioni complicate. Inizia con controlli diretti e banali.

Prova prompt come:

  • "Elenca i file nella mia cartella Desktop."
  • "Leggi ~/Documents/todo.md e riassumi le tre priorità principali."
  • "Esegui git status nella mia cartella di progetto locale e spiega cosa è cambiato."
  • "Fai uno screenshot chiamato workspace-check."
  • "Apri il README del mio progetto."

Se questi flussi semplici funzionano in modo coerente, hai un server che vale la pena espandere.

Se non funzionano, aggiungere più strumenti nasconderà solo i veri problemi.

Dove i server MCP locali diventano veramente preziosi

Il caso d'uso ovvio è lo sviluppo, ma è solo una corsia.

Flusso di lavoro dello sviluppatore

Claude può:

  • ispezionare una cartella del repository
  • leggere un file di configurazione
  • eseguire git status
  • catturare uno screenshot di uno stato di bug
  • aprire la directory del progetto

Questo elimina già molti cambi di contesto.

Flusso di lavoro della ricerca

Claude può:

  • elencare le cartelle di ricerca
  • aprire e riassumere note Markdown
  • leggere CSV strutturati
  • salvare screenshot da strumenti o dashboard
  • aprire file sorgente o link del browser

Flusso di lavoro dei contenuti

Claude può:

  • scansionare una cartella di bozze
  • leggere idee di post esistenti
  • catturare uno screenshot di un riferimento di design
  • aprire il file di scrittura o l'URL giusto
  • eseguire un comando limitato che genera un artefatto di build o un'esportazione di bozza

Flusso di lavoro operativo

Claude può:

  • ispezionare i log dalle directory approvate
  • eseguire un comando diagnostico di sola lettura
  • aprire la cartella pertinente o il link della dashboard
  • salvare uno screenshot come prova

Questo è il vero punto dell'architettura: non il "controllo del computer" come trovata, ma la compressione del flusso di lavoro.

Il livello di sicurezza è il prodotto

Questa è la sezione che troppi articoli tecnici banalizzano.

La parte pericolosa dell'MCP locale non è il protocollo. È una cattiva progettazione dei permessi.

Se vuoi che questo server sia utilizzabile oltre una demo, costruisci il modello di sicurezza all'inizio.

Swati Gupta - inline image

Usa liste di directory consentite

Claude dovrebbe essere in grado di vedere solo i percorsi che approvi esplicitamente. Ecco perché _resolve_path() è il cuore degli strumenti per i file.

Usa liste di comandi consentiti

Non esporre mai l'esecuzione arbitraria della shell in una prima versione. Inizia con comandi esatti che puoi controllare riga per riga.

Separa gli strumenti di lettura dagli strumenti d'azione

Gli strumenti di sola lettura dovrebbero essere l'impostazione predefinita. Gli strumenti d'azione dovrebbero essere introdotti deliberatamente.

Registra tutto

Anche un semplice log JSON append-only rende il debug e la fiducia enormemente migliori.

Aggiungi un livello di conferma per le scritture

Se in seguito aggiungi write_file, move_file o delete_file, rendi questi strumenti che richiedono un secondo token di conferma o lasciali disabilitati per impostazione predefinita.

Considera una modalità di simulazione

Per gli strumenti che eseguono azioni, la modalità di simulazione è sottovalutata. Permette a Claude di spiegare cosa farebbe prima di farlo.

Esegui sotto un utente con restrizioni quando possibile

Se fai sul serio con l'automazione locale, non dare al tuo server MCP più privilegi del sistema operativo di quanto necessario.

Una buona regola pratica:

  • Livello 1: strumenti di sola lettura
  • Livello 2: azioni a basso rischio come apri file / apri app
  • Livello 3: azioni di scrittura confermate
  • Livello 4: azioni distruttive che probabilmente non dovresti esporre casualmente

La maggior parte delle persone non ha mai bisogno del Livello 4.

Swati Gupta - inline image

Cosa migliorare dopo la v1

Una solida prima versione guadagna il diritto di diventare più capace.

Una volta che il server di base è stabile, i prossimi aggiornamenti sensati sono:

  1. File di policy centralizzato

Sposta le tue regole in config/policy.json in modo che le modifiche siano dichiarative.

Esempio:

json
1{
2 "allowed_roots": [
3 "~/Documents",
4 "~/Desktop",
5 "./"
6 ],
7 "allowed_commands": [
8 "pwd",
9 "ls",
10 "git status",
11 "git diff --stat",
12 "python --version"
13 ]
14}
  1. Logging strutturato

Registra le chiamate agli strumenti, i timestamp, gli argomenti e i risultati in logs/server.log o in un file JSONL.

  1. Esecuzione di comandi più sicura

Invece di un singolo strumento di comando generico, suddividi i comandi in strumenti più mirati come:

  • git_status
  • show_current_directory
  • list_project_files

Questo rende la scelta dello strumento più facile per Claude e la sicurezza più facile per te.

  1. Migliore gestione degli screenshot

Puoi evolvere da "salva uno screenshot su disco" a:

  • catture con timestamp
  • cattura della finestra attiva
  • cattura di una regione
  • regole di conservazione dei file
  1. Adattatori di automazione specifici per sistema operativo

Su macOS, potresti in seguito aggiungere AppleScript o Shortcuts. Su Windows, PowerShell o UI Automation. Su Linux, lanciatori specifici del desktop e strumenti per finestre.

Ma questo dovrebbe venire dopo che il noioso nucleo locale è affidabile.

Errori comuni che le persone fanno con i server MCP locali

Gli errori sono prevedibili.

Errore 1: Troppo potere, troppo presto

Alla gente piace l'idea del controllo totale del computer. A loro non piace fare il debug. Inizia in piccolo.

Errore 2: Nomi di strumenti vaghi

Se i nomi dei tuoi strumenti sono ambigui, Claude li userà male. Sii esplicito.

Male:

  • system_action
  • computer_control

Meglio:

  • list_files
  • read_file
  • run_command
  • take_screenshot
  • open_target

Errore 3: Output non strutturati

Un blob di testo misto è più difficile da elaborare per Claude rispetto a un oggetto JSON pulito.

Errore 4: Nessun logging

Se uno strumento fallisce e non puoi vedere perché, il sistema diventa un'ipotesi.

Errore 5: Trattare il modello come il livello di controllo

Claude è il livello di ragionamento. Il tuo server deve essere ancora il livello di applicazione.

Quella distinzione non è negoziabile.

Cosa fa questa architettura meglio dell'automazione semplice

L'automazione desktop tradizionale è di solito una di due cose:

  • scripting GUI fragile
  • script isolati che richiedono che un umano sappia esattamente quando eseguirli

Un server MCP locale cambia questo perché Claude può decidere quale strumento usare in base alla richiesta dell'utente e al contesto disponibile.

Questo significa che non stai solo automatizzando un comando. Stai costruendo un livello di capacità locale su cui il modello può ragionare.

Ecco perché MCP sembra importante. Non è semplicemente un altro modello di integrazione. È un modo più pulito per esporre l'uso degli strumenti al modello senza codificare ogni possibile flusso di lavoro nel livello dell'applicazione.

I limiti che dovresti rispettare

Anche un buon server MCP locale ha limiti reali.

  • L'automazione desktop può essere instabile tra i sistemi operativi.
  • Gli screenshot sono utili, ma non magici.
  • L'avvio di app è facile; la manipolazione affidabile dell'interfaccia utente è più difficile.
  • L'accesso generico alla shell è pericoloso.
  • Il gonfiamento del contesto è reale se gli output degli strumenti sono troppo grandi.
  • L'approvazione umana è ancora preziosa per qualsiasi cosa di conseguenza.

In altre parole: non confondere "il modello può eseguire azioni" con "il modello dovrebbe agire senza supervisione."

Il modello più prezioso è il controllo collaborativo, non l'autonomia cieca.

Salva con un clic

Leggi in profondità gli articoli virali con l’AI di YouMind

Salva la fonte, fai domande mirate, riassumi l’argomentazione e trasforma un articolo virale in note riutilizzabili in un unico spazio di lavoro AI.

Scopri YouMind
Per i creator

Trasforma il tuo Markdown in un articolo 𝕏 pulito

Quando pubblichi i tuoi testi lunghi, formattare immagini, tabelle e blocchi di codice per 𝕏 è una seccatura. YouMind trasforma un'intera bozza Markdown in un articolo 𝕏 pulito e pronto da pubblicare.

Prova Markdown verso 𝕏

Altri pattern da decodificare

Articoli virali recenti

Esplora altri articoli virali