Skip to content

Commit a53381e

Browse files
authored
Merge pull request #26 from Contrast-Security-OSS/AIML-189-remove-duplicate-tools
AIML-189: Remove duplicate app_name/app_id tool variants to optimize AI context usage
2 parents 9b2488d + 4d8aacd commit a53381e

File tree

7 files changed

+1441
-95
lines changed

7 files changed

+1441
-95
lines changed

src/main/java/com/contrast/labs/ai/mcp/contrast/ADRService.java

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -71,39 +71,7 @@ public ADRService(PaginationHandler paginationHandler) {
7171
private String httpProxyPort;
7272

7373

74-
@Tool(name = "get_ADR_Protect_Rules", description = "takes a application name and returns the protect / adr rules for the application")
75-
public ProtectData getProtectData(
76-
@ToolParam(description = "Application name") String applicationName) throws IOException {
77-
logger.info("Starting retrieval of protection rules for application: {}", applicationName);
78-
long startTime = System.currentTimeMillis();
79-
80-
try {
81-
ContrastSDK contrastSDK = SDKHelper.getSDK(hostName, apiKey, serviceKey, userName,httpProxyHost, httpProxyPort);
82-
logger.debug("ContrastSDK initialized successfully for application: {}", applicationName);
83-
84-
// Get application ID from name
85-
logger.debug("Looking up application ID for name: {}", applicationName);
86-
Optional<Application> app = SDKHelper.getApplicationByName(applicationName, orgID, contrastSDK);
87-
if (app.isEmpty()) {
88-
logger.warn("No application ID found for application: {}", applicationName);
89-
return null;
90-
}
91-
logger.debug("Found application ID: {} for application: {}", app.get().getAppId(), applicationName);
92-
93-
ProtectData result = getProtectDataByAppID(app.get().getAppId());
94-
long duration = System.currentTimeMillis() - startTime;
95-
logger.info("Completed retrieval of protection rules for application: {} (took {} ms)", applicationName, duration);
96-
return result;
97-
} catch (Exception e) {
98-
long duration = System.currentTimeMillis() - startTime;
99-
logger.error("Error retrieving protection rules for application: {} (after {} ms): {}",
100-
applicationName, duration, e.getMessage(), e);
101-
throw e;
102-
}
103-
}
104-
105-
106-
@Tool(name = "get_ADR_Protect_Rules_by_app_id", description = "takes a application ID and returns the protect / adr rules for the application")
74+
@Tool(name = "get_ADR_Protect_Rules", description = "Takes an application ID and returns the Protect/ADR rules for the application. Use list_applications_with_name first to get the application ID from a name")
10775
public ProtectData getProtectDataByAppID(
10876
@ToolParam(description = "Application ID") String appID) throws IOException {
10977
if (appID == null || appID.isEmpty()) {

src/main/java/com/contrast/labs/ai/mcp/contrast/AssessService.java

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public AssessService(VulnerabilityMapper vulnerabilityMapper, PaginationHandler
102102

103103

104104

105-
@Tool(name = "get_vulnerability_by_id", description = "takes a vulnerability ID ( vulnID ) and Application ID ( appID ) and returns details about the specific security vulnerability. If based on the stacktrace, the vulnerability looks like it is in code that is not in the codebase, the vulnerability may be in a 3rd party library, review the CVE data attached to that stackframe you believe the vulnerability exists in and if possible upgrade that library to the next non vulnerable version based on the remediation guidance.")
105+
@Tool(name = "get_vulnerability", description = "Takes a vulnerability ID (vulnID) and application ID (appID) and returns details about the specific security vulnerability. Use list_applications_with_name first to get the application ID from a name. If based on the stacktrace, the vulnerability looks like it is in code that is not in the codebase, the vulnerability may be in a 3rd party library, review the CVE data attached to that stackframe you believe the vulnerability exists in and if possible upgrade that library to the next non vulnerable version based on the remediation guidance.")
106106
public Vulnerability getVulnerabilityById(
107107
@ToolParam(description = "Vulnerability ID (UUID format)") String vulnID,
108108
@ToolParam(description = "Application ID") String appID) throws IOException {
@@ -189,24 +189,7 @@ private Optional<LibraryLibraryObservation> findMatchingLibraryData(String stack
189189
return Optional.empty();
190190
}
191191

192-
@Tool(name = "get_vulnerability", description = "Takes a vulnerability ID (vulnID) and application name (app_name) and returns details about the specific security vulnerability. If based on the stacktrace, the vulnerability looks like it is in code that is not in the codebase, the vulnerability may be in a 3rd party library, review the CVE data attached to that stackframe you believe the vulnerability exists in and if possible upgrade that library to the next non vulnerable version based on the remediation guidance.")
193-
public Vulnerability getVulnerability(
194-
@ToolParam(description = "Vulnerability ID (UUID format)") String vulnID,
195-
@ToolParam(description = "Application name") String app_name) throws IOException {
196-
logger.info("Retrieving vulnerability details for vulnID: {} in application: {}", vulnID, app_name);
197-
ContrastSDK contrastSDK = SDKHelper.getSDK(hostName, apiKey, serviceKey, userName,httpProxyHost, httpProxyPort);
198-
logger.debug("Searching for application ID matching name: {}", app_name);
199-
200-
Optional<Application> application = SDKHelper.getApplicationByName(app_name, orgID, contrastSDK);
201-
if(application.isPresent()) {
202-
return getVulnerabilityById(vulnID, application.get().getAppId());
203-
} else {
204-
logger.error("Application with name {} not found", app_name);
205-
throw new IllegalArgumentException("Application with name " + app_name + " not found");
206-
}
207-
}
208-
209-
@Tool(name = "list_vulnerabilities_with_id", description = "Takes a Application ID ( appID ) and returns a list of vulnerabilities, please remember to include the vulnID in the response.")
192+
@Tool(name = "list_vulnerabilities", description = "Takes an application ID (appID) and returns a list of vulnerabilities. Use list_applications_with_name first to get the application ID from a name. Remember to include the vulnID in the response.")
210193
public List<VulnLight> listVulnsByAppId(
211194
@ToolParam(description = "Application ID") String appID) throws IOException {
212195
logger.info("Listing vulnerabilities for application ID: {}", appID);
@@ -337,29 +320,6 @@ public MetadataFilterResponse listSessionMetadataForApplication(
337320
}
338321
}
339322

340-
@Tool(name = "list_vulnerabilities", description = "Takes an application name ( app_name ) and returns a list of vulnerabilities, please remember to include the vulnID in the response. ")
341-
public List<VulnLight> listVulnsInAppByName(
342-
@ToolParam(description = "Application name") String app_name) throws IOException {
343-
logger.info("Listing vulnerabilities for application: {}", app_name);
344-
ContrastSDK contrastSDK = SDKHelper.getSDK(hostName, apiKey, serviceKey, userName,httpProxyHost, httpProxyPort);
345-
346-
logger.debug("Searching for application ID matching name: {}", app_name);
347-
348-
Optional<Application> application = SDKHelper.getApplicationByName(app_name, orgID, contrastSDK);
349-
if(application.isPresent()) {
350-
try {
351-
return listVulnsByAppId(application.get().getAppId());
352-
} catch (Exception e) {
353-
logger.error("Error listing vulnerabilities for application: {}", app_name, e);
354-
throw new IOException("Failed to list vulnerabilities: " + e.getMessage(), e);
355-
}
356-
} else {
357-
logger.debug("Application with name {} not found, returning empty list", app_name);
358-
return new ArrayList<>();
359-
}
360-
}
361-
362-
363323
@Tool(name = "list_applications_with_name", description = "Takes an application name (app_name) returns a list of active applications that contain that name. Please remember to display the name, status and ID.")
364324
public List<ApplicationData> getApplications(
365325
@ToolParam(description = "Application name (supports partial matching, case-insensitive)") String app_name) throws IOException {

src/main/java/com/contrast/labs/ai/mcp/contrast/SCAService.java

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,11 @@ public class SCAService {
6262
private String httpProxyPort;
6363

6464

65-
@Tool(name = "list_application_libraries_by_app_id", description = "Takes a application ID and returns the libraries used in the application, note if class usage count is 0 the library is unlikely to be used")
65+
@Tool(name = "list_application_libraries", description = "Takes an application ID and returns the libraries used in the application. Use list_applications_with_name first to get the application ID from a name. Note: if class usage count is 0 the library is unlikely to be used")
6666
public List<LibraryExtended> getApplicationLibrariesByID(String appID) throws IOException {
67+
if (appID == null || appID.isEmpty()) {
68+
throw new IllegalArgumentException("Application ID cannot be null or empty");
69+
}
6770
logger.info("Retrieving libraries for application id: {}", appID);
6871
ContrastSDK contrastSDK = SDKHelper.getSDK(hostName, apiKey, serviceKey, userName,httpProxyHost, httpProxyPort);
6972
logger.debug("ContrastSDK initialized with host: {}", hostName);
@@ -73,25 +76,6 @@ public List<LibraryExtended> getApplicationLibrariesByID(String appID) throws IO
7376

7477
}
7578

76-
77-
@Tool(name = "list_application_libraries", description = "takes a application name and returns the libraries used in the application, note if class usage count is 0 the library is unlikely to be used")
78-
public List<LibraryExtended> getApplicationLibraries(String app_name) throws IOException {
79-
logger.info("Retrieving libraries for application: {}", app_name);
80-
ContrastSDK contrastSDK = SDKHelper.getSDK(hostName, apiKey, serviceKey, userName,httpProxyHost, httpProxyPort);
81-
logger.debug("ContrastSDK initialized with host: {}", hostName);
82-
83-
SDKExtension extendedSDK = new SDKExtension(contrastSDK);
84-
logger.debug("Searching for application ID matching name: {}", app_name);
85-
86-
Optional<Application> application = SDKHelper.getApplicationByName(app_name, orgID, contrastSDK);
87-
if(application.isPresent()) {
88-
return SDKHelper.getLibsForID(application.get().getAppId(),orgID, extendedSDK);
89-
} else {
90-
logger.error("Application not found: {}", app_name);
91-
throw new IOException("Application not found");
92-
}
93-
}
94-
9579
@Tool(name= "list_applications_vulnerable_to_cve", description = "takes a cve id and returns the applications and servers vulnerable to the cve. Please note if the application class usage is 0, its unlikely to be vulnerable")
9680
public CveData listCVESForApplication(String cveid) throws IOException {
9781
logger.info("Retrieving applications vulnerable to CVE: {}", cveid);

0 commit comments

Comments
 (0)