🎃 Export the audit log as CSV or JSON from /logs
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 68/100
- Loại issue
- Tính năng
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- typescript
- Lĩnh vực
- backend-api-design, documentation, frontend
Hướng nghiên cứu
Start with the list filters in packages/backend/src/audit/audit.controller.ts and orgScope()/getRecentInvocations() in audit.service.ts; then read the logs page and audit client paths listed in the issue. Run the backend tests with cd packages/backend && npm test and add the specified CSV utility tests. Done means the streamed export honors filters, admin and organization restrictions, row cap and truncation header, with the frontend button and API docs updated.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Part of the October Challenge #846.
Why
The Audit Log page (/logs) only lets you page through tool calls 50 at a time. Admins who need to send a compliance report, look into an incident in a spreadsheet, or attach evidence to a support ticket have nothing to download. Most API gateways and MCP platforms (Kong, Tyk, Apigee, Postman monitors) have a "download logs" button. This issue adds a streamed export that applies the filters the user already has set.
Self-hosted vs Cloud
- Self-hosted: enabled in Community and Business. Not a Business feature: do not touch
ee/. - Cloud (
DEPLOYMENT_MODE=cloud): enabled, behaves the same. Cloud is multi-tenant, so the export must always be scoped to the caller's organization: refuse with 403 whenreq.user.organizationIdis not set, and never fall back to unscoped rows. One tenant can hold millions of rows (see the comment inbound-payload.ts), so the row cap and the throttle are required. - Who can use it:
ADMINonly (@Roles('ADMIN')+RolesGuard). Every role can view the list today, but a bulk download of the whole org's call payloads is a bigger step, so it is limited to admins. Hide the button for other roles. The data is always filtered to the caller's organization.
What to build
- Backend:
GET /api/audit/invocations/export?format=csv|jsoninaudit.controller.ts. It takes the same filters as the list (status,search,connectorId,mcpServerId,toolId) plus optional ISOfrom/tooncreatedAt. - Move the
whereconstruction out ofgetRecentInvocations()into one helper (e.g.buildInvocationWhere(filters)) that both the list and the export call, so the two cannot drift apart. - Stream the response: read in batches (e.g. 1000 rows, keyset pagination on
createdAt/id, newest first) and write each batch tores. Never load everything into memory. Cap atAUDIT_EXPORT_MAX_ROWS(default50000). SendX-Export-Truncated: truewhen the cap was hit (do acountfirst). SetContent-Disposition: attachment; filename="anythingmcp-logs-YYYY-MM-DD.csv". Throttle with@Throttle({ default: { limit: 5, ttl: 60_000 } }). - Columns (only data the page already shows):
createdAt(ISO),status,durationMs,tool,connector,connectorType,mcpServer,userEmail,authMethod,apiKeyName,error. JSON additionally includes theinput/outputexcerpts exactly as stored. Do not exportintent,costMicros,usedProxy, the rawclientInfoblob, internal ids other than the invocation id, or anything else the UI does not show. - CSV safety: RFC 4180 quoting (wrap in quotes, double any
"), and escape formula injection: prefix any cell that starts with=,+,-,@, tab or CR with'. Put this in a small pure function (e.g.packages/backend/src/audit/csv.util.ts) so it can be unit-tested. JSON: either one array or NDJSON. Pick one and document it. - Frontend: an "Export" button (with a CSV/JSON choice) in the page
actionsnext to Refresh. Call it with the current filters,fetchwith the Bearer token, download the result as a Blob (same pattern asconnectors/page.tsx:139-149), and show a notice whenX-Export-Truncatedis set. Add anaudit.exportInvocations()helper inlib/api.ts. The sharedrequest()helper parses JSON, so it can't be used for the file.
Where to look
packages/backend/src/audit/audit.controller.ts:13-38: the list endpoint and its filters.packages/backend/src/audit/audit.service.ts:176-225:orgScope()andgetRecentInvocations().packages/backend/src/audit/bound-payload.ts:16:_amcp_truncatedmarker. Stored payloads are excerpts, so don't try to recover full bodies.packages/backend/src/knowledge-graph/kg.controller.ts:22,52:RolesGuard+@Roles('ADMIN')pattern.packages/backend/src/auth/login.controller.ts:137:@Throttlepattern.packages/backend/src/auth/login.controller.ts:87:@Res()usage with Express.packages/frontend/src/app/logs/page.tsx:116-134(filters),:183-207(theexportButtonvariable is actually Refresh; rename it),:204-208(actions).packages/frontend/src/app/settings/layout.tsx:54:user?.role === 'ADMIN'check.packages/frontend/src/lib/api.ts:735-747:auditclient.
Acceptance criteria
- Export applies every active filter, and only the caller's org rows are ever returned (unit test:
organizationIdis in thewhere; a missing org gives 403). - Non-admins get 403, and the button is hidden for them.
- Results are streamed in batches, the row cap is honored, and the truncation header is set.
-
csv.util.spec.tscovers quoting, newlines inside cells, and=cmd|' /C calc'!A0-style injection. -
audit.service.spec.ts/ a new controller spec covers the shared where-builder (cd packages/backend && npm test). -
docs/api-reference.mdAudit section (line 219) documents the endpoint. Also fix the existing examples at lines 226-236, which usetoolName/from/toparams the list endpoint does not support.
Out of scope
- Scheduled exports, emailing exports, S3/SIEM push.
- Exporting security events or product events.
- Changing what is stored in
tool_invocations, or the retention policy.
Size
M (1–2 days)
How to claim
Comment "I'd like to work on this" and we'll assign you. Rules in #846.
- Ngôn ngữ chính
- TypeScript
- Star
- 856
- Fork
- 82
- Merge trung bình
- 5 giờ 18 phút
- Pull request đã merge (30 ngày)
- 162
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của HelpCode-ai/anythingmcp
-
Docs: document all SMTP_* and other undocumented env vars for self-hostingCó thể đã có người làm @notlakshitha đã nhận 4 ngày trước. Đang mởenhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
HelpCode-ai/anythingmcp#1049 · 3 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
good first issue hacktoberfest
Độ khó 2/5 Nửa ngày Mức phù hợp với người mới 70/100
HelpCode-ai/anythingmcp#996 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
good first issue hacktoberfest
Độ khó 2/5 Nửa ngày Mức phù hợp với người mới 72/100
HelpCode-ai/anythingmcp#995 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement good first issue hacktoberfest help wanted
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
HelpCode-ai/anythingmcp#982 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Upload the new social previewCó thể đã có người làm @helpcodeai đã nhận 4 ngày trước. Đang mở
HelpCode-ai/anythingmcp#1087 · 6 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của HelpCode-ai/anythingmcp
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 90/100
chrisparsons83/flexspotff#215 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
vitest-dev/vitest#11633 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
Maintainer thường phản hồi trong vòng 1 ngày