Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@ public final class McpUsageRecorder {
private McpUsageRecorder() {}

/**
* Records a tool invocation with the full Phase 3 payload. The legacy 3-arg overload below is
* kept so existing call sites and tests compile unchanged. New call sites should call this one
* directly with the latency timer reading + error category + client name they already have.
* Records a tool invocation with the full Phase 3 payload.
*
* @param toolName name of the tool that was invoked
* @param userName principal name from the security context
Expand Down Expand Up @@ -90,14 +88,6 @@ public static void record(
}
}

/**
* Backwards-compatible overload. New call sites should use the 6-arg variant so the row gets
* the full Phase 3 payload.
*/
public static void record(String toolName, String userName, boolean success) {
record(toolName, userName, success, null, null, null);
}

private static App resolveMcpApp() {
AbstractNativeApplication app =
ApplicationContext.getInstance().getAppIfExists(McpAppConstants.MCP_APP_NAME);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void recordWritesUsageRowWhenAppRegistered() {
stubMcpApp(appId, McpAppConstants.MCP_APP_NAME);

long before = System.currentTimeMillis();
McpUsageRecorder.record("search_metadata", "alice", true);
McpUsageRecorder.record("search_metadata", "alice", true, null, null, null);
long after = System.currentTimeMillis();

ArgumentCaptor<String> json = ArgumentCaptor.forClass(String.class);
Expand Down Expand Up @@ -102,7 +102,7 @@ void recordWritesUsageRowWhenAppRegistered() {
void serializedJsonContainsGeneratedColumnFieldNames() {
stubMcpApp(UUID.randomUUID(), McpAppConstants.MCP_APP_NAME);

McpUsageRecorder.record("any_tool", "alice", true);
McpUsageRecorder.record("any_tool", "alice", true, null, null, null);

ArgumentCaptor<String> json = ArgumentCaptor.forClass(String.class);
verify(dao).insert(json.capture(), eq("limits"));
Expand All @@ -117,7 +117,7 @@ void serializedJsonContainsGeneratedColumnFieldNames() {
void recordSkipsWhenMcpApplicationNotInitialized() {
when(appContext.getAppIfExists(McpAppConstants.MCP_APP_NAME)).thenReturn(null);

McpUsageRecorder.record("any_tool", "alice", true);
McpUsageRecorder.record("any_tool", "alice", true, null, null, null);

verify(dao, never()).insert(anyString(), anyString());
}
Expand All @@ -127,7 +127,7 @@ void recordSwallowsDaoException() {
stubMcpApp(UUID.randomUUID(), McpAppConstants.MCP_APP_NAME);
doThrow(new RuntimeException("db down")).when(dao).insert(anyString(), eq("limits"));

McpUsageRecorder.record("create_entity", "alice", false);
McpUsageRecorder.record("create_entity", "alice", false, null, null, null);

verify(dao, times(1)).insert(anyString(), eq("limits"));
}
Expand All @@ -136,7 +136,7 @@ void recordSwallowsDaoException() {
void recordCapturesFailureFlag() {
stubMcpApp(UUID.randomUUID(), McpAppConstants.MCP_APP_NAME);

McpUsageRecorder.record("patch_entity", "bob", false);
McpUsageRecorder.record("patch_entity", "bob", false, null, null, null);

ArgumentCaptor<String> json = ArgumentCaptor.forClass(String.class);
verify(dao).insert(json.capture(), eq("limits"));
Expand All @@ -159,20 +159,6 @@ void recordCapturesPhase3Metadata() {
assertThat(decoded.getClientName()).isEqualTo("Claude Desktop");
}

@Test
void legacy3ArgOverloadOmitsPhase3Fields() {
stubMcpApp(UUID.randomUUID(), McpAppConstants.MCP_APP_NAME);

McpUsageRecorder.record("search_metadata", "alice", true);

ArgumentCaptor<String> json = ArgumentCaptor.forClass(String.class);
verify(dao).insert(json.capture(), eq("limits"));
McpToolCallUsage decoded = JsonUtils.readValue(json.getValue(), McpToolCallUsage.class);
assertThat(decoded.getLatencyMs()).isNull();
assertThat(decoded.getErrorCategory()).isNull();
assertThat(decoded.getClientName()).isNull();
}

private void stubMcpApp(UUID appId, String appName) {
AbstractNativeApplication nativeApp = mock(AbstractNativeApplication.class);
App app = new App().withId(appId).withName(appName);
Expand Down
Loading