Tôi cảm thấy mệt mỏi khi phải sao chép các tệp vào một cuộc trò chuyện AI chỉ để nhận phản hồi. Vì vậy, tôi đã xây dựng một máy chủ MCP (Master Control Program) thuần Python, cung cấp cho các công cụ AI quyền truy cập trực tiếp vào dự án cục bộ của tôi—không cần framework, không cần thư viện phụ thuộc. Nó chạy qua stdio (standard input/output) để sử dụng cục bộ và chuyển sang HTTP/SSE (Server-Sent Events) cho các máy khách đồng thời chỉ với một cờ lệnh duy nhất. Kết quả: 5 máy khách, dưới 50ms, và một thiết kế vẫn đơn giản mà không làm giảm khả năng.
Bài viết "AI của tôi không thể xem tệp của tôi — Tôi đã xây dựng một máy chủ MCP không phụ thuộc" xuất hiện lần đầu trên Towards Data Science.
Mô hình ngôn ngữ lớn
AI của tôi không thể truy cập tệp của tôi — Tôi đã xây dựng một máy chủ MCP không phụ thuộc
Tôi đã xây dựng một lớp MCP thuần Python chạy trên stdio cho các máy khách cục bộ và HTTP/SSE cho các kết nối đồng thời. Một cờ. Không phụ thuộc. 5 máy khách. Dưới 50ms.
Emmimal P Alexander
Ngày 5/6/2026
17 phút đọc
Chia sẻ
Hình ảnh do tác giả cung cấp, được tạo bằng ChatGPT (DALL·E)
Tôi đang tái cấu trúc một trình cạo dữ liệu. Các hàm đã trở nên quá dài và tên biến không còn ý nghĩa nữa. Mỗi khi tôi muốn phản hồi về một tệp, tôi dừng lại, mở cuộc trò chuyện, sao chép toàn bộ nội dung vào đó và chờ đợi. Sau đó quay lại trình chỉnh sửa, áp dụng thay đổi, mở tệp tiếp theo và lặp lại.
Đến một lúc nào đó tôi đã đếm. Sáu tệp. Mười một lần dán. Hai mươi phút chuyển đổi trước khi tôi viết một dòng mới.
Giải pháp rõ ràng là cấp cho công cụ AI quyền truy cập trực tiếp vào thư mục dự án của tôi. Đó là lúc tôi gặp MCP — Giao thức ngữ cảnh mô hình — được xây dựng chính xác cho mục đích này. Một máy chủ chạy cục bộ, hiển thị các công cụ và máy khách AI gọi trực tiếp các công cụ đó thay vì chờ tôi dán.
Vì vậy, tôi đã xem xét các triển khai hiện có. Hầu hết yêu cầu FastAPI, uvicorn, LangChain hoặc SDK MCP chính thức. Trước khi viết một dòng logic nghiệp vụ nào, tôi đã có năm gói trong tệp yêu cầu của mình và một máy chủ mà tôi không tự tin rằng sẽ chạy trên Windows mà không gặp khó khăn.
Tôi lùi lại và đọc thông số kỹ thuật MCP thực tế [1]. Giao thức là JSON-RPC 2.0 [2] qua một lớp truyền tải. Một đối tượng JSON mỗi dòng. Máy khách gửi, máy chủ phản hồi. Thông số kỹ thuật định nghĩa chính xác hai phương thức truyền tải: stdio cho các kết nối máy khách đơn cục bộ và HTTP với Server-Sent Events cho các máy khách đồng thời.
Đó là toàn bộ giao thức.
Tôi đã đặt một câu hỏi khác: điều này thực sự cần gì mà thư viện chuẩn của Python chưa cung cấp? sys.stdin, sys.stdout, http.server, threading, queue, pathlib, json. Chỉ vậy thôi. Không cần cài đặt pip nào.
Bài viết này là triển khai đó — cả hai phương thức truyền tải, mô hình bảo mật sản xuất, 50 bài kiểm tra và các số liệu từ việc chạy nó.
Tóm tắt
Hầu hết các triển khai MCP đều cảm thấy nặng nề hơn mức cần thiết. Thông số kỹ thuật chỉ định nghĩa hai phương thức truyền tải, stdio và HTTP/SSE, nhưng trên thực tế chúng thường được gói trong các framework và các phụ thuộc bổ sung.
Tôi đã xây dựng cả hai phương thức truyền tải từ đầu chỉ sử dụng thư viện chuẩn của Python.
Nó chạy dưới dạng một tệp duy nhất với một cờ thời gian chạy. Không cài đặt, không thiết lập.
Đối với công việc cục bộ, nó sử dụng stdio với một máy khách duy nhất. Khi bạn cần đồng thời, nó chuyển sang HTTP/SSE và xử lý nhiều máy khách mà không thay đổi bất cứ điều gì khác.
Bên dưới, mọi thứ vẫn nhất quán. Cùng một bộ điều phối, cùng một công cụ, cùng một mô hình bảo mật.
Vì nó chạm vào hệ thống tệp, tôi đã thêm các kiểm tra đường dẫn nghiêm ngặt ngay từ đầu. Các mẫu thoát phổ biến như ../../, các thủ thuật liên kết tượng trưng và đường dẫn UNC của Windows đều bị chặn.
5 máy khách đồng thời. Tổng thời gian thực dưới 50ms. Đã xác minh trên Windows 11, Python 3.12.6, chỉ CPU.
Mã đầy đủ: https://github.com/Emmimal/local-mcp-server/
Sai lầm đã định hình toàn bộ thiết kế
Trước khi nói về kiến trúc, tôi muốn kể cho bạn nghe về điều suýt chút nữa đã khiến tôi từ bỏ toàn bộ dự án.
Trong giai đoạn đầu phát triển, tôi đang thử nghiệm công cụ tìm kiếm. Tôi đã trỏ máy chủ vào C:\Users\Admin và chạy nó để tìm các tệp Python. Máy chủ đã khởi động. Bản demo bắt đầu chạy. Sau đó nó cứ tiếp tục chạy.
Ba mươi giây. Một phút. Năm phút. Tôi nghĩ có một vòng lặp vô hạn ở đâu đó. Tôi đã xem lại mã ba lần. Mọi thứ đều có vẻ đúng. Tôi đã dừng tiến trình và khởi động lại. Kết quả tương tự.
Mười phút sau, tôi cuối cùng cũng hiểu chuyện gì đang xảy ra. Công cụ tìm kiếm đang sử dụng rglob() theo mặc định. Tôi đã trỏ nó vào toàn bộ thư mục người dùng của mình và nó đang quét mọi thứ — môi trường ảo, AppData, mọi tệp được lưu trong bộ nhớ cache trên máy. Hàng chục nghìn tệp, từng tệp một.
Tôi đã dừng tiến trình và thay đổi một dòng:
# Trước — đệ quy theo mặc định, quét mọi thứ
for match in target.rglob(pattern):
# Sau — nông theo mặc định, chọn tham gia đệ quy
for match in target.glob(pattern):
Và đặt recursive=False làm tham số mặc định. Máy khách phải truyền recursive=True một cách rõ ràng. Máy chủ sẽ không bao giờ quét đệ quy một mình.
Thay đổi duy nhất đó là lý do tại sao tìm kiếm hoàn thành trong vòng chưa đầy 30ms trên một thư mục dự án thực tế ngày nay thay vì chạy mãi mãi. Và nó trở thành quy tắc tôi áp dụng ở mọi nơi: không có hành vi nào làm giảm hiệu suất đáng kể nên là mặc định.
MCP thực sự là gì
Giao thức ngữ cảnh mô hình (Model Context Protocol - MCP) [1] là một cách chuẩn hóa để các máy khách AI gọi các công cụ trên các máy chủ bên ngoài. Nó sử dụng JSON-RPC 2.0 [2] làm định dạng thông báo của nó.
Trong thực tế, điều này có nghĩa là các máy khách AI như Claude hoặc ChatGPT có thể trực tiếp truy cập và suy luận trên các tệp cục bộ thay vì dựa vào sao chép-dán.
Quá trình bắt tay có ba giai đoạn. Đầu tiên, máy khách khởi tạo, sau đó nó hỏi những công cụ nào có sẵn, sau đó nó bắt đầu gọi chúng:
Vòng đời thông báo của Giao thức ngữ cảnh mô hình (MCP). Một cái nhìn tổng quan kiến trúc rõ ràng cho thấy sự trao đổi JSON-RPC tuần tự, hai chiều giữa Máy khách và Máy chủ trong các giai đoạn Khởi tạo, Khám phá và Thực thi. Hình ảnh của Tác giả
Mọi thứ sau đó là phương tiện vận chuyển mang các thông báo qua lại.
Đặc tả định nghĩa hai phương tiện vận chuyển. stdio chạy qua đầu vào và đầu ra tiêu chuẩn — một đối tượng JSON trên mỗi dòng, được xóa ngay lập tức. HTTP/SSE chạy các yêu cầu qua HTTP POST, với các phản hồi được truyền trở lại qua kết nối Sự kiện được gửi từ máy chủ (Server-Sent Events) liên tục [3].
Hầu hết các triển khai chọn một. Triển khai này thực hiện cả hai, với cùng một bộ điều phối và cùng bốn công cụ nằm sau mỗi cái.
Đây là những gì bản demo hiển thị khi khởi động — cả hai phương tiện vận chuyển đều đăng ký các công cụ tương tự:
[2] Các công cụ có sẵn
[list_directory ] Liệt kê các tệp và thư mục. Trả về tên, loại, kích thước...
[read_file ] Đọc nội dung của một tệp. Tối đa 1 MB. Các tệp nhị phân được trả về...
[search_files ] Tìm kiếm tệp theo mẫu glob. Sử dụng recursive=true cho...
[get_file_info ] Lấy siêu dữ liệu cho một tệp hoặc thư mục: kích thước, loại, phần mở rộng...
Nguồn tin: Towards Data Science — Tác giả: Emmimal P Alexander. Bản dịch tiếng Việt do AI thực hiện, có thể có sai sót.