---
title: "Nên ghi log những gì cho mỗi lần gọi công cụ MCP"
description: "Với client, một máy chủ MCP từ xa chỉ là một span mờ đục, còn bảng điều khiển của thư mục chỉ thấy các con số tổng. Chỉ máy chủ thấy được lần gọi đó. Đây là dòng mà các máy chủ MCP của Tajo ghi cho mỗi lần gọi, từng trường một, những gì bị loại bỏ khỏi nó, và những gì chưa được xây dựng."
url: https://tajo.io/vi/blog/what-to-log-for-every-mcp-tool-call/
markdown: https://tajo.io/vi/blog/what-to-log-for-every-mcp-tool-call.md
lang: vi-VN
author: "Set Noa"
author_url: https://tajo.io/vi/set-noa/
published: 2026-11-06
updated: 2026-11-06
alternates: {en-US: /blog/what-to-log-for-every-mcp-tool-call.md, bg-BG: /bg/blog/what-to-log-for-every-mcp-tool-call.md, cs-CZ: /cz/blog/what-to-log-for-every-mcp-tool-call.md, de-DE: /de/blog/what-to-log-for-every-mcp-tool-call.md, da-DK: /dk/blog/what-to-log-for-every-mcp-tool-call.md, es-ES: /es/blog/what-to-log-for-every-mcp-tool-call.md, fr-FR: /fr/blog/what-to-log-for-every-mcp-tool-call.md, el-GR: /gr/blog/what-to-log-for-every-mcp-tool-call.md, hi-IN: /hi/blog/what-to-log-for-every-mcp-tool-call.md, id-ID: /in/blog/what-to-log-for-every-mcp-tool-call.md, hr-HR: /hr/blog/what-to-log-for-every-mcp-tool-call.md, hu-HU: /hu/blog/what-to-log-for-every-mcp-tool-call.md, it-IT: /it/blog/what-to-log-for-every-mcp-tool-call.md, ja-JP: /jp/blog/what-to-log-for-every-mcp-tool-call.md, ko-KR: /kr/blog/what-to-log-for-every-mcp-tool-call.md, ar-SA: /ar/blog/what-to-log-for-every-mcp-tool-call.md, nl-NL: /nl/blog/what-to-log-for-every-mcp-tool-call.md, no-NO: /no/blog/what-to-log-for-every-mcp-tool-call.md, pl-PL: /pl/blog/what-to-log-for-every-mcp-tool-call.md, pt-BR: /pt/blog/what-to-log-for-every-mcp-tool-call.md, ro-RO: /ro/blog/what-to-log-for-every-mcp-tool-call.md, ru-RU: /ru/blog/what-to-log-for-every-mcp-tool-call.md, sv-SE: /se/blog/what-to-log-for-every-mcp-tool-call.md, zh-CN: /zh-cn/blog/what-to-log-for-every-mcp-tool-call.md, sl-SI: /sl/blog/what-to-log-for-every-mcp-tool-call.md, sr-Latn-RS: /sr/blog/what-to-log-for-every-mcp-tool-call.md, th-TH: /th/blog/what-to-log-for-every-mcp-tool-call.md, tr-TR: /tr/blog/what-to-log-for-every-mcp-tool-call.md, ur-PK: /ur/blog/what-to-log-for-every-mcp-tool-call.md, sk-SK: /sk/blog/what-to-log-for-every-mcp-tool-call.md}
---

[Tác nhân AI](https://tajo.io/vi/blog/?category=ai-agents)

# Nên ghi log những gì cho mỗi lần gọi công cụ MCP

Với client, một máy chủ MCP từ xa chỉ là một span mờ đục, còn bảng điều khiển của thư mục chỉ thấy các con số tổng. Chỉ máy chủ thấy được lần gọi đó. Đây là dòng mà các máy chủ MCP của Tajo ghi cho mỗi lần gọi, từng trường một, những gì bị loại bỏ khỏi nó, và những gì chưa được xây dựng.

ghi log máy chủ mcp

Máy chủ MCP nên ghi lại những gì cho mỗi lần gọi công cụ?

Ghi một dòng cho mỗi lần gọi công cụ, trên máy chủ, vì máy chủ là nơi duy nhất thấy được lần gọi đó. Các máy chủ MCP của Tajo ghi lại ai đã gọi (id của khóa, không bao giờ là giá trị bí mật), máy chủ và connector nào, công cụ nếu nó tồn tại, lớp tác động, ok hoặc một mã lỗi ngắn, thời lượng, kích thước kết quả, trace id, các bản ghi mà lần gọi đã chạm tới, cùng các đối số và câu trả lời đã được loại bỏ bí mật và dữ liệu cá nhân. Các dòng được đọc bằng logs.list và logs.get và bị xóa sau 30 ngày. Chúng được lưu tách biệt với log kiểm toán dạng chuỗi băm, nơi lưu các phê duyệt và digest đầu vào của chúng. Chưa xây dựng: điểm sức khỏe, cảnh báo tỷ lệ lỗi, tìm kiếm theo công cụ hoặc trace id, và xuất sang hệ thống tracing của riêng bạn.

[Tìm hiểu thêm](https://tajo.io/vi/blog/what-to-log-for-every-mcp-tool-call/#m%E1%BB%99t-d%C3%B2ng-cho-m%E1%BB%97i-l%E1%BA%A7n-g%E1%BB%8Di)

Ngày 8 tháng 6 năm 2026, Anthropic cung cấp cho chủ sở hữu các connector trong thư mục của Claude một bảng điều khiển. Nó hiển thị số người dùng đang hoạt động, tổng số lần gọi công cụ và thứ hạng trong thư mục. Nó hiển thị “[điểm sức khỏe, tỷ lệ lỗi và độ trễ chỉ trong một cái nhìn, với phân tích lỗi theo từng công cụ để xác định chính xác điều gì đang hỏng](https://claude.com/resources/articles/observability-for-developers-building-connectors)”.

Một năm trước đó, Alex Volkov của Weights & Biases đã mô tả cùng vấn đề ấy từ đầu bên kia. Khi tác nhân của anh gọi công cụ qua MCP, “[toàn bộ khả năng quan sát mà tôi quen có khi mã của chính mình chạy từ đầu đến cuối đã trở nên hơi tối](https://www.youtube.com/watch?v=Lcqat4iP_lE&t=61s)”. Người cùng trình bày với anh, Benjamin Eckel của Dylibso, chỉ ra lý do. Một máy chủ MCP từ xa “[xuất hiện với chúng tôi trong trace như một span dịch vụ duy nhất](https://www.youtube.com/watch?v=Lcqat4iP_lE&t=447s)” vì nó chạy ngoài tầm kiểm soát của bên gọi.

Cả hai góc nhìn đều đứng bên ngoài máy chủ. Client thấy một span mờ đục. Thư mục thấy các con số tổng. Không bên nào thấy máy chủ đã được yêu cầu gì, đã từ chối gì và đã chạm vào gì. Chỉ máy chủ thấy, vì vậy chỉ máy chủ có thể ghi lại.

Đây là những gì các máy chủ MCP của Tajo ghi lại, được đọc từ chính mã chạy chúng và [được nêu trong tài liệu](https://tajo.io/vi/docs/mcp/#mcp-request-log). Bài [Máy chủ MCP là gì](https://tajo.io/vi/blog/what-is-an-mcp-server/) nói về giao thức. Bài này nói về dòng log.

## Một dòng cho mỗi lần gọi

Bảng điều khiển là góc nhìn của trưởng cảng: tàu vào, tàu ra, tàu nào đến muộn. Log yêu cầu là nhật ký hải trình của chính con tàu, được viết trên tàu vào đúng lúc đó.

Mọi `tools/call` trên máy chủ workspace của Tajo và trên mọi máy chủ connector đều [kết thúc bằng một dòng](https://tajo.io/vi/docs/mcp/#mcp-request-log). Dòng được ghi sau khi phản hồi đã được tạo, bất kể phản hồi đó là gì. Một lần gọi bị từ chối vì khóa không được phép ghi, hoặc vì endpoint chỉ cho phép đọc, cũng có một dòng như mọi lần gọi khác. Lần gọi đến một công cụ không tồn tại cũng vậy.

Đây là những gì dòng đó lưu, và những gì nó từ chối lưu.

| Trường | Được giữ | Không được giữ |
| --- | --- | --- |
| Ai | Id của khóa API đã gọi. Token từ đăng nhập OAuth cũng là một khóa. | Giá trị bí mật của khóa hoặc tiền tố của nó. |
| Ở đâu | Máy chủ workspace hoặc một máy chủ connector, cùng connector và hồ sơ của nó. |  |
| Công cụ | Tên, khi máy chủ có công cụ mang tên đó. | Bất kỳ tên nào khác mà client gửi: được lưu là `(unknown)`. |
| Tác động | `read`, `write`, `send` hoặc `destructive`: tác động nặng nhất mà lần gọi có thể gây ra. |  |
| Kết quả | `ok`, hoặc một mã lỗi snake\_case ngắn như `unknown_tool`. | Văn bản mô tả lỗi: mọi thứ không phải là mã đều được lưu là `tool_error`. |
| Thời lượng và kích thước | Số mili giây từ lúc đến tới lúc phản hồi, và số byte bên gọi nhận được. |  |
| Trace id | Id của yêu cầu, từ header `x-request-id`, `x-trace-id` hoặc W3C `traceparent`, nếu không có thì tạo mới. | Giá trị header không phải hex hoặc UUID. |
| Bản ghi | Tối đa 20 id của các bản ghi mà lần gọi nêu tên hoặc tạo ra: một liên hệ, một tin nhắn, một phê duyệt. | Bản thân các bản ghi. |
| Nội dung | Đối số và câu trả lời, [đã làm sạch](https://tajo.io/vi/docs/mcp/#mcp-request-log), tối đa 4 KB mỗi phần. | Bí mật, văn bản tự do và dữ liệu cá nhân được liệt kê bên dưới. |

Ba trong số các lần từ chối đó liên quan đến client, không phải dữ liệu. Tên công cụ, mã lỗi và trace id đều đến từ bên ngoài. Mỗi thứ chỉ được giữ ở dạng mà máy chủ có thể bảo đảm. Một log lưu bất cứ thứ gì bên gọi gửi tới có thể bị nhồi đủ thứ, kể cả địa chỉ email của khách hàng trong cột tên công cụ.

Câu hỏi mở của Benjamin Eckel ở cuối bài trình bày là làm sao một bộ thu thập biết “[đó là một lần gọi công cụ MCP bị lỗi](https://www.youtube.com/watch?v=Lcqat4iP_lE&t=906s)”. Trên một máy chủ, câu trả lời là một cột. `ok` là false, và mã cho biết đó là lỗi gì.

## Đối số: một quy tắc chúng tôi đã đảo ngược

Phản bác này là hợp lý, và đó là phản bác của chính chúng tôi. Ghi log đối số thì bạn đã tạo ra bản sao thứ hai của dữ liệu khách hàng, nằm ngoài mọi yêu cầu xóa. Cho đến ngày 18 tháng 10 năm 2026, đó là [quy tắc của chính chúng tôi](https://tajo.io/vi/docs/mcp/#mcp-request-log). Log không giữ đối số cũng không giữ nội dung kết quả, vì cả hai đều có thể chứa dữ liệu cá nhân.

Đó là một sự đánh đổi sai. Một log yêu cầu không thể cho thấy cái gì đã được gửi đi và cái gì đã quay về thì không thể trả lời câu hỏi duy nhất mà nó tồn tại để trả lời: vì sao lần gọi của tác nhân của tôi thất bại?

Vì vậy nội dung được giữ, và lý do trước đây không giữ được giải quyết theo cách khác. Mỗi phần nội dung đi qua [một lượt xử lý tất định](https://tajo.io/vi/docs/mcp/#mcp-request-log) trước khi được đưa vào hàng đợi.

- **Không bí mật nào còn sót.** Một trường có tên chỉ token, password, secret, signature, cookie, session hoặc khoảng hai mươi từ tương tự chỉ giữ `[secret]`. Một giá trị có dạng thông tin xác thực đã biết cũng vậy, dù nó xuất hiện ở đâu. Điều đó bao gồm bearer token, JWT, khóa riêng tư, URL có mật khẩu và mọi chuỗi mờ đục gồm 40 ký tự khóa trở lên.
- **Văn xuôi hoàn toàn không được giữ.** Một trường tên `html`, `text`, `body`, `markdown` hoặc `content` chỉ giữ `[redacted]`. Văn xuôi chứa tên người và địa chỉ đường phố mà không mẫu nào tìm ra được.
- **Dữ liệu cá nhân bị che vĩnh viễn.** Một trường có tên cho thấy dữ liệu cá nhân, như email, điện thoại, tên, địa chỉ hoặc ghi chú, chỉ giữ `[redacted]`. Địa chỉ email, số điện thoại, số thẻ hoặc IBAN nằm trong bất kỳ chuỗi nào khác đều bị che.
- **Nội dung được giữ nhỏ gọn.** [Chuỗi bị cắt ở 512 ký tự](https://tajo.io/vi/docs/mcp/#mcp-request-log), danh sách ở 20 phần tử, đối tượng ở 50 khóa và độ lồng ở 6 cấp. Toàn bộ nội dung bị [cắt ở 4 KB](https://tajo.io/vi/docs/mcp/#mcp-request-log) và được đánh dấu là đã cắt bớt.

Có hai loại lần gọi giữ ít hơn nữa. Các liên hệ mà cuộc trò chuyện của một người mang vào từ một ứng dụng khác được ghi lại dưới dạng một dấu đánh dấu và một con số đếm, không bao giờ là nội dung. Một lần gọi đọc log không giữ câu trả lời, vì câu trả lời đó chỉ là các dòng log khác.

Giờ đến chi phí. Việc che là vĩnh viễn, không phải mã hóa bằng một khóa mà ai đó nắm giữ. Log không thể cho bạn thấy địa chỉ email đã bị trả về. Nó cho bạn thấy id của liên hệ, và liên hệ đó, theo các quy tắc riêng của nó, chỉ cách một lần gọi. Log nằm ngoài quy trình xóa dữ liệu của workspace, và đó là lý do việc che không thể chờ đến quy trình ấy.

## Vì sao log này không phải là dấu vết kiểm toán

Tajo đã có [một log kiểm toán chỉ cho phép nối thêm](https://tajo.io/vi/docs/mcp/#mcp-request-log). Mỗi dòng mang mã băm của dòng trước nó, nên một chỉnh sửa ở bất kỳ đâu cũng làm đứt chuỗi. Vậy sao không ghi các lần gọi công cụ vào đó?

Vì chuỗi có cái giá của nó. Mỗi lần nối thêm phải lấy một khóa theo workspace và đọc dòng trước để kéo dài chuỗi. Ghi mọi lượt đọc qua đó sẽ khiến các lần gọi của một workspace xếp hàng sau một khóa duy nhất. Nó cũng sẽ vùi các thay đổi trạng thái, thứ mà log kiểm toán tồn tại để cho thấy, dưới hàng nghìn lượt đọc.

Vì vậy hai bản ghi được chia theo câu hỏi. Log yêu cầu cho biết tác nhân đã yêu cầu gì và điều gì đã xảy ra, [trong 30 ngày](https://tajo.io/vi/docs/mcp/#mcp-request-log). Log kiểm toán cho biết điều gì đã thay đổi, ai đã cho phép, và liệu có ai đã chỉnh sửa bản ghi kể từ đó hay không.

Phê duyệt nằm ở phía kiểm toán. Trên các hồ sơ connector của Tajo, [một công cụ propose chuẩn bị một hành động đã khai báo và một công cụ apply chạy nó sau khi được phê duyệt](https://tajo.io/vi/docs/mcp/). Không có gì đến được nhà cung cấp cho đến khi đề xuất được phê duyệt, bởi một người hoặc bởi một quy tắc mà workspace đã bật. Dòng của lần gọi propose ghi tên phê duyệt mà nó tạo ra trong số các bản ghi của nó. Bản thân phê duyệt được gắn với một digest SHA-256 của đầu vào chính xác. [Một phê duyệt chỉ áp dụng cho đúng đầu vào bạn đã thấy](https://tajo.io/vi/docs/mcp/agent-specification/): thay đổi một trường là nó không còn khớp. Khi thao tác ghi được thực hiện, dòng kiểm toán của nó giữ digest đầu vào và một digest của phản hồi từ nhà cung cấp, không bao giờ giữ các giá trị của phản hồi.

## Một dòng tốn bao nhiêu

Một dòng là một thao tác ghi vào cơ sở dữ liệu, và thao tác ghi cần một lần commit. [Cho đến ngày 8 tháng 10 năm 2026](https://tajo.io/vi/docs/mcp/#mcp-request-log), mỗi lần gọi phải chờ commit của chính nó trước khi phản hồi, khoảng 2,6 ms trên máy chủ của chúng tôi. Với một client, con số đó bằng một phần tư thời gian của một lần gọi công cụ nhỏ.

Giờ đây dòng được tạo khi lần gọi kết thúc rồi đưa vào hàng đợi. Một lượt flush ghi hàng đợi [chậm nhất 100 ms sau đó](https://tajo.io/vi/docs/mcp/#mcp-request-log), một giao dịch cho mỗi workspace, nên nhiều lần gọi dùng chung một lần commit. Không có gì trong dòng thay đổi, kể cả dấu thời gian. Nếu [5.000 dòng đang chờ](https://tajo.io/vi/docs/mcp/#mcp-request-log), lần gọi tiếp theo sẽ chờ lượt flush thay vì bỏ một dòng.

Việc ghi lại không bao giờ làm một lần gọi thất bại. Một thao tác ghi thất bại được thử lại từng dòng một, sau đó được ghi log và bị bỏ. Thứ bị mất khi tiến trình bị buộc dừng là những gì còn nằm trong hàng đợi: [tối đa các lần gọi trong 100 ms cuối cùng](https://tajo.io/vi/docs/mcp/#mcp-request-log).

## Đọc lại

[`logs.list`](https://tajo.io/vi/docs/mcp/#mcp-request-log) trả về các lần gọi của workspace, mới nhất trước, không kèm nội dung. Nó lọc theo thời gian, theo kết quả hoặc trạng thái HTTP, theo nguồn (MCP hoặc REST API, vốn dùng chung bảng) và theo khóa API. Mặc định mỗi trang 50 dòng, tối đa 100. `logs.get` trả về một lần gọi kèm tên hiện tại của khóa, trạng thái, thời lượng, yêu cầu và phản hồi đã làm sạch, cùng các bản ghi mà nó đã chạm tới.

Cả hai chỉ đọc workspace của bên gọi. Một id dòng từ workspace khác sẽ không được tìm thấy.

Một lỗi công cụ mang theo id yêu cầu. Khi máy chủ tạo ra id đó, hoặc id đến ở dạng hex hoặc UUID, thì đó là trace id của dòng. Một tác nhân nhận được lỗi có thể trao cho một người đúng một giá trị xác định lần gọi đó.

## Những gì đã xây dựng, và những gì chưa

Đã xây dựng, tại thời điểm viết bài:

- Một dòng cho mỗi `tools/call` trên máy chủ workspace và mọi máy chủ connector, kể cả các lần gọi bị từ chối và không xác định.
- [Id khóa, máy chủ, connector, hồ sơ, công cụ, tác động, kết quả, thời lượng, kích thước kết quả, trace id và tối đa 20 bản ghi đã chạm tới](https://tajo.io/vi/docs/mcp/#mcp-request-log).
- [Đối số và câu trả lời đã làm sạch](https://tajo.io/vi/docs/mcp/#mcp-request-log), tối đa 4 KB mỗi phần.
- [`logs.list` và `logs.get`](https://tajo.io/vi/docs/mcp/#mcp-request-log), giới hạn trong workspace, giữ trong 30 ngày.
- Phê duyệt gắn với digest đầu vào, và các thao tác ghi đã thực hiện được ghi lại cùng digest đầu vào và đầu ra trong log kiểm toán dạng chuỗi băm.

Chưa xây dựng, và đáng biết trước khi bạn dựa vào nó:

- Không có điểm sức khỏe, không có biểu đồ theo công cụ và không có cảnh báo khi tỷ lệ lỗi tăng. Một bản tóm tắt theo công cụ về số lần gọi, lỗi và thời lượng chậm nhất [có sẵn cho đội vận hành của Tajo](https://tajo.io/vi/docs/mcp/#mcp-request-log), không nằm trên bất kỳ giao diện nào bạn có thể mở.
- `logs.list` không thể lọc theo tên công cụ hay theo trace id. Để tìm dòng ứng với một id yêu cầu, hãy thu hẹp theo thời gian và khóa.
- Các dòng không được xuất sang hệ thống tracing mà bạn vận hành. Trace id chỉ được đọc từ header HTTP, không từ trường MCP `_meta` mà bài trình bày dùng để [mang ngữ cảnh trace](https://www.youtube.com/watch?v=Lcqat4iP_lE&t=535s).
- [Sau 30 ngày, một dòng bị xóa](https://tajo.io/vi/docs/mcp/#mcp-request-log). Không có lưu trữ hay xuất dữ liệu.
- Những gì đã bị che không thể khôi phục từ log.
- [Một lần buộc dừng có thể làm mất các dòng của 100 ms cuối cùng](https://tajo.io/vi/docs/mcp/#mcp-request-log).

Bài trình bày khép lại với nhận định rằng khả năng quan sát trong MCP “[không được phân bố đồng đều](https://www.youtube.com/watch?v=Lcqat4iP_lE&t=841s)”. Một bảng điều khiển ở hạ nguồn không thể khắc phục điều đó, một trace dừng lại trước cửa máy chủ cũng vậy. [Một lần đồng bộ thất bại cần bản ghi của riêng nó](https://tajo.io/vi/blog/worker-died-sync-didnt/); mọi lần gọi đã yêu cầu điều gì đó cũng vậy.

Máy chủ đã thấy lần gọi. Không ai khác thấy. Hãy ghi lại nó ở đó.

## Câu hỏi Thường gặp

**Máy chủ MCP nên ghi log những gì cho mỗi lần gọi công cụ?**

Một dòng cho mỗi lần gọi, do máy chủ ghi: khóa API nào đã gọi, máy chủ và connector nào, tên công cụ nếu công cụ đó tồn tại, lớp tác động của nó, ok hoặc một mã lỗi ngắn, thời lượng, kích thước kết quả, trace id của yêu cầu, id của các bản ghi mà lần gọi nêu tên hoặc tạo ra, cùng các đối số và câu trả lời đã được loại bỏ bí mật và dữ liệu cá nhân. Các máy chủ MCP của Tajo ghi dòng đó cho mọi tools/call, kể cả các lần gọi bị từ chối, và giữ trong 30 ngày.

**Log yêu cầu MCP có nên giữ đối số của công cụ không?**

Có, sau khi đã làm sạch. Một log không có đối số không thể cho biết vì sao lần gọi thất bại. Tajo không giữ phần nội dung nào cho đến ngày 18 tháng 10 năm 2026, và giờ giữ cả hai sau một lượt xử lý tất định: bí mật trở thành \[secret\], văn bản tự do và các trường cá nhân trở thành \[redacted\], email, số điện thoại, số thẻ và IBAN bị che, và mỗi phần nội dung bị cắt ở 4 KB. Việc che là vĩnh viễn, vì vậy log trỏ đến bản ghi bằng id thay vì sao chép nó.

**Vì sao tách log gọi công cụ MCP khỏi log kiểm toán?**

Vì chúng trả lời những câu hỏi khác nhau với chi phí khác nhau. Log kiểm toán của Tajo là một chuỗi băm các thay đổi trạng thái, và mỗi lần nối thêm phải lấy một khóa theo workspace để kéo dài chuỗi. Ghi mọi lượt đọc qua đó sẽ khiến các lần gọi của một workspace xếp hàng sau khóa ấy và vùi các thay đổi giữa các lượt đọc. Các lần gọi công cụ đi vào một bảng riêng, không có chuỗi, được giữ 30 ngày; các thao tác ghi mà một lần gọi chuẩn bị vẫn để lại các dòng kiểm toán riêng của chúng.

## Bài viết liên quan

### [Máy chủ MCP là gì? MCP và MCP UI hoạt động thế nào năm 2026](https://tajo.io/vi/blog/what-is-an-mcp-server/)

3 thg 10, 2026 · 20 phút đọc

Bước 1 → Bước 6

### [Grok Bot và Brevo: phản hồi khách khi tính năng họ yêu cầu đã sẵn sàng](https://tajo.io/vi/blog/grok-bot-brevo-product-feedback/)

7 thg 10, 2026 · 6 phút đọc

3 phần

### [MCP hay CLI là câu hỏi sai. Hãy hỏi trạng thái nằm ở đâu](https://tajo.io/vi/blog/mcp-or-cli-is-the-wrong-question/)

4 thg 11, 2026 · 10 phút đọc

5 phần
