Skip to main content
Version: 1.1.x

Audit Logs

Audit logs record what your agents do and what changes in MCPX. Each event is saved in a structured form, so you can review activity and configuration history. Logging is on by default. View recent events in the MCPX control plane, or read the JSONL files directly.

MCPX records five event types: tool_used, target_server_added, target_server_removed, agent_permission_updated, and catalog_updated.

Audit Log in the MCPX control plane

Tool usage event (tool_used)

Triggered whenever an agent invokes a tool. Payload fields include:

  • toolName: the name of the tool called
  • targetServerName: the server or service that handled the request
  • args: the input arguments passed to the tool
  • consumerTag: optional tag identifying the consumer or agent
Tool Used Example Log
{"timestamp":"2025-10-28T13:52:46.201Z","createdAt":"2025-10-28T13:52:48.806Z","eventType":"tool_used","payload":{"toolName":"slack_list_channels","targetServerName":"slack","args":{"limit":20},"consumerTag":"Claude"}}

MCP server added (target_server_added)

Recorded when a new MCP server is added to your catalog. Payload fields:

  • name: the server that was added
MCP Server Added Example Log
{
"timestamp": "2025-10-29T10:05:44.132Z",
"createdAt": "2025-10-29T10:05:44.417Z",
"eventType": "target_server_added",
"payload": {
"name": "github"
}
}

MCP server removed (target_server_removed)

Recorded when an MCP server is removed from your catalog. Payload fields:

  • name: the server that was removed
MCP Server Removed Example Log
{
"timestamp": "2025-10-29T10:59:05.063Z",
"createdAt": "2025-10-29T10:59:05.289Z",
"eventType": "target_server_removed",
"payload": {
"name": "slack"
}
}

Agent permission updated (agent_permission_updated)

Recorded when an identity's access changes. MCPX logs only the servers that were added or removed, not the full permission set. Payload fields:

  • name: the identity whose access changed
  • identityType: consumers or clientNames
  • addedServers: servers the identity can now use
  • removedServers: servers the identity can no longer use
Agent Permission Updated Example Log
{
"timestamp": "2025-10-29T10:30:32.516Z",
"createdAt": "2025-10-29T10:30:33.525Z",
"eventType": "agent_permission_updated",
"payload": {
"name": "Claude",
"identityType": "consumers",
"addedServers": ["time"],
"removedServers": []
}
}

Catalog updated (catalog_updated)

Recorded when the catalog changes: servers are added or removed, or the approved tools on a server change. Payload fields:

  • addedServers: servers added to the catalog
  • removedServers: servers removed from the catalog
  • approvedToolsChanges: tool changes per server, each listing the server and which tools were added or removed
Catalog Updated Example Log
{
"timestamp": "2025-10-29T10:30:18.772Z",
"createdAt": "2025-10-29T10:30:23.529Z",
"eventType": "catalog_updated",
"payload": {
"addedServers": ["time"],
"removedServers": [],
"approvedToolsChanges": [
{
"serverName": "slack",
"addedTools": ["slack_post_message", "slack_reply_to_thread"],
"removedTools": []
}
]
}
}

Each entry includes two timestamps:

  • timestamp: when the event happened
  • createdAt: when MCPX saved it to disk

Viewing audit logs in the UI

The MCPX control plane includes an Audit Log page where you can browse recent events without opening the log files.

The page lists recent events in a table with Time, Event, and Details columns. Click any row to see the full event details. Use the filters at the top to show or hide each event type: MCP added, MCP removed, Agent permission updated, Catalog updated, and Tool used. Click Refresh to load the latest events.

The UI shows the most recent events. For long-term storage and use with other tools, the JSONL files in AUDIT_LOG_DIR remain the source of truth.


Configuration

Audit logging is controlled through the following environment variables:

ENABLE_AUDIT_LOG

Type: boolean or string ("true"/"false")
Default: true
Required: Yes
Enables or disables audit logging


AUDIT_LOG_FLUSH_INTERVAL_IN_SEC

Type: seconds
Default: 5
Required: No
Number of seconds to wait before flushing logs to disk


AUDIT_LOG_DIR

Type: path
Default: <cwd>/audit-logs
Required: No
Directory where logs are written. When running MCPX in Docker, the default file path is /lunar/packages/mcpx-server/audit-logs/audit-2025-10-29T10.jsonl. Audited events are automatically grouped by hour and written to separate files, meaning a new log file is generated each hour at the configured path.


AUDIT_LOG_RETENTION_HOURS

Type: num
Default: 336 (14 days)
Required: No
How long to retain log files before cleanup


Best practices

  • Keep ENABLE_AUDIT_LOG=true in production to maintain full visibility.
  • If you need tighter real-time tracking, reduce AUDIT_LOG_FLUSH_INTERVAL_IN_SEC; if you want to reduce disk I/O, increase it.
  • When running in Docker, mount AUDIT_LOG_DIR to a persistent volume so logs survive container restarts.
  • Set retention (AUDIT_LOG_RETENTION_HOURS) according to your compliance and audit policy.
  • Consider shipping the JSONL file to your observability stack (for example : Loki, Splunk, or Elasticsearch) for centralized querying and alerting.

Example

Here is an example of a log file

/lunar/packages/mcpx-server/audit-logs/audit-2025-10-29T10.jsonl
{"timestamp":"2025-10-29T10:05:44.132Z","createdAt":"2025-10-29T10:05:44.417Z","eventType":"config_applied","payload":{"config":{"permissions":{"default":{"_type":"default-allow","block":[]},"consumers":{}},"toolGroups":[{"name":"Version_control_and_issue_management","services":{"github":["get_issue","create_issue","add_issue_comment","list_issues","update_issue","get_pull_request","list_pull_requests","merge_pull_request","get_pull_request_diff","create_pull_request","update_pull_request","delete_file","list_branches","push_files","search_repositories","create_repository","fork_repository","create_branch","run_workflow","get_workflow_run","get_workflow_run_logs","rerun_failed_jobs","rerun_workflow_run","cancel_workflow_run"],"slack":"*"}},{"name":"Browser_automation_and_UI_testing","services":{"duckduckgo":["search"],"playwright":["browser_snapshot","browser_click","browser_drag","browser_hover","browser_type","browser_select_option","browser_wait_for","browser_navigate","browser_tab_list","browser_tab_new","browser_tab_select","browser_press_key"]}},{"name":"Database_and_file_operations","services":{"supabase":["search_docs","list_tables","list_migrations","apply_migration","execute_sql","get_project_url","get_anon_key","generate_typescript_types"]}},{"name":"Code_development_and_refactoring","services":{"memory":["create_entities","create_relations","add_observations"],"serena":["create_text_file","activate_project","delete_memory","execute_shell_command","find_symbol","get_symbols_overview","insert_after_symbol","list_memories","list_dir","prepare_for_new_conversation","read_memory","read_file","search_for_pattern"]}},{"name":"Observability_and_debugging","services":{"grafana":["search_dashboards","query_prometheus","query_loki_logs","list_incidents"]}}],"auth":{"enabled":false},"toolExtensions":{"services":{}}},"version":1,"lastModified":"2025-10-29T10:05:44.132Z"}}
{"timestamp":"2025-10-29T10:30:18.772Z","createdAt":"2025-10-29T10:30:23.529Z","eventType":"config_applied","payload":{"config":{"permissions":{"default":{"_type":"default-allow","block":[]},"consumers":{}},"toolGroups":[{"name":"Version_control_and_issue_management","services":{"github":["get_issue","create_issue","add_issue_comment","list_issues","update_issue","get_pull_request","list_pull_requests","merge_pull_request","get_pull_request_diff","create_pull_request","update_pull_request","delete_file","list_branches","push_files","search_repositories","create_repository","fork_repository","create_branch","run_workflow","get_workflow_run","get_workflow_run_logs","rerun_failed_jobs","rerun_workflow_run","cancel_workflow_run"],"slack":["slack_list_channels","slack_post_message","slack_reply_to_thread","slack_add_reaction","slack_get_channel_history","slack_get_thread_replies","slack_get_users","slack_get_user_profile"]}},{"name":"Browser_automation_and_UI_testing","services":{"duckduckgo":["search"],"playwright":["browser_snapshot","browser_click","browser_drag","browser_hover","browser_type","browser_select_option","browser_wait_for","browser_navigate","browser_tab_list","browser_tab_new","browser_tab_select","browser_press_key"]}},{"name":"Database_and_file_operations","services":{"supabase":["search_docs","list_tables","list_migrations","apply_migration","execute_sql","get_project_url","get_anon_key","generate_typescript_types"]}},{"name":"Code_development_and_refactoring","services":{"memory":["create_entities","create_relations","add_observations"],"serena":["create_text_file","activate_project","delete_memory","execute_shell_command","find_symbol","get_symbols_overview","insert_after_symbol","list_memories","list_dir","prepare_for_new_conversation","read_memory","read_file","search_for_pattern"]}},{"name":"Observability_and_debugging","services":{"grafana":["search_dashboards","query_prometheus","query_loki_logs","list_incidents"]}},{"name":"time","services":{"time":["get_current_time","convert_time"]}}],"auth":{"enabled":false},"toolExtensions":{"services":{}}},"version":2,"lastModified":"2025-10-29T10:30:18.755Z"}}
{"timestamp":"2025-10-29T10:30:32.516Z","createdAt":"2025-10-29T10:30:33.525Z","eventType":"config_applied","payload":{"config":{"permissions":{"default":{"_type":"default-allow","block":[]},"consumers":{"Claude":{"_type":"default-block","consumerGroupKey":"claude-ai (via mcp-remote 0.1.21) Profile","allow":["time"]}}},"toolGroups":[{"name":"Version_control_and_issue_management","services":{"github":["get_issue","create_issue","add_issue_comment","list_issues","update_issue","get_pull_request","list_pull_requests","merge_pull_request","get_pull_request_diff","create_pull_request","update_pull_request","delete_file","list_branches","push_files","search_repositories","create_repository","fork_repository","create_branch","run_workflow","get_workflow_run","get_workflow_run_logs","rerun_failed_jobs","rerun_workflow_run","cancel_workflow_run"],"slack":"*"}},{"name":"Browser_automation_and_UI_testing","services":{"duckduckgo":["search"],"playwright":["browser_snapshot","browser_click","browser_drag","browser_hover","browser_type","browser_select_option","browser_wait_for","browser_navigate","browser_tab_list","browser_tab_new","browser_tab_select","browser_press_key"]}},{"name":"Database_and_file_operations","services":{"supabase":["search_docs","list_tables","list_migrations","apply_migration","execute_sql","get_project_url","get_anon_key","generate_typescript_types"]}},{"name":"Code_development_and_refactoring","services":{"memory":["create_entities","create_relations","add_observations"],"serena":["create_text_file","activate_project","delete_memory","execute_shell_command","find_symbol","get_symbols_overview","insert_after_symbol","list_memories","list_dir","prepare_for_new_conversation","read_memory","read_file","search_for_pattern"]}},{"name":"Observability_and_debugging","services":{"grafana":["search_dashboards","query_prometheus","query_loki_logs","list_incidents"]}},{"name":"time","services":{"time":"*"}}],"auth":{"enabled":false},"toolExtensions":{"services":{}}},"version":3,"lastModified":"2025-10-29T10:30:32.509Z"}}
{"timestamp":"2025-10-29T10:31:33.063Z","createdAt":"2025-10-29T10:31:33.598Z","eventType":"tool_used","payload":{"toolName":"get_current_time","targetServerName":"time","args":{"timezone":"Asia/Tokyo"},"consumerTag":"Claude"}}
{"timestamp":"2025-10-29T10:58:40.710Z","createdAt":"2025-10-29T10:58:45.207Z","eventType":"config_applied","payload":{"config":{"permissions":{"default":{"_type":"default-allow","block":[]},"consumers":{"Claude":{"_type":"default-block","consumerGroupKey":"claude-ai (via mcp-remote 0.1.21) Profile","allow":["time"]}}},"toolGroups":[{"name":"Browser_automation_and_UI_testing","services":{"duckduckgo":["search"],"playwright":["browser_snapshot","browser_click","browser_drag","browser_hover","browser_type","browser_select_option","browser_wait_for","browser_navigate","browser_tab_list","browser_tab_new","browser_tab_select","browser_press_key"]}},{"name":"Database_and_file_operations","services":{"supabase":["search_docs","list_tables","list_migrations","apply_migration","execute_sql","get_project_url","get_anon_key","generate_typescript_types"]}},{"name":"Code_development_and_refactoring","services":{"memory":["create_entities","create_relations","add_observations"],"serena":["create_text_file","activate_project","delete_memory","execute_shell_command","find_symbol","get_symbols_overview","insert_after_symbol","list_memories","list_dir","prepare_for_new_conversation","read_memory","read_file","search_for_pattern"]}},{"name":"Observability_and_debugging","services":{"grafana":["search_dashboards","query_prometheus","query_loki_logs","list_incidents"]}},{"name":"time","services":{"time":["get_current_time","convert_time"]}}],"auth":{"enabled":false},"toolExtensions":{"services":{}}},"version":4,"lastModified":"2025-10-29T10:58:40.698Z"}}
{"timestamp":"2025-10-29T10:59:05.063Z","createdAt":"2025-10-29T10:59:05.289Z","eventType":"config_applied","payload":{"config":{"permissions":{"default":{"_type":"default-allow","block":[]},"consumers":{"Claude":{"_type":"default-block","consumerGroupKey":"claude-ai (via mcp-remote 0.1.21) Profile","allow":["time"]}}},"toolGroups":[{"name":"Database_and_file_operations","services":{"supabase":["search_docs","list_tables","list_migrations","apply_migration","execute_sql","get_project_url","get_anon_key","generate_typescript_types"]}},{"name":"Observability_and_debugging","services":{"grafana":["search_dashboards","query_prometheus","query_loki_logs","list_incidents"]}},{"name":"time","services":{"time":["get_current_time","convert_time"]}}],"auth":{"enabled":false},"toolExtensions":{"services":{}}},"version":5,"lastModified":"2025-10-29T10:59:05.058Z"}}
{"timestamp":"2025-10-29T10:59:29.434Z","createdAt":"2025-10-29T10:59:30.309Z","eventType":"config_applied","payload":{"config":{"permissions":{"default":{"_type":"default-allow","block":[]},"consumers":{"Claude":{"_type":"default-block","consumerGroupKey":"claude-ai (via mcp-remote 0.1.21) Profile","allow":["time"]}}},"toolGroups":[{"name":"Database_and_file_operations","services":{"supabase":["search_docs","list_tables","list_migrations","apply_migration","execute_sql","get_project_url","get_anon_key","generate_typescript_types"]}},{"name":"Observability_and_debugging","services":{"grafana":["search_dashboards","query_prometheus","query_loki_logs","list_incidents"]}},{"name":"time","services":{"time":["get_current_time","convert_time"]}},{"name":"tool_group_name","services":{"duckduckgo":["search"],"github":["add_comment_to_pending_review","add_issue_comment","get_me"],"grafana":["fetch_pyroscope_profile"]}}],"auth":{"enabled":false},"toolExtensions":{"services":{}}},"version":6,"lastModified":"2025-10-29T10:59:29.428Z"}}
{"timestamp":"2025-10-29T10:59:40.881Z","createdAt":"2025-10-29T10:59:45.329Z","eventType":"config_applied","payload":{"config":{"permissions":{"default":{"_type":"default-allow","block":[]},"consumers":{"Claude":{"_type":"default-block","consumerGroupKey":"claude-ai (via mcp-remote 0.1.21) Profile","allow":["time"]}}},"toolGroups":[{"name":"Database_and_file_operations","services":{"supabase":["search_docs","list_tables","list_migrations","apply_migration","execute_sql","get_project_url","get_anon_key","generate_typescript_types"]}},{"name":"Observability_and_debugging","services":{"grafana":["search_dashboards","query_prometheus","query_loki_logs","list_incidents"]}},{"name":"time","services":{"time":["get_current_time","convert_time"]}},{"name":"tool_group_name","services":{"duckduckgo":["search"],"github":["add_comment_to_pending_review","add_issue_comment","get_me"],"grafana":["fetch_pyroscope_profile"]}},{"name":"tool group","services":{"duckduckgo":["search","fetch_content"]}}],"auth":{"enabled":false},"toolExtensions":{"services":{}}},"version":7,"lastModified":"2025-10-29T10:59:40.873Z"}}