Claude trở nên hữu ích hơn rất nhiều khi nó không chỉ là một giao diện trò chuyện.
Một máy chủ MCP cục bộ cho phép Claude tương tác với máy tính thực tế của bạn: các tệp cục bộ, các lệnh đã được phê duyệt, ảnh chụp màn hình và khởi chạy ứng dụng. Phần quan trọng không phải là quyền truy cập thô. Mà là quyền truy cập có kiểm soát.
Trong hướng dẫn này, chúng ta sẽ xây dựng một máy chủ MCP cục bộ cho Claude, vừa thực tế, vừa hẹp, vừa đủ an toàn để sử dụng trong các quy trình làm việc thực tế.
Một lưu ý nhanh trước khi chúng ta xây dựng bất cứ thứ gì
Bài viết này cố tình tránh phiên bản "điều khiển máy tính" một cách thiếu trách nhiệm.
Chúng tôi sẽ không cấp cho Claude quyền truy cập shell không giới hạn, toàn quyền hệ thống tệp hoặc quyền thay đổi máy tính của bạn mà không có rào cản. Cách nhanh nhất để xây dựng một máy chủ MCP cục bộ tồi là expose một công cụ run_anything() khổng lồ và gọi đó là sự đổi mới.
Mô hình tốt hơn là:
- các thư mục được phép (allowlisted directories)
- các lệnh được phép (allowlisted commands)
- các giá trị mặc định an toàn
- nhật ký có thể đọc được bởi con người
- phản hồi rõ ràng
- sự phân tách rõ ràng giữa các công cụ chỉ đọc và công cụ hành động
Nếu Claude có thể làm mọi thứ, bạn đã xây dựng một bản demo.
Nếu Claude có thể làm những việc đúng đắn một cách an toàn, bạn đã xây dựng một thứ có thể sử dụng được.
Tại sao kiến trúc này đáng để học
Giá trị của một máy chủ MCP cục bộ không phải là sự mới lạ. Đó là sự giảm thiểu ma sát.
Nếu không có lớp công cụ cục bộ, quy trình làm việc của bạn sẽ như thế này:
- Hỏi Claude phải làm gì
- Sao chép câu trả lời
- Tự mở thư mục
- Tự chạy lệnh
- Tự chụp ảnh màn hình
- Dán kết quả trở lại cuộc trò chuyện
Với một máy chủ MCP cục bộ, vòng lặp đó trở nên chặt chẽ hơn đáng kể. Claude có thể kiểm tra ngữ cảnh cần thiết, sử dụng các công cụ có phạm vi hẹp và trả về câu trả lời dựa trên trạng thái máy tính thực tế của bạn.
Điều đó hữu ích cho:
- quy trình làm việc phát triển
- kiểm tra nhật ký
- vận hành nội dung
- quy trình nghiên cứu
- tự động hóa máy tính để bàn
- các tác vụ quản trị lặp đi lặp lại
Và bởi vì lớp công cụ là của bạn, bạn chọn chính xác nơi mô hình dừng lại.
Muốn học AI và đi trước trong sự nghiệp của bạn?
Tôi chia sẻ:
Hơn 1.000 prompt AI
Các công cụ AI & tự động hóa
Mẹo phát triển sự nghiệp và LinkedIn
Tài nguyên công nghệ & năng suất được tuyển chọn
Đăng ký tại đây:
Theo dõi tôi để biết thêm mẹo AI
👇
Thiết kế chúng ta đang xây dựng

Chúng ta sẽ xây dựng một máy chủ cục bộ với năm công cụ:
- list_files — xem những gì tồn tại bên trong các thư mục được phê duyệt
- read_file — mở các tệp văn bản an toàn
- run_command — thực thi một tập hợp nhỏ các lệnh cục bộ đã được phê duyệt
- take_screenshot — lưu ảnh chụp màn hình vào một vị trí đã biết
- open_target — mở một ứng dụng, tệp, thư mục hoặc URL

Phạm vi đó là có chủ đích.
Nó đủ để làm cho Claude trở nên hữu ích một cách có ý nghĩa trên máy cục bộ mà không bị sụp đổ thành tự động hóa mục đích chung không an toàn.
Mô hình tinh thần sẽ trông như thế này:
Claude → MCP client → máy chủ MCP cục bộ → các công cụ hẹp → hệ điều hành
Claude không bao giờ nên nói chuyện trực tiếp với hệ điều hành của bạn. Máy chủ MCP của bạn là mặt phẳng điều khiển ở giữa.
Công nghệ sử dụng
Đối với một bản dựng cục bộ, Python là một lựa chọn sạch sẽ vì MCP SDK chính thức đã trưởng thành, FastMCP abstraction rất ngắn gọn và Python vẫn là ngôn ngữ dễ nhất cho các công việc viết script hệ thống tệp, subprocess và desktop 4 2.
Chúng ta sẽ sử dụng:
- Python 3.11+
- mcp[cli] cho runtime máy chủ MCP
- mss cho ảnh chụp màn hình đa nền tảng
- các mô-đun thư viện chuẩn để truy cập tệp, gọi subprocess và xử lý hệ điều hành
Thiết lập một dự án mới:
1mkdir local-mcp-server2cd local-mcp-server3uv init --python 3.114uv add "mcp[cli]>=1.0,<2.0" "mss>=9.0,<10.0"
Phong cách FastMCP dựa trên decorator giữ lớp giao thức tránh xa bạn để bạn có thể tập trung vào chất lượng công cụ thay vì kết nối 4 5.
Một bố cục dự án đơn giản hoạt động tốt:
1mkdir local-mcp-server2cd local-mcp-server3uv init --python 3.114uv add "mcp[cli]>=1.0,<2.0" "mss>=9.0,<10.0"
Bạn không cần một kiến trúc phức tạp cho v1. Điều bạn cần là sự rõ ràng.
Máy chủ thực tế
Tạo server.py và bắt đầu với một triển khai dựa trên chính sách.
1from __future__ import annotations23import json4import os5import platform6import shlex7import subprocess8from pathlib import Path9from typing import Any1011import mss12from mcp.server.fastmcp import FastMCP1314app = FastMCP("local-computer-control", json_response=True)1516HOME = Path.home()17PROJECT_ROOT = Path(__file__).parent.resolve()18CAPTURE_DIR = PROJECT_ROOT / "captures"19CAPTURE_DIR.mkdir(exist_ok=True)2021ALLOWED_ROOTS = [22 HOME / "Documents",23 HOME / "Desktop",24 PROJECT_ROOT,25]2627ALLOWED_COMMANDS = {28 "pwd",29 "ls",30 "git status",31 "git diff --stat",32 "python --version",33 "node --version",34 "npm --version",35}3637READABLE_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}5253def _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 path59 raise ValueError(f"Path not allowed: {path}")6061def _ensure_safe_command(command: str) -> str:62 normalized = " ".join(shlex.split(command))63 if normalized not in ALLOWED_COMMANDS:64 raise ValueError(65 "Command not allowed. Add it explicitly to ALLOWED_COMMANDS if you really need it."66 )67 return normalized6869@app.tool()70def list_files(path: str = "~") -> dict[str, Any]:71 """List files and folders inside an approved directory."""72 target = _resolve_path(path)73 if not target.is_dir():74 raise ValueError(f"Not a directory: {target}")7576 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 )8586 return {87 "path": str(target),88 "count": len(items),89 "items": items,90 }9192@app.tool()93def read_file(path: str, max_chars: int = 12000) -> dict[str, Any]:94 """Read a safe text file from an approved location."""95 target = _resolve_path(path)96 if not target.is_file():97 raise ValueError(f"Not a file: {target}")98 if target.suffix.lower() not in READABLE_EXTENSIONS:99 raise ValueError(f"Unsupported file type: {target.suffix}")100101 content = target.read_text(encoding="utf-8", errors="replace")102 truncated = len(content) > max_chars103 content = content[:max_chars]104105 return {106 "path": str(target),107 "truncated": truncated,108 "content": content,109 }110111@app.tool()112def run_command(command: str, cwd: str | None = None, timeout: int = 15) -> dict[str, Any]:113 """Run one allowlisted local command."""114 safe_command = _ensure_safe_command(command)115 working_dir = _resolve_path(cwd) if cwd else PROJECT_ROOT116117 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 )125126 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 }133134@app.tool()135def take_screenshot(name: str = "latest") -> dict[str, Any]:136 """Capture a screenshot and save it locally."""137 output_path = CAPTURE_DIR / f"{name}.png"138139 with mss.mss() as sct:140 sct.shot(output=str(output_path))141142 return {143 "saved": True,144 "path": str(output_path),145 }146147@app.tool()148def open_target(target: str) -> dict[str, Any]:149 """Open an approved file, folder, app, or URL using the local OS."""150 system = platform.system().lower()151152 if target.startswith("http://") or target.startswith("https://"):153 resolved = target154 else:155 resolved = str(_resolve_path(target))156157 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)163164 return {165 "opened": True,166 "target": resolved,167 }168169if __name__ == "__main__":170 app.run(transport="stdio")
Đây là một máy chủ nhỏ gọn, nhưng phần quan trọng không phải là độ dài của nó. Phần quan trọng là hình dạng của giao diện:
- mọi công cụ đều có một công việc rất rõ ràng
- mọi công cụ đều trả về dữ liệu có cấu trúc
- việc thực thi lệnh bị giới hạn
- quyền truy cập tệp có gốc rễ
- ảnh chụp màn hình được lưu vào một thư mục đã biết
Đó chính xác là những gì bạn muốn trong một máy chủ MCP cục bộ.
Tại sao các công cụ này được thiết kế theo cách này
Nội dung cấp cao về công cụ agent không bao giờ nên dừng lại ở "đây là code". Hình dạng công cụ mới là bài học thực sự.
list_files
Công cụ này cung cấp cho Claude một bề mặt khám phá an toàn. Nó sẽ có thể trả lời các câu hỏi như:
- Có gì trong thư mục dự án này?
- Những ghi chú nào tồn tại trong Documents?
- Đã có tệp nhật ký nào tôi có thể kiểm tra chưa?
Nhưng nó không nên trở thành một trình thu thập toàn bộ đĩa đệ quy.
read_file
Đây thường là công cụ cục bộ hữu ích nhất trong tất cả. Một phần trăm lớn công việc thực tế vẫn ẩn trong các ghi chú Markdown, nhật ký, CSV, tài liệu và tệp dự án cục bộ.
Giới hạn max_chars rất quan trọng. Các tệp lớn là một vấn đề về ngữ cảnh và độ trễ. Trả về toàn bộ nội dung của một tệp nhật ký khổng lồ hiếm khi hữu ích.
run_command
Đây là nơi hầu hết mọi người trở nên cẩu thả.
Mô hình an toàn không phải là "cho phép truy cập shell, sau đó hy vọng điều tốt nhất." Mô hình an toàn là "cho phép một tập hợp nhỏ các lệnh chính xác, có thể xem xét." Đó là lý do tại sao ví dụ sử dụng một danh sách cho phép nghiêm ngặt.
take_screenshot
Một công cụ chụp màn hình có giá trị vì nó cho phép Claude tham gia vào các quy trình làm việc trên máy tính để bàn. Ngay cả khi phiên bản đầu tiên của bạn chỉ lưu hình ảnh vào đĩa, điều đó đã hữu ích cho việc báo cáo, gỡ lỗi giao diện người dùng, chụp tài liệu và bàn giao có cấu trúc.
open_target
Kiểm soát ứng dụng không cần phải bắt đầu bằng tự động hóa GUI. Đối với nhiều quy trình làm việc, "mở đúng thư mục, tệp hoặc URL" là đủ.
Đó là một v1 bền vững hơn là giả vờ bạn cần tự động hóa con trỏ đầy đủ ngay từ ngày đầu tiên.
Kết nối máy chủ với Claude
Các máy chủ MCP cục bộ thường được chạy qua stdio, có nghĩa là Claude khởi chạy tiến trình cục bộ và giao tiếp trực tiếp với nó qua stdin/stdout. Đối với một máy chủ điều khiển máy tính cục bộ, đó là mặc định đúng đắn vì nó tránh tiếp xúc mạng không cần thiết 4 5.
Claude Desktop hỗ trợ các máy chủ MCP cục bộ thông qua cấu hình, nơi nó khởi chạy tiến trình máy chủ cho bạn. Trong thực tế, sử dụng đường dẫn tuyệt đối cho trình thông dịch và script là thiết lập ít mong manh nhất vì môi trường ứng dụng GUI cục bộ thường nghiêm ngặt hơn terminal của bạn 2.
Một cấu hình tối thiểu trông như thế này:
1{2 "mcpServers": {3 "local-computer-control": {4 "command": "/absolute/path/to/python",5 "args": [6 "/absolute/path/to/local-mcp-server/server.py"7 ]8 }9 }10}
Nếu bạn thích uv, điều đó cũng tốt:
1{2 "mcpServers": {3 "local-computer-control": {4 "command": "/absolute/path/to/uv",5 "args": [6 "--directory",7 "/absolute/path/to/local-mcp-server",8 "run",9 "python",10 "server.py"11 ]12 }13 }14}
Sau khi bạn lưu cấu hình và khởi động lại Claude, các công cụ máy chủ sẽ xuất hiện trong danh sách công cụ MCP cục bộ. Thiết lập MCP cục bộ của Claude Desktop được xây dựng xung quanh chính xác mô hình này: khởi chạy một tiến trình cục bộ, kết nối qua stdio và expose các công cụ cho mô hình 2 3.

Các prompt thực sự hữu ích cho việc kiểm tra
Khi máy chủ đã được kết nối, đừng bắt đầu với sự phối hợp phức tạp. Hãy bắt đầu với các kiểm tra trực tiếp, đơn giản.
Hãy thử các prompt như:
- "Liệt kê các tệp trong thư mục Desktop của tôi."
- "Đọc ~/Documents/todo.md và tóm tắt ba ưu tiên hàng đầu."
- "Chạy git status trong thư mục dự án cục bộ của tôi và giải thích những gì đã thay đổi."
- "Chụp ảnh màn hình có tên workspace-check."
- "Mở README dự án của tôi."
Nếu các luồng đơn giản đó hoạt động nhất quán, bạn có một máy chủ đáng để mở rộng.
Nếu không, việc thêm nhiều công cụ hơn sẽ chỉ che giấu các vấn đề thực sự.
Nơi các máy chủ MCP cục bộ trở nên thực sự có giá trị
Trường hợp sử dụng rõ ràng là phát triển, nhưng đó chỉ là một làn đường.
Quy trình làm việc của nhà phát triển
Claude có thể:
- kiểm tra một thư mục repo
- đọc một tệp cấu hình
- chạy git status
- chụp ảnh màn hình của một trạng thái lỗi
- mở thư mục dự án
Điều đó đã loại bỏ rất nhiều sự chuyển đổi ngữ cảnh.
Quy trình làm việc nghiên cứu
Claude có thể:
- liệt kê các thư mục nghiên cứu
- mở và tóm tắt các ghi chú Markdown
- đọc các CSV có cấu trúc
- lưu ảnh chụp màn hình từ các công cụ hoặc bảng điều khiển
- mở các tệp nguồn hoặc liên kết trình duyệt
Quy trình làm việc nội dung
Claude có thể:
- quét một thư mục bản nháp
- đọc các ý tưởng bài viết hiện có
- chụp ảnh màn hình của một tài liệu tham khảo thiết kế
- mở tệp viết hoặc URL phù hợp
- chạy một lệnh giới hạn tạo ra một artifact bản dựng hoặc bản xuất nháp
Quy trình làm việc vận hành
Claude có thể:
- kiểm tra nhật ký từ các thư mục được phê duyệt
- chạy một lệnh chẩn đoán chỉ đọc
- mở thư mục có liên quan hoặc liên kết bảng điều khiển
- lưu ảnh chụp màn hình bằng chứng
Đây là điểm thực sự của kiến trúc: không phải là "điều khiển máy tính" như một màn trình diễn, mà là nén quy trình làm việc.
Lớp bảo mật là sản phẩm
Đây là phần mà quá nhiều bài viết kỹ thuật coi nhẹ.
Phần nguy hiểm của MCP cục bộ không phải là giao thức. Đó là thiết kế quyền hạn kém.
Nếu bạn muốn máy chủ này có thể sử dụng được ngoài một bản demo, hãy xây dựng mô hình an toàn sớm.

Sử dụng danh sách cho phép thư mục
Claude chỉ có thể thấy các đường dẫn bạn phê duyệt một cách rõ ràng. Đó là lý do tại sao _resolve_path() là cốt lõi của các công cụ tệp.
Sử dụng danh sách cho phép lệnh
Không bao giờ expose thực thi shell tùy ý trong phiên bản đầu tiên. Bắt đầu với các lệnh chính xác mà bạn có thể kiểm tra từng dòng.
Tách biệt các công cụ đọc khỏi các công cụ hành động
Các công cụ chỉ đọc nên là mặc định. Các công cụ hành động nên được giới thiệu một cách có chủ đích.
Ghi nhật ký mọi thứ
Ngay cả một nhật ký JSON chỉ nối thêm đơn giản cũng làm cho việc gỡ lỗi và tin cậy tốt hơn đáng kể.
Thêm một lớp xác nhận cho các thao tác ghi
Nếu sau này bạn thêm write_file, move_file hoặc delete_file, hãy làm cho các công cụ đó yêu cầu một token xác nhận thứ hai hoặc giữ chúng bị vô hiệu hóa theo mặc định.
Cân nhắc chế độ dry-run
Đối với các công cụ hành động, chế độ dry-run bị đánh giá thấp. Nó cho phép Claude giải thích những gì nó sẽ làm trước khi nó làm điều đó.
Chạy dưới một người dùng bị hạn chế khi có thể
Nếu bạn nghiêm túc về tự động hóa cục bộ, đừng cấp cho máy chủ MCP của bạn nhiều đặc quyền hệ điều hành hơn mức cần thiết.
Một nguyên tắc hữu ích:
- Cấp độ 1: các công cụ chỉ đọc
- Cấp độ 2: các hành động rủi ro thấp như mở tệp / mở ứng dụng
- Cấp độ 3: các hành động ghi đã được xác nhận
- Cấp độ 4: các hành động phá hủy mà bạn có lẽ không nên expose một cách thông thường
Hầu hết mọi người không bao giờ cần Cấp độ 4.

Những gì cần cải thiện sau v1
Một phiên bản đầu tiên vững chắc kiếm được quyền trở nên có năng lực hơn.
Khi máy chủ cơ bản đã ổn định, các nâng cấp hợp lý tiếp theo là:
- Tệp chính sách tập trung
Di chuyển các quy tắc của bạn vào config/policy.json để các thay đổi mang tính khai báo.
Ví dụ:
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}
- Ghi nhật ký có cấu trúc
Ghi lại các lệnh gọi công cụ, dấu thời gian, đối số và kết quả vào logs/server.log hoặc một tệp JSONL.
- Thực thi lệnh an toàn hơn
Thay vì một công cụ lệnh chung chung duy nhất, hãy chia các lệnh thành các công cụ hẹp hơn như:
- git_status
- show_current_directory
- list_project_files
Điều đó làm cho việc lựa chọn công cụ dễ dàng hơn cho Claude và an toàn hơn cho bạn.
- Xử lý ảnh chụp màn hình tốt hơn
Bạn có thể phát triển từ "lưu ảnh chụp màn hình vào đĩa" thành:
- chụp có dấu thời gian
- chụp cửa sổ đang hoạt động
- chụp vùng
- quy tắc lưu giữ tệp
- Bộ điều hợp tự động hóa dành riêng cho hệ điều hành
Trên macOS, sau này bạn có thể thêm AppleScript hoặc Shortcuts. Trên Windows, PowerShell hoặc UI Automation. Trên Linux, các trình khởi chạy và công cụ cửa sổ dành riêng cho desktop.
Nhưng điều đó sẽ đến sau khi phần lõi cục bộ nhàm chán đáng tin cậy.
Những sai lầm phổ biến mọi người mắc phải với máy chủ MCP cục bộ
Những sai lầm có thể dự đoán trước.
Sai lầm 1: Quá nhiều sức mạnh, quá sớm
Mọi người thích ý tưởng về toàn quyền kiểm soát máy tính. Họ ghét việc gỡ lỗi nó. Bắt đầu nhỏ hơn.
Sai lầm 2: Tên công cụ mơ hồ
Nếu tên công cụ của bạn không rõ ràng, Claude sẽ sử dụng chúng một cách tồi tệ. Hãy rõ ràng.
Tệ:
- system_action
- computer_control
Tốt hơn:
- list_files
- read_file
- run_command
- take_screenshot
- open_target
Sai lầm 3: Đầu ra không có cấu trúc
Một khối văn bản hỗn hợp khó để Claude suy luận hơn một đối tượng JSON sạch sẽ.
Sai lầm 4: Không ghi nhật ký
Nếu một công cụ bị lỗi và bạn không thể thấy lý do tại sao, hệ thống trở nên phỏng đoán.
Sai lầm 5: Coi mô hình như lớp điều khiển
Claude là lớp suy luận. Máy chủ của bạn vẫn phải là lớp thực thi.
Sự khác biệt đó là không thể thương lượng.
Kiến trúc này làm tốt hơn tự động hóa đơn thuần ở điểm nào
Tự động hóa máy tính để bàn truyền thống thường là một trong hai điều:
- script GUI mong manh
- các script biệt lập yêu cầu con người biết chính xác khi nào chạy chúng
Một máy chủ MCP cục bộ thay đổi điều đó vì Claude có thể quyết định công cụ nào để sử dụng dựa trên yêu cầu của người dùng và ngữ cảnh có sẵn.
Điều đó có nghĩa là bạn không chỉ tự động hóa một lệnh. Bạn đang xây dựng một lớp khả năng cục bộ mà mô hình có thể suy luận.
Đây là lý do tại sao MCP cảm thấy quan trọng. Nó không chỉ đơn thuần là một mẫu tích hợp khác. Nó là một cách sạch hơn để expose việc sử dụng công cụ cho mô hình mà không cần hardcode mọi quy trình làm việc có thể có trong lớp ứng dụng.
Các giới hạn bạn nên tôn trọng
Ngay cả một máy chủ MCP cục bộ tốt cũng có những hạn chế thực tế.
- Tự động hóa máy tính để bàn có thể không ổn định trên các hệ điều hành khác nhau.
- Ảnh chụp màn hình rất hữu ích, nhưng không phải là phép màu.
- Khởi chạy ứng dụng thì dễ; thao tác giao diện người dùng đáng tin cậy thì khó hơn.
- Truy cập shell chung chung rất nguy hiểm.
- Sự phình to ngữ cảnh là có thật nếu đầu ra công cụ quá lớn.
- Sự chấp thuận của con người vẫn có giá trị đối với bất cứ điều gì hệ trọng.
Nói cách khác: đừng nhầm lẫn "mô hình có thể thực hiện các hành động" với "mô hình nên hành động mà không cần giám sát."
Mô hình có giá trị hơn là kiểm soát hợp tác, không phải là quyền tự chủ mù quáng.





