Is your feature request related to a problem? Please describe.
Feast can expose the Python feature server as an MCP server (feature_server.type: mcp, mcp_enabled: true, endpoint /mcp) via fastapi_mcp. Operators and platform teams need a clear audit trail for agent/MCP access: who invoked which tool, what resource was accessed, whether authentication and authorization succeeded or failed, and a correlation ID that links MCP calls to internal REST requests.
Today, MCP integration only logs startup/errors (sdk/python/feast/infra/mcp_servers/mcp_server.py). That is not enough for security and operations use cases:
| Mechanism |
What it does |
Gap for MCP audit |
feature_logging |
Logs served feature values to the offline store |
Not a security audit log; not wired on the Python FastAPI MCP server |
| Uvicorn access logs |
HTTP path/status (off by default) |
No principal, no MCP tool name |
| RBAC logs |
Unstructured permission messages in app logs |
No MCP correlation; often DEBUG-only for allows |
With auth.type: no_auth: MCP tool calls are effectively anonymous — no principal in logs.
With auth.type: oidc / kubernetes: RBAC applies on secured REST routes when the MCP client forwards Authorization (default in fastapi_mcp), but there is still no structured audit stream for MCP tools/call, successful reads, or request correlation. The /mcp transport itself is not audited.
Registry MCP (registry.mcp.enabled: true) has the same gap.
Describe the solution you'd like
Add structured audit logging (JSONL) for the Python MCP feature server, separate from feature_logging:
- Config under
feature_server (e.g. audit_logging.enabled, sink, file_path, require_auth_for_mcp, log_successful_reads).
- Audit events with stable schema:
event_type, UTC timestamp, request_id, principal, source (IP, transport), action (MCP tool / HTTP path), resource, outcome, duration_ms.
- Two emission layers:
- MCP middleware on
/mcp (mcp.tools.call, session events).
- REST + RBAC hooks (
authn.*, authz.decision, http.request) on secured endpoints.
- Header propagation via
FastApiMCP(headers=[...]) so MCP and REST events share request_id (and optionally tool name).
- No sensitive payloads in audit logs (no tokens, entity rows, or feature values).
Optional follow-ups: registry MCP parity, OTEL sink, operator CRD fields.
Example config:
feature_server:
type: mcp
mcp_enabled: true
audit_logging:
enabled: true
sink: stdout
Example event (JSONL):
{
"event_type": "mcp.tools.call",
"timestamp": "2026-05-28T12:00:00.000Z",
"request_id": "…",
"principal": {
"username": "jane.doe@company.com",
"roles": ["feast-reader", "ml-engineer"],
"auth_type": "oidc"
},
"source": { "ip": "10.0.0.1", "transport": "mcp-http" },
"action": { "mcp_tool": "get_online_features", "path": "/get-online-features" },
"resource": { "type": "feature_service", "name": "driver_activity_v1", "actions": ["READ_ONLINE"] },
"outcome": "success",
"duration_ms": 42
}
Is your feature request related to a problem? Please describe.
Feast can expose the Python feature server as an MCP server (
feature_server.type: mcp,mcp_enabled: true, endpoint/mcp) viafastapi_mcp. Operators and platform teams need a clear audit trail for agent/MCP access: who invoked which tool, what resource was accessed, whether authentication and authorization succeeded or failed, and a correlation ID that links MCP calls to internal REST requests.Today, MCP integration only logs startup/errors (
sdk/python/feast/infra/mcp_servers/mcp_server.py). That is not enough for security and operations use cases:feature_loggingWith
auth.type: no_auth: MCP tool calls are effectively anonymous — no principal in logs.With
auth.type: oidc/kubernetes: RBAC applies on secured REST routes when the MCP client forwardsAuthorization(default infastapi_mcp), but there is still no structured audit stream for MCPtools/call, successful reads, or request correlation. The/mcptransport itself is not audited.Registry MCP (
registry.mcp.enabled: true) has the same gap.Describe the solution you'd like
Add structured audit logging (JSONL) for the Python MCP feature server, separate from
feature_logging:feature_server(e.g.audit_logging.enabled,sink,file_path,require_auth_for_mcp,log_successful_reads).event_type, UTCtimestamp,request_id,principal,source(IP, transport),action(MCP tool / HTTP path),resource,outcome,duration_ms./mcp(mcp.tools.call, session events).authn.*,authz.decision,http.request) on secured endpoints.FastApiMCP(headers=[...])so MCP and REST events sharerequest_id(and optionally tool name).Optional follow-ups: registry MCP parity, OTEL sink, operator CRD fields.
Example config:
Example event (JSONL):
{ "event_type": "mcp.tools.call", "timestamp": "2026-05-28T12:00:00.000Z", "request_id": "…", "principal": { "username": "jane.doe@company.com", "roles": ["feast-reader", "ml-engineer"], "auth_type": "oidc" }, "source": { "ip": "10.0.0.1", "transport": "mcp-http" }, "action": { "mcp_tool": "get_online_features", "path": "/get-online-features" }, "resource": { "type": "feature_service", "name": "driver_activity_v1", "actions": ["READ_ONLINE"] }, "outcome": "success", "duration_ms": 42 }