run method
Runs this command.
The return value is wrapped in a Future if necessary and returned by
CommandRunner.runCommand.
Implementation
@override
Future<bool> run() async {
final rest = argResults!.rest;
if (rest.isEmpty) {
throw StateError('Missing tool name. Usage: apollovm mcp call <tool>');
}
final toolName = _normalizeToolName(rest.first);
if (!_allKnownToolNames.contains(toolName)) {
throw StateError(
'Unknown tool: ${rest.first}. Known: ${_allKnownToolNames.join(', ')}',
);
}
// Workspace/repository tools take a JSON args object and need an adapter.
if (isRepoTool(toolName)) {
final repository = this.repository;
if (repository == null) {
throw StateError(
'The tool $toolName requires a workspace: pass --workspace <dir>.',
);
}
final rawArgs = argResults!['json-args'] as String?;
final args = rawArgs == null
? <String, Object?>{}
: (jsonDecode(rawArgs) as Map).cast<String, Object?>();
final runtime = RepoRuntime(repository);
final result = await runtime.call(toolName, args);
print(_json.convert(result));
if (result['isError'] == true) exitCode = 1;
return result['isError'] != true;
}
final file = argResults!['file'] as String?;
final source = await _resolveSource(argResults!['source'] as String?, file);
final language =
(argResults!['language'] as String?) ??
(file != null
? ApolloVM.parseLanguageFromFilePathExtension(file)
: null);
final args = <String, Object?>{};
if (toolName == translateToolName) {
args['from'] = argResults!['from'] ?? language;
args['to'] = argResults!['to'];
args['source'] = source;
} else if (toolName == lspWorkspaceSymbolsToolName) {
// The CLI wraps the single provided source as a one-file workspace.
args['query'] = argResults!['query'] ?? '';
args['files'] = [
<String, Object?>{
'uri': file ?? 'file:///mcp/source',
'source': source,
'language': ?language,
},
];
} else {
args['language'] = language;
args['source'] = source;
if (toolName == executeToolName) {
if (argResults!['function'] != null) {
args['function'] = argResults!['function'];
}
if (argResults!['class-name'] != null) {
args['className'] = argResults!['class-name'];
}
final rawArgs = argResults!['args'] as String?;
if (rawArgs != null) {
args['args'] = jsonDecode(rawArgs) as List;
}
} else if (lspToolNames.contains(toolName)) {
args['line'] = int.tryParse(argResults!['line'] as String? ?? '') ?? 0;
args['character'] =
int.tryParse(argResults!['character'] as String? ?? '') ?? 0;
}
}
final limits = this.limits;
final result = limits.runsInIsolate(toolName)
? await computeToolIsolated(toolName, args, limits)
: await computeTool(toolName, args, limits);
print(_json.convert(result));
if (result['isError'] == true) exitCode = 1;
return result['isError'] != true;
}