build method
Generates the outputs for a given BuildStep.
Implementation
@override
Future<void> build(BuildStep buildStep) async {
final inputId = buildStep.inputId;
final resolver = buildStep.resolver;
if (!await resolver.isLibrary(inputId)) return;
final library = await buildStep.resolver.libraryFor(inputId);
// Single pass: find the first @Server annotation in the library and
// resolve every field we care about. Returns null when the library
// carries no @Server (or deprecated @Mcp typedef).
final config = _extractServerConfig(library);
if (config == null) return;
// Aggregate tools from this library AND all its package-local imports
final tools = await _extractAllTools(
library,
config.toolPrefix,
config.autoClassPrefix,
config.annotationsDefault,
);
if (tools.isEmpty) return; // No tools found anywhere
// Aggregate prompts from this library AND all its package-local imports
final prompts = await _extractAllPrompts(library);
// Conditionally generate MCP server code (gated by generateMcp flag)
if (config.generateMcp) {
// Generate the appropriate server code based on transport type
final generated = config.transport == 'http'
? HttpTemplate.generate(
tools,
config.port,
config.address,
codeMode: config.codeMode,
codeModeTimeout: config.codeModeTimeout,
logErrors: config.logErrors,
prompts: prompts,
corsOrigins: config.corsOrigins,
)
: StdioTemplate.generate(
tools,
codeMode: config.codeMode,
codeModeTimeout: config.codeModeTimeout,
logErrors: config.logErrors,
prompts: prompts,
);
// Write the generated server code
await buildStep.writeAsString(
inputId.changeExtension('.mcp.dart'),
generated,
);
// Optionally generate JSON metadata file
if (config.generateJson) {
final jsonMetadata = _generateJsonMetadata(tools, prompts: prompts);
await buildStep.writeAsString(
inputId.changeExtension('.mcp.json'),
jsonEncode(jsonMetadata),
);
}
}
// Conditionally generate REST/OpenAPI output (gated by generateRest flag)
if (config.generateRest) {
final openApiSpec = OpenApiBuilder.build(
tools,
config.transport,
config.port,
config.address,
);
await buildStep.writeAsString(
inputId.changeExtension('.openapi.json'),
const JsonEncoder.withIndent(' ').convert(openApiSpec),
);
// Generate .openapi.dart REST server
final openApiDartCode = OpenApiDartTemplate.generate(
tools,
config.port,
config.address,
openApiSpec,
logErrors: config.logErrors,
);
await buildStep.writeAsString(
inputId.changeExtension('.openapi.dart'),
openApiDartCode,
);
}
}