Skip to content

Commit 6dc2ac9

Browse files
aksOpsclaude
andcommitted
Fix McpTools FlowEngine dependency: make Optional for H2 fallback
- McpTools constructor accepts Optional<FlowEngine> instead of hard dependency - resolveFlowEngine() creates FlowEngine from H2 cache when no Spring bean - Fixes APPLICATION FAILED TO START when FlowEngine not in Spring context Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 1ef2b1b commit 6dc2ac9

2 files changed

Lines changed: 24 additions & 5 deletions

File tree

src/main/java/io/github/randomcodespace/iq/mcp/McpTools.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.springframework.stereotype.Component;
2222

2323
import java.nio.file.Path;
24+
import java.util.Optional;
2425
import java.util.ArrayList;
2526
import java.util.LinkedHashMap;
2627
import java.util.List;
@@ -46,13 +47,13 @@ public class McpTools {
4647

4748
public McpTools(QueryService queryService, Analyzer analyzer,
4849
CodeIqConfig config, ObjectMapper objectMapper,
49-
FlowEngine flowEngine, GraphDatabaseService graphDb,
50+
Optional<FlowEngine> flowEngine, GraphDatabaseService graphDb,
5051
StatsService statsService, TopologyService topologyService) {
5152
this.queryService = queryService;
5253
this.analyzer = analyzer;
5354
this.config = config;
5455
this.objectMapper = objectMapper;
55-
this.flowEngine = flowEngine;
56+
this.flowEngine = flowEngine.orElse(null);
5657
this.graphDb = graphDb;
5758
this.statsService = statsService;
5859
this.topologyService = topologyService;
@@ -181,8 +182,12 @@ public String generateFlow(
181182
String viewName = view != null ? view : "overview";
182183
String fmt = format != null ? format : "json";
183184
try {
184-
FlowDiagram diagram = flowEngine.generate(viewName);
185-
String rendered = flowEngine.render(diagram, fmt);
185+
FlowEngine engine = resolveFlowEngine();
186+
if (engine == null) {
187+
return toJson(Map.of("error", "No analysis data available. Run 'code-iq analyze' first."));
188+
}
189+
FlowDiagram diagram = engine.generate(viewName);
190+
String rendered = engine.render(diagram, fmt);
186191
return rendered;
187192
} catch (IllegalArgumentException e) {
188193
Map<String, Object> error = new LinkedHashMap<>();
@@ -422,6 +427,20 @@ public String findNode(
422427
}
423428
}
424429

430+
/**
431+
* Resolve FlowEngine: use injected instance if available, otherwise create from H2 cache.
432+
*/
433+
private FlowEngine resolveFlowEngine() {
434+
if (flowEngine != null) return flowEngine;
435+
try {
436+
CacheData data = loadCacheData();
437+
if (data.nodes().isEmpty()) return null;
438+
return FlowEngine.fromCache(data.nodes());
439+
} catch (RuntimeException e) {
440+
return null;
441+
}
442+
}
443+
425444
/**
426445
* Load nodes and edges from the H2 analysis cache.
427446
*/

src/test/java/io/github/randomcodespace/iq/mcp/McpToolsTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ void setUp() {
6363
config = new CodeIqConfig();
6464
config.setRootPath(".");
6565
objectMapper = new ObjectMapper();
66-
mcpTools = new McpTools(queryService, analyzer, config, objectMapper, flowEngine, graphDb, statsService, new io.github.randomcodespace.iq.query.TopologyService());
66+
mcpTools = new McpTools(queryService, analyzer, config, objectMapper, java.util.Optional.ofNullable(flowEngine), graphDb, statsService, new io.github.randomcodespace.iq.query.TopologyService());
6767
}
6868

6969
private Map<String, Object> parseJson(String json) throws IOException {

0 commit comments

Comments
 (0)