Skip to content

Conversation

@aaronsteers
Copy link
Contributor

@aaronsteers aaronsteers commented Nov 19, 2025

Summary

This PR adds three new build strategy submodules to the connector-builder-mcp server, expanding support beyond the existing declarative YAML strategy:

  1. OpenAPI/Sonar (openapi_sonar_v1): For building connectors from OpenAPI 3.0 specifications using Sonar's connector-sdk
  2. Kotlin Source (kotlin_source_v1): For building Kotlin-based source connectors
  3. Kotlin Destination (kotlin_destination_v1): For building Kotlin-based destination connectors

Each strategy follows the established BuildStrategy pattern and includes:

  • Comprehensive checklist YAML with phased development workflow
  • Guidance tools with detailed documentation and code examples
  • Validation tools (manifest_checks) for static analysis
  • Testing tools (manifest_tests) for runtime verification
  • Prompt templates for guided workflows

The server.py has been updated to register all 4 strategies (including the existing DeclarativeYamlV1Strategy) with availability checking.

⚠️ KNOWN ISSUE: There is a Python syntax error in connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py at line 186 that needs to be fixed before this PR can be merged. The error appears to be related to the markdown documentation structure but the root cause is unclear.

Review & Testing Checklist for Human

Risk Level: 🔴 RED - Contains known syntax error that breaks the build

  • CRITICAL: Fix syntax error in kotlin_destination_v1/guidance.py - The file has a Python syntax error at line 186. The dictionary structure appears correct but Python reports "Perhaps you forgot a comma?". This needs to be debugged and fixed before merge.

  • Verify server starts correctly - Run poe server or poe mcp-serve-local to ensure the server starts and all 4 strategies register without errors. Check stderr output for the strategy registration messages.

  • Review placeholder implementations - The validation and testing tools in all 3 new strategies are placeholder implementations that return success but don't actually validate or test anything. Confirm this is acceptable for initial release or if real implementations are needed.

  • Test checklist YAML loading - Verify that all 3 new checklist.yaml files load correctly using the get_connector_builder_checklist() tool with each strategy.

  • Review documentation accuracy - The guidance.py files contain extensive Kotlin code examples and OpenAPI documentation. Review for technical accuracy, especially the Kotlin code snippets which use $ for string interpolation.

Recommended Test Plan

  1. Fix the syntax error in kotlin_destination_v1/guidance.py
  2. Run poe format && poe lint-fix to ensure code quality
  3. Run poe test to verify existing tests still pass
  4. Start the MCP server and verify all 4 strategies register
  5. Test calling get_connector_builder_docs() for each new strategy to ensure documentation loads
  6. Test calling get_connector_builder_checklist() to ensure checklists load correctly

Notes

  • Requested by: AJ Steers (@aaronsteers) via Slack (#ask-devin-ai)
  • Devin Session: https://app.devin.ai/sessions/826b137fdef54a378ff8f6ed4534ec6f
  • Architecture: Follows the BuildStrategy pattern established in commit 7ac498d
  • Placeholder Tools: All validation and testing tools are placeholders that need real implementations in future PRs
  • Documentation: Each strategy includes 5-6 detailed documentation topics with code examples
  • Checklists: Comprehensive phased workflows with 📝 markers for user-facing outputs

The syntax error needs to be resolved before this can be merged. Once fixed, the PR adds significant new functionality to support multiple connector development workflows.

Summary by CodeRabbit

Release Notes

  • New Features
    • Added support for declarative OpenAPI v3 connector building with spec validation, guidance, and testing tools.
    • Added support for Kotlin destination connector development with project validation and write operation testing.
    • Added support for Kotlin source connector development with project validation and stream testing.
    • Server now supports multiple concurrent build strategies with intelligent availability detection.
    • Added comprehensive guidance documentation for all supported connector types.

✏️ Tip: You can customize this high-level summary in your review settings.

…ce, Kotlin Destination)

- Add OpenAPI/Sonar build strategy (openapi_sonar_v1) for building connectors from OpenAPI specifications
- Add Kotlin Source build strategy (kotlin_source_v1) for Kotlin-based source connectors
- Add Kotlin Destination build strategy (kotlin_destination_v1) for Kotlin-based destination connectors
- Update server.py to register all 4 build strategies (including existing DeclarativeYamlV1)
- Each strategy includes: checklist.yaml, guidance tools, validation tools, test tools, and prompts

Note: kotlin_destination_v1/guidance.py has a syntax error that will be fixed in follow-up commit
Co-Authored-By: AJ Steers <[email protected]>
@devin-ai-integration
Copy link
Contributor

Original prompt from AJ Steers
Received message in Slack channel #ask-devin-ai:

@Devin - Update the connector builder MCP with 3 new build strategy submodules:
1. OpenAPI Interfaces (Sonar)
2. Kotlin Source Connectors
3. Kotlin Destination Connectors
Each new connector type will have its own checklist yaml file, prompts, and specialized tools.
Thread URL: https://airbytehq-team.slack.com/archives/C08BHPUMEPJ/p1763589676785049

@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@github-actions github-actions bot added the enhancement New feature or request label Nov 19, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 19, 2025

📝 Walkthrough

Walkthrough

This PR adds support for three new build strategies (Declarative OpenAPI v3, Kotlin Destination, and Kotlin Source) to the MCP server. The server.py is refactored to use a collection-driven approach that iterates over available strategies, registers their tools, and logs unavailable ones, replacing the prior single-strategy registration model.

Changes

Cohort / File(s) Summary
Server Core
connector_builder_mcp/server.py
Modified to import multiple strategies, iterate over a list of strategy classes, check availability, conditionally register tools, and update startup messaging to reflect multi-strategy support.
Declarative OpenAPI v3 Strategy
connector_builder_mcp/build_strategies/declarative_openapi_v3/__init__.py, build_strategy.py, checklist.yaml, guidance.py, manifest_checks.py, manifest_tests.py, prompts.py
Introduces DeclarativeOpenApiV3Strategy with metadata (name="declarative_openapi_v3", version="3.0", is_default=False), availability check, and delegated registration methods. Includes guidance documentation lookup, basic OpenAPI spec validation, resource testing scaffolding, and a structured prompt for building OpenAPI connectors. Provides task checklist for guided workflow.
Kotlin Destination Strategy
connector_builder_mcp/build_strategies/kotlin_destination/__init__.py, build_strategy.py, checklist.yaml, guidance.py, manifest_checks.py, manifest_tests.py, prompts.py
Introduces KotlinDestinationStrategy with Java 21 detection via subprocess (5s timeout), delegated tool registration, and strategy metadata. Includes topic-scoped guidance docs, destination validation, write operation testing, and structured prompts for Kotlin destination scaffolding. Provides task checklist for guided workflow.
Kotlin Source Strategy
connector_builder_mcp/build_strategies/kotlin_source/__init__.py, build_strategy.py, checklist.yaml, guidance.py, manifest_checks.py, manifest_tests.py, prompts.py
Introduces KotlinSourceStrategy with Java 21 detection, delegated tool registration, and strategy metadata. Includes topic-scoped guidance docs, source connector validation, stream testing, and structured prompts for Kotlin source implementation. Provides task checklist for guided workflow.

Sequence Diagram

sequenceDiagram
    participant Server as Server.py
    participant StrategyMgr as Strategy Manager
    participant Strategy as BuildStrategy
    participant ToolRegistry as Tool Registries

    rect rgb(220, 240, 250)
    note over Server,ToolRegistry: Old Flow (Single Strategy)
    Server->>Strategy: register_*_tools(app)
    Strategy->>ToolRegistry: register tools
    end

    rect rgb(240, 255, 240)
    note over Server,ToolRegistry: New Flow (Multi-Strategy)
    Server->>StrategyMgr: iterate [DeclarativeOpenApiV3,<br/>KotlinDestination, KotlinSource]
    loop for each strategy
        StrategyMgr->>Strategy: is_available()
        alt available
            StrategyMgr->>Strategy: register_guidance_tools(app)
            StrategyMgr->>Strategy: register_manifest_check_tools(app)
            StrategyMgr->>Strategy: register_manifest_test_tools(app)
            StrategyMgr->>Strategy: register_prompts(app)
            Strategy->>ToolRegistry: register tools (domain-specific)
            StrategyMgr->>Server: log: strategy registered
        else unavailable
            StrategyMgr->>Server: log: strategy skipped (unavailable)
        end
    end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

  • Areas requiring extra attention:
    • Java 21 detection logic in both kotlin_destination/build_strategy.py and kotlin_source/build_strategy.py — validates subprocess error handling and timeout behavior
    • Server.py strategy iteration and registration logic — ensure no strategies are silently dropped and logging is informative
    • Placeholder implementations in manifest_checks and manifest_tests modules (e.g., validate_openapi_spec, test_openapi_resource) — verify completeness and error handling; some include basic scaffolding that may need expansion
    • Consistency of guidance documentation, field descriptions, and prompt structure across three similar strategies
    • Checklist YAML structure and task progression for each strategy (similar content, should be validated for coherence)

Possibly related PRs

Suggested reviewers

  • pnilan
  • dbgold17
  • pedroslopez
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch devin/1763589811-add-build-strategy-submodules

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

👋 Welcome to the Airbyte Connector Builder MCP!

Thank you for your contribution! Here are some helpful tips and reminders for your convenience.

Testing This Branch via MCP

To test the changes in this specific branch with an MCP client like Claude Desktop, use the following configuration:

{
  "mcpServers": {
    "connector-builder-mcp-dev": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/airbytehq/connector-builder-mcp.git@devin/1763589811-add-build-strategy-submodules", "connector-builder-mcp"]
    }
  }
}

Testing This Branch via CLI

You can test this version of the MCP Server using the following CLI snippet:

# Run the CLI from this branch:
uvx 'git+https://github.com/airbytehq/connector-builder-mcp.git@devin/1763589811-add-build-strategy-submodules#egg=airbyte-connector-builder-mcp' --help

PR Slash Commands

Airbyte Maintainers can execute the following slash commands on your PR:

  • /autofix - Fixes most formatting and linting issues
  • /build-connector - Builds the default connector on-demand using the AI builder
  • /build-connector prompt="<your prompt>" - Builds a connector on-demand using the AI builder
  • /poe <command> - Runs any poe command in the uv virtual environment

AI Builder Evaluations

AI builder evaluations run automatically under the following conditions:

  • When a PR is marked as "ready for review"
  • When a PR is reopened

A set of standardized evaluations also run on a schedule (Mon/Wed/Fri at midnight UTC) and can be manually triggered via workflow dispatch.

Helpful Resources

If you have any questions, feel free to ask in the PR comments or join our Slack community.

📝 Edit this welcome message.

@github-actions
Copy link

github-actions bot commented Nov 19, 2025

PyTest Results (Fast)

0 tests  ±0   0 ✅ ±0   0s ⏱️ ±0s
0 suites ±0   0 💤 ±0 
0 files   ±0   0 ❌ ±0 

Results for commit 7688d5b. ± Comparison against base commit 7ac498d.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Nov 19, 2025

PyTest Results (Full)

0 tests  ±0   0 ✅ ±0   0s ⏱️ ±0s
0 suites ±0   0 💤 ±0 
0 files   ±0   0 ❌ ±0 

Results for commit 7688d5b. ± Comparison against base commit 7ac498d.

♻️ This comment has been updated with latest results.

…conflict with Kotlin raw string literals

Co-Authored-By: AJ Steers <[email protected]>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (8)
connector_builder_mcp/build_strategies/openapi_sonar_v1/manifest_checks.py (1)

19-26: Optional: make list fields explicit future-proof defaults

errors, warnings, and resources_found are always set explicitly in your function, so the =[] defaults on the model aren’t harmful. If you later construct OpenApiValidationResult without passing these fields, consider switching to Field(default_factory=list) for each to align with common Pydantic patterns around mutable defaults.

connector_builder_mcp/build_strategies/kotlin_source_v1/manifest_checks.py (1)

19-26: Optional: use Field(default_factory=list) for list fields

As with the OpenAPI result model, you may eventually want to construct KotlinSourceValidationResult without explicitly passing errors, warnings, or streams_found. Using Field(default_factory=list) for these fields would follow common Pydantic patterns for list defaults.

connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py (1)

431-435: Add return type annotation for consistency.

The function is missing a return type annotation. Other similar functions in the codebase include -> None.

 def register_guidance_tools(
     app: FastMCP,
-):
+) -> None:
     """Register guidance tools in the MCP server."""
     register_mcp_tools(app, domain=ToolDomain.GUIDANCE)
connector_builder_mcp/build_strategies/openapi_sonar_v1/guidance.py (1)

201-205: Add return type annotation for consistency.

The function is missing a return type annotation.

 def register_guidance_tools(
     app: FastMCP,
-):
+) -> None:
     """Register guidance tools in the MCP server."""
     register_mcp_tools(app, domain=ToolDomain.GUIDANCE)
connector_builder_mcp/build_strategies/kotlin_destination_v1/manifest_checks.py (1)

19-25: Avoid mutable list defaults on Pydantic model fields

errors, warnings, and streams_found use =[] as defaults. Even with Pydantic, it’s safer/clearer to use default_factory so instances don’t share list objects.

 class KotlinDestinationValidationResult(BaseModel):
     """Result of Kotlin destination connector validation."""
 
     is_valid: bool
-    errors: list[str] = []
-    warnings: list[str] = []
-    streams_found: list[str] = []
+    errors: list[str] = Field(default_factory=list)
+    warnings: list[str] = Field(default_factory=list)
+    streams_found: list[str] = Field(default_factory=list)
connector_builder_mcp/build_strategies/kotlin_source_v1/manifest_tests.py (1)

19-27: Use default_factory for errors list on result model

errors is defined with a mutable default =[], which is better expressed via Field(default_factory=list) to avoid shared list instances.

 class KotlinStreamTestResult(BaseModel):
     """Result of Kotlin stream testing operation."""
 
     success: bool
     message: str
     records_read: int = 0
-    errors: list[str] = []
+    errors: list[str] = Field(default_factory=list)
     records: list[dict[str, Any]] | None = Field(
         default=None, description="Actual record data from the stream"
     )
connector_builder_mcp/build_strategies/openapi_sonar_v1/manifest_tests.py (2)

52-55: Unused parameter: max_records.

The max_records parameter is defined but never used in the function body, even in the placeholder implementation. While this is expected given the placeholder status, consider acknowledging it in the success message or adding a TODO comment.

Optional improvement:

     return ResourceTestResult(
         success=True,
-        message=f"Successfully tested resource '{resource_name}' (placeholder implementation)",
+        message=f"Successfully tested resource '{resource_name}' (placeholder implementation - max_records={max_records} not yet implemented)",
         records_read=0,
         errors=[],
         records=[],
     )

85-91: Placeholder implementation needs future work.

The function currently returns a hardcoded success result without actually testing the OpenAPI resource. This is acknowledged in the PR description as placeholder implementation.

Consider adding a TODO comment or tracking issue to implement the actual testing logic:

+    # TODO: Implement actual OpenAPI resource testing
+    # - Parse and validate OpenAPI spec
+    # - Initialize connector with config
+    # - Execute resource read with max_records limit
+    # - Collect and return actual records
     return ResourceTestResult(
         success=True,
         message=f"Successfully tested resource '{resource_name}' (placeholder implementation)",
         records_read=0,
         errors=[],
         records=[],
     )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7ac498d and 0a32fbc.

📒 Files selected for processing (22)
  • connector_builder_mcp/build_strategies/kotlin_destination_v1/__init__.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_destination_v1/checklist.yaml (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_destination_v1/manifest_checks.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_destination_v1/manifest_tests.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_destination_v1/prompts.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_source_v1/__init__.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_source_v1/checklist.yaml (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_source_v1/guidance.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_source_v1/manifest_checks.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_source_v1/manifest_tests.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_source_v1/prompts.py (1 hunks)
  • connector_builder_mcp/build_strategies/openapi_sonar_v1/__init__.py (1 hunks)
  • connector_builder_mcp/build_strategies/openapi_sonar_v1/build_strategy.py (1 hunks)
  • connector_builder_mcp/build_strategies/openapi_sonar_v1/checklist.yaml (1 hunks)
  • connector_builder_mcp/build_strategies/openapi_sonar_v1/guidance.py (1 hunks)
  • connector_builder_mcp/build_strategies/openapi_sonar_v1/manifest_checks.py (1 hunks)
  • connector_builder_mcp/build_strategies/openapi_sonar_v1/manifest_tests.py (1 hunks)
  • connector_builder_mcp/build_strategies/openapi_sonar_v1/prompts.py (1 hunks)
  • connector_builder_mcp/server.py (4 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: aaronsteers
Repo: airbytehq/connector-builder-mcp PR: 116
File: .github/workflows/ci-tests.yml:110-113
Timestamp: 2025-10-10T17:09:02.151Z
Learning: The connector-builder-mcp repository (airbytehq/connector-builder-mcp) is an internal/private repository that doesn't accept external contributions, so there are no forked PRs to consider in workflow configurations.
Learnt from: aaronsteers
Repo: airbytehq/connector-builder-mcp PR: 116
File: .github/workflows/ci-tests.yml:110-113
Timestamp: 2025-10-10T17:09:05.986Z
Learning: The connector-builder-mcp repository at airbytehq/connector-builder-mcp is a private/internal repository that does not accept external contributions or forks.
Learnt from: aaronsteers
Repo: airbytehq/connector-builder-mcp PR: 116
File: connector_builder_agents/src/evals/evaluators.py:78-79
Timestamp: 2025-10-08T17:51:38.833Z
Learning: In the connector-builder-mcp repository, internal evaluation code (e.g., in connector_builder_agents/src/evals/) doesn't need to be bulletproof with extensive error handling, as the simpler approach is preferred for internal tooling.
📚 Learning: 2025-10-11T02:19:05.231Z
Learnt from: aaronsteers
Repo: airbytehq/connector-builder-mcp PR: 136
File: connector_builder_agents/src/evals/evaluators.py:233-245
Timestamp: 2025-10-11T02:19:05.231Z
Learning: In the connector-builder-mcp repository Python files, all imports must be placed at the module level (top of the file), never inside functions or methods. This is a recurring issue that should be flagged during code reviews.

Applied to files:

  • connector_builder_mcp/build_strategies/openapi_sonar_v1/prompts.py
📚 Learning: 2025-11-08T06:53:26.977Z
Learnt from: aaronsteers
Repo: airbytehq/connector-builder-mcp PR: 176
File: connector_builder_mcp/_manifest_history_utils.py:38-49
Timestamp: 2025-11-08T06:53:26.977Z
Learning: In the connector-builder-mcp repository, all imports must be at the module level (top of the file). Inline imports inside functions or methods are not allowed unless explicit permission is granted. This rule must never be violated.

Applied to files:

  • connector_builder_mcp/server.py
📚 Learning: 2025-10-10T17:09:05.986Z
Learnt from: aaronsteers
Repo: airbytehq/connector-builder-mcp PR: 116
File: .github/workflows/ci-tests.yml:110-113
Timestamp: 2025-10-10T17:09:05.986Z
Learning: The connector-builder-mcp repository at airbytehq/connector-builder-mcp is a private/internal repository that does not accept external contributions or forks.

Applied to files:

  • connector_builder_mcp/server.py
🧬 Code graph analysis (16)
connector_builder_mcp/build_strategies/openapi_sonar_v1/prompts.py (2)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_prompt (152-182)
  • register_mcp_prompts (282-308)
connector_builder_mcp/build_strategies/openapi_sonar_v1/build_strategy.py (1)
  • register_prompts (57-59)
connector_builder_mcp/build_strategies/openapi_sonar_v1/guidance.py (6)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py (1)
  • register_guidance_tools (41-43)
connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py (1)
  • register_guidance_tools (431-435)
connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py (1)
  • register_guidance_tools (41-43)
connector_builder_mcp/build_strategies/kotlin_source_v1/guidance.py (1)
  • register_guidance_tools (307-311)
connector_builder_mcp/build_strategies/openapi_sonar_v1/build_strategy.py (1)
  • register_guidance_tools (42-44)
connector_builder_mcp/build_strategies/kotlin_source_v1/guidance.py (2)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py (1)
  • register_guidance_tools (41-43)
connector_builder_mcp/build_strategies/openapi_sonar_v1/build_strategy.py (5)
connector_builder_mcp/build_strategies/base/build_strategy.py (1)
  • BuildStrategy (18-185)
connector_builder_mcp/build_strategies/openapi_sonar_v1/guidance.py (1)
  • register_guidance_tools (201-205)
connector_builder_mcp/build_strategies/openapi_sonar_v1/manifest_checks.py (1)
  • register_manifest_check_tools (91-97)
connector_builder_mcp/build_strategies/openapi_sonar_v1/manifest_tests.py (1)
  • register_manifest_test_tools (94-100)
connector_builder_mcp/build_strategies/openapi_sonar_v1/prompts.py (1)
  • register_prompts (95-101)
connector_builder_mcp/build_strategies/kotlin_destination_v1/manifest_tests.py (4)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py (1)
  • register_manifest_test_tools (51-53)
connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py (1)
  • register_manifest_test_tools (51-53)
connector_builder_mcp/build_strategies/kotlin_source_v1/manifest_tests.py (1)
  • register_manifest_test_tools (92-98)
connector_builder_mcp/server.py (5)
connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py (2)
  • KotlinDestinationV1Strategy (21-58)
  • is_available (33-38)
connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py (2)
  • KotlinSourceV1Strategy (21-58)
  • is_available (33-38)
connector_builder_mcp/build_strategies/openapi_sonar_v1/build_strategy.py (2)
  • OpenApiSonarV1Strategy (22-59)
  • is_available (34-39)
connector_builder_mcp/build_strategies/declarative_yaml_v1/build_strategy.py (2)
  • DeclarativeYamlV1Strategy (22-61)
  • is_available (35-41)
connector_builder_mcp/build_strategies/base/build_strategy.py (2)
  • is_available (52-61)
  • register_all_mcp_callables (107-120)
connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py (5)
connector_builder_mcp/build_strategies/base/build_strategy.py (1)
  • BuildStrategy (18-185)
connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py (1)
  • register_guidance_tools (431-435)
connector_builder_mcp/build_strategies/kotlin_destination_v1/manifest_checks.py (1)
  • register_manifest_check_tools (76-82)
connector_builder_mcp/build_strategies/kotlin_destination_v1/manifest_tests.py (1)
  • register_manifest_test_tools (95-101)
connector_builder_mcp/build_strategies/kotlin_destination_v1/prompts.py (1)
  • register_prompts (93-99)
connector_builder_mcp/build_strategies/kotlin_source_v1/prompts.py (6)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_prompt (152-182)
  • register_mcp_prompts (282-308)
connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py (1)
  • register_prompts (56-58)
connector_builder_mcp/build_strategies/kotlin_destination_v1/prompts.py (1)
  • register_prompts (93-99)
connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py (1)
  • register_prompts (56-58)
connector_builder_mcp/build_strategies/openapi_sonar_v1/build_strategy.py (1)
  • register_prompts (57-59)
connector_builder_mcp/build_strategies/openapi_sonar_v1/prompts.py (1)
  • register_prompts (95-101)
connector_builder_mcp/build_strategies/kotlin_destination_v1/manifest_checks.py (3)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py (1)
  • register_manifest_check_tools (46-48)
connector_builder_mcp/build_strategies/kotlin_source_v1/manifest_checks.py (1)
  • register_manifest_check_tools (76-82)
connector_builder_mcp/build_strategies/kotlin_source_v1/manifest_checks.py (4)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py (1)
  • register_manifest_check_tools (46-48)
connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py (1)
  • register_manifest_check_tools (46-48)
connector_builder_mcp/build_strategies/openapi_sonar_v1/build_strategy.py (1)
  • register_manifest_check_tools (47-49)
connector_builder_mcp/build_strategies/kotlin_source_v1/manifest_tests.py (5)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py (1)
  • register_manifest_test_tools (51-53)
connector_builder_mcp/build_strategies/kotlin_destination_v1/manifest_tests.py (1)
  • register_manifest_test_tools (95-101)
connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py (1)
  • register_manifest_test_tools (51-53)
connector_builder_mcp/build_strategies/openapi_sonar_v1/build_strategy.py (1)
  • register_manifest_test_tools (52-54)
connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py (5)
connector_builder_mcp/build_strategies/base/build_strategy.py (1)
  • BuildStrategy (18-185)
connector_builder_mcp/build_strategies/kotlin_source_v1/guidance.py (1)
  • register_guidance_tools (307-311)
connector_builder_mcp/build_strategies/kotlin_source_v1/manifest_checks.py (1)
  • register_manifest_check_tools (76-82)
connector_builder_mcp/build_strategies/kotlin_source_v1/manifest_tests.py (1)
  • register_manifest_test_tools (92-98)
connector_builder_mcp/build_strategies/kotlin_source_v1/prompts.py (1)
  • register_prompts (92-98)
connector_builder_mcp/build_strategies/openapi_sonar_v1/manifest_checks.py (2)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/openapi_sonar_v1/build_strategy.py (1)
  • register_manifest_check_tools (47-49)
connector_builder_mcp/build_strategies/kotlin_destination_v1/prompts.py (3)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_prompt (152-182)
  • register_mcp_prompts (282-308)
connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py (1)
  • register_prompts (56-58)
connector_builder_mcp/build_strategies/kotlin_source_v1/prompts.py (1)
  • register_prompts (92-98)
connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py (2)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py (1)
  • register_guidance_tools (41-43)
connector_builder_mcp/build_strategies/openapi_sonar_v1/manifest_tests.py (2)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/openapi_sonar_v1/build_strategy.py (1)
  • register_manifest_test_tools (52-54)
🪛 GitHub Actions: CI Tests
connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py

[error] 186-186: SyntaxError: invalid syntax. Perhaps you forgot a comma? (likely inside the "write_modes" block in guidance.py)

🪛 GitHub Actions: Generate Docs
connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py

[error] 186-186: SyntaxError: invalid syntax. Perhaps you forgot a comma?

🪛 GitHub Actions: Linters
connector_builder_mcp/build_strategies/kotlin_source_v1/guidance.py

[error] 118-122: W293: Blank line contains whitespace. Ruff reported trailing/whitespace formatting issues in this file. Review and clean up blank lines.

connector_builder_mcp/build_strategies/openapi_sonar_v1/build_strategy.py

[error] 9-9: F401: 'sys' imported but unused. Remove unused import.

connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py

[error] 8-8: F401: 'sys' imported but unused. Remove unused import.

connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py

[error] 8-8: F401: 'sys' imported but unused. Remove unused import.

connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py

[error] 122-160: W293, W291, E211: Multiple formatting issues detected (blank lines with whitespace, trailing whitespace, and related formatting hints). Ruff reported numerous whitespace-related lint issues in this file. Review and fix blank lines, trailing spaces, and line formatting to resolve.

🪛 GitHub Actions: Pytest (Fast)
connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py

[error] 186-186: SyntaxError: invalid syntax. Perhaps you forgot a comma?

🔇 Additional comments (18)
connector_builder_mcp/build_strategies/kotlin_source_v1/__init__.py (1)

1-1: Docstring-only module looks fine

Straightforward, descriptive module docstring; no issues from a behavior or style perspective.

connector_builder_mcp/build_strategies/kotlin_destination_v1/__init__.py (1)

1-1: Kotlin destination init is fine; remember to fix guidance.py before merge

The minimal docstring here is fine. As per the PR description, just ensure the known syntax error in kotlin_destination_v1/guidance.py is resolved before taking this out of draft.

connector_builder_mcp/build_strategies/kotlin_destination_v1/checklist.yaml (1)

1-181: Checklist structure and content look coherent

Top-level keys and task lists are well-structured and read logically for a Kotlin destination build workflow; indentation and YAML structure also look valid.

connector_builder_mcp/build_strategies/openapi_sonar_v1/manifest_checks.py (1)

91-97: Registration helper correctly wires tools into MANIFEST_CHECKS domain

register_manifest_check_tools delegating to register_mcp_tools(app, domain=ToolDomain.MANIFEST_CHECKS) matches how the @mcp_tool decorator tags validate_openapi_spec, so this should integrate cleanly with the shared registration mechanism.

connector_builder_mcp/build_strategies/kotlin_source_v1/manifest_checks.py (1)

76-82: Manifest-check tool registration is consistent with shared MCP utilities

The registration helper correctly reuses register_mcp_tools with the MANIFEST_CHECKS domain, which should make this tool discoverable wherever other manifest-check tools are registered.

connector_builder_mcp/build_strategies/kotlin_destination_v1/manifest_tests.py (1)

87-92: Placeholder implementation acknowledged.

The placeholder implementation is noted in the PR description. The success return with records_written=0 clearly indicates this is not yet functional.

connector_builder_mcp/build_strategies/kotlin_source_v1/prompts.py (1)

20-89: LGTM!

The prompt template follows the established MCP pattern and provides comprehensive guidance for building Kotlin source connectors.

connector_builder_mcp/build_strategies/openapi_sonar_v1/__init__.py (1)

1-1: LGTM!

Minimal __init__.py with just a docstring is appropriate for this module.

connector_builder_mcp/server.py (1)

65-78: LGTM!

The multi-strategy registration flow correctly checks availability and registers tools for each strategy. The approach allows graceful handling of missing dependencies.

connector_builder_mcp/build_strategies/openapi_sonar_v1/checklist.yaml (1)

1-153: LGTM!

The checklist provides comprehensive workflow guidance for OpenAPI/Sonar connector development, following the established pattern from other strategy checklists.

connector_builder_mcp/build_strategies/openapi_sonar_v1/guidance.py (1)

19-198: LGTM!

The guidance documentation tool follows the established pattern and provides comprehensive OpenAPI/Sonar connector development guidance.

connector_builder_mcp/build_strategies/kotlin_source_v1/checklist.yaml (1)

1-186: LGTM!

The checklist provides comprehensive guidance for Kotlin source connector development, following the established checklist pattern.

connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py (1)

122-160: Fix formatting issues.

The linter reports multiple whitespace-related issues in this range: blank lines with whitespace (W293), trailing whitespace (W291), and whitespace before brackets (E211).

Run the formatters to fix these issues:

#!/bin/bash
# Fix formatting issues
ruff check --fix connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py
ruff format connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py
⛔ Skipped due to learnings
Learnt from: aaronsteers
Repo: airbytehq/connector-builder-mcp PR: 136
File: connector_builder_agents/src/evals/evaluators.py:233-245
Timestamp: 2025-10-11T02:19:05.231Z
Learning: In the connector-builder-mcp repository Python files, all imports must be placed at the module level (top of the file), never inside functions or methods. This is a recurring issue that should be flagged during code reviews.
connector_builder_mcp/build_strategies/openapi_sonar_v1/prompts.py (1)

1-101: Prompt definition and registration look consistent

The OpenAPI/Sonar prompt and register_prompts hook follow the existing MCP patterns cleanly; parameters, defaults, and registration domain all look good.

connector_builder_mcp/build_strategies/kotlin_destination_v1/prompts.py (1)

1-99: Kotlin destination prompt wiring looks good

The prompt definition, parameter handling, and register_prompts hook are consistent with the existing prompt modules and MCP utilities.

connector_builder_mcp/build_strategies/openapi_sonar_v1/manifest_tests.py (3)

1-16: LGTM! Clean module structure.

The imports are appropriate and well-organized. The module docstring clearly describes the purpose of testing OpenAPI-based connectors.


19-28: LGTM! Well-designed result model.

The ResourceTestResult model provides a clear structure for test results with sensible defaults and helpful field descriptions.


94-100: LGTM! Clean registration helper.

The registration function follows the established pattern for registering MCP tools by domain. Implementation is correct and matches the pattern used in other strategy modules.

Comment on lines 6 to 9
from __future__ import annotations

import sys

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Drop unused sys import and ensure destination guidance module compiles

Ruff flags sys as unused (F401). You can safely remove it here:

-from __future__ import annotations
-
-import sys
-
-from fastmcp import FastMCP
+from __future__ import annotations
+
+from fastmcp import FastMCP

Also, per the PR description, don’t forget to fix the syntax error in kotlin_destination_v1/guidance.py before enabling this strategy end‑to‑end.

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 GitHub Actions: Linters

[error] 8-8: F401: 'sys' imported but unused. Remove unused import.

🤖 Prompt for AI Agents
In
connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py
around lines 6 to 9, remove the unused import "sys" (Ruff F401) so the file only
imports needed symbols; additionally open kotlin_destination_v1/guidance.py and
fix the reported syntax error mentioned in the PR (correct the offending
token/structure so the module compiles) before enabling this strategy
end-to-end.

Comment on lines 19 to 73
class KotlinSourceValidationResult(BaseModel):
"""Result of Kotlin source connector validation."""

is_valid: bool
errors: list[str] = []
warnings: list[str] = []
streams_found: list[str] = []


@mcp_tool(
ToolDomain.MANIFEST_CHECKS,
read_only=True,
idempotent=True,
open_world=False,
)
def validate_kotlin_source_connector(
ctx: Context,
*,
project_path: Annotated[
str | None,
Field(description="Path to the Kotlin source connector project directory"),
] = None,
) -> KotlinSourceValidationResult:
"""Validate a Kotlin source connector project structure and code.

Args:
ctx: FastMCP context (automatically injected)
project_path: Path to the connector project

Returns:
Validation result with success status and any errors/warnings
"""
logger.info("Validating Kotlin source connector")

if project_path is None:
return KotlinSourceValidationResult(
is_valid=False,
errors=["No project path provided"],
warnings=[],
)

errors = []
warnings = []
streams_found = []

warnings.append("Kotlin source validation is a placeholder implementation")

is_valid = len(errors) == 0

return KotlinSourceValidationResult(
is_valid=is_valid,
errors=errors,
warnings=warnings,
streams_found=streams_found,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Align docstring and help text with current placeholder behavior

Right now the tool only checks that project_path is provided and then returns is_valid=True with a generic “placeholder implementation” warning; it doesn’t yet inspect project structure, code, or streams.

To avoid overpromising to tool users until the real checks exist, consider:

  • Updating the function docstring and/or Field description to explicitly call this a lightweight/placeholder validation, or
  • Implementing at least a minimal structural check (e.g., presence of expected Gradle/Kotlin files) before advertising full “project structure and code” validation.

This keeps expectations clear while you iterate on the real validator.

🤖 Prompt for AI Agents
In connector_builder_mcp/build_strategies/kotlin_source_v1/manifest_checks.py
around lines 19-73, the function docstring and Field description promise a full
“project structure and code” validation but the implementation is a placeholder
that only checks for project_path and returns a generic placeholder warning;
either update the docstring and the Field(description=...) text to state this is
a lightweight/placeholder validation, or implement a minimal structural check:
verify the project_path exists and contains expected files/directories (e.g.,
build.gradle(.kts) or settings.gradle(.kts), and src/main/kotlin or
src/main/java), append specific errors when missing, set is_valid = len(errors)
== 0 accordingly, and provide concrete warnings/errors in the returned
KotlinSourceValidationResult.

Comment on lines 19 to 88
class OpenApiValidationResult(BaseModel):
"""Result of OpenAPI specification validation."""

is_valid: bool
errors: list[str] = []
warnings: list[str] = []
resources_found: list[str] = []


@mcp_tool(
ToolDomain.MANIFEST_CHECKS,
read_only=True,
idempotent=True,
open_world=False,
)
def validate_openapi_spec(
ctx: Context,
*,
spec_content: Annotated[
str | None,
Field(
description="The OpenAPI specification content (YAML or JSON). "
"Can be raw content or path to spec file."
),
] = None,
) -> OpenApiValidationResult:
"""Validate an OpenAPI specification for connector building.

Args:
ctx: FastMCP context (automatically injected)
spec_content: The OpenAPI specification to validate

Returns:
Validation result with success status and any errors/warnings
"""
logger.info("Validating OpenAPI specification")

if spec_content is None:
return OpenApiValidationResult(
is_valid=False,
errors=["No OpenAPI specification provided"],
warnings=[],
)

errors = []
warnings = []
resources_found = []

if len(spec_content) < 10:
errors.append("OpenAPI specification appears to be empty or too short")

if "openapi" not in spec_content.lower():
errors.append("Missing 'openapi' version field")

if "paths" not in spec_content.lower():
warnings.append("No 'paths' section found in specification")

if "x-airbyte" not in spec_content:
warnings.append(
"No x-airbyte-* extensions found. You may need to add these to define resources."
)

is_valid = len(errors) == 0

return OpenApiValidationResult(
is_valid=is_valid,
errors=errors,
warnings=warnings,
resources_found=resources_found,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Clarify spec_content contract (raw spec vs path) or implement path loading

The implementation treats spec_content purely as a text blob (length checks, substring searches) and never attempts to resolve or read from a filesystem path, but the parameter/Field description says it “Can be raw content or path to spec file.” Passing a path today will just run these string checks on the path itself and likely produce misleading errors/warnings.

Either:

  • Narrow the description/docstring to say this expects raw OpenAPI spec content only, or
  • Extend the function to detect a likely file path and load its contents before validation (and then revisit open_world if you consider filesystem access “external”).

The current behavior is otherwise consistent and safe; this is mainly to avoid confusing tool consumers.

Comment on lines 42 to 51
spec_content: Annotated[
str | None,
Field(
description="The OpenAPI specification content. Can be raw content or path to spec file."
),
] = None,
config: Annotated[
dict[str, Any] | str | None,
Field(description="Connector configuration dictionary (including auth credentials)."),
] = None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Consider making required parameters non-optional.

The spec_content and config parameters have default values of None, which suggests they're optional. However, the function body treats them as required by returning errors when they're None (lines 71-83). This creates a misleading API.

Consider one of these approaches:

Option 1 (Preferred): Make them truly required

-    spec_content: Annotated[
-        str | None,
-        Field(
-            description="The OpenAPI specification content. Can be raw content or path to spec file."
-        ),
-    ] = None,
+    spec_content: Annotated[
+        str,
+        Field(
+            description="The OpenAPI specification content. Can be raw content or path to spec file."
+        ),
+    ],
     config: Annotated[
-        dict[str, Any] | str | None,
+        dict[str, Any] | str,
         Field(description="Connector configuration dictionary (including auth credentials)."),
-    ] = None,
+    ],

Option 2: Accept them as optional and handle gracefully in a real implementation

If there's a valid use case for calling this without credentials (e.g., dry-run validation), keep them optional but document this behavior clearly.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
spec_content: Annotated[
str | None,
Field(
description="The OpenAPI specification content. Can be raw content or path to spec file."
),
] = None,
config: Annotated[
dict[str, Any] | str | None,
Field(description="Connector configuration dictionary (including auth credentials)."),
] = None,
spec_content: Annotated[
str,
Field(
description="The OpenAPI specification content. Can be raw content or path to spec file."
),
],
config: Annotated[
dict[str, Any] | str,
Field(description="Connector configuration dictionary (including auth credentials)."),
],

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0a32fbc and c94798e.

📒 Files selected for processing (1)
  • connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: aaronsteers
Repo: airbytehq/connector-builder-mcp PR: 116
File: .github/workflows/ci-tests.yml:110-113
Timestamp: 2025-10-10T17:09:02.151Z
Learning: The connector-builder-mcp repository (airbytehq/connector-builder-mcp) is an internal/private repository that doesn't accept external contributions, so there are no forked PRs to consider in workflow configurations.
📚 Learning: 2025-10-11T02:19:05.231Z
Learnt from: aaronsteers
Repo: airbytehq/connector-builder-mcp PR: 136
File: connector_builder_agents/src/evals/evaluators.py:233-245
Timestamp: 2025-10-11T02:19:05.231Z
Learning: In the connector-builder-mcp repository Python files, all imports must be placed at the module level (top of the file), never inside functions or methods. This is a recurring issue that should be flagged during code reviews.

Applied to files:

  • connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py
🧬 Code graph analysis (1)
connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py (6)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py (1)
  • register_guidance_tools (41-43)
connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py (1)
  • register_guidance_tools (41-43)
connector_builder_mcp/build_strategies/kotlin_source_v1/guidance.py (1)
  • register_guidance_tools (307-311)
connector_builder_mcp/build_strategies/openapi_sonar_v1/guidance.py (1)
  • register_guidance_tools (201-205)
connector_builder_mcp/build_strategies/openapi_sonar_v1/build_strategy.py (1)
  • register_guidance_tools (42-44)
🪛 GitHub Actions: Linters
connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py

[warning] 122-122: W293 Blank line contains whitespace


[warning] 124-124: W293 Blank line contains whitespace


[warning] 131-131: W293 Blank line contains whitespace


[warning] 144-144: W293 Blank line contains whitespace


[warning] 158-158: W293 Blank line contains whitespace


[warning] 160-160: W293 Blank line contains whitespace


[warning] 167-167: W293 Blank line contains whitespace


[warning] 177-177: W293 Blank line contains whitespace


[warning] 194-194: W293 Blank line contains whitespace


[warning] 211-211: W293 Blank line contains whitespace


[warning] 213-213: W293 Blank line contains whitespace


[warning] 236-236: W293 Blank line contains whitespace


[warning] 244-244: W293 Blank line contains whitespace


[warning] 265-265: W293 Blank line contains whitespace


[warning] 272-272: W293 Blank line contains whitespace


[warning] 275-275: W293 Blank line contains whitespace


[warning] 297-297: W293 Blank line contains whitespace


[warning] 300-300: W293 Blank line contains whitespace


[warning] 326-326: W293 Blank line contains whitespace


[warning] 342-342: W293 Blank line contains whitespace


[warning] 367-367: W293 Blank line contains whitespace


[warning] 390-390: W293 Blank line contains whitespace

🔇 Additional comments (4)
connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py (4)

1-16: LGTM!

Module structure and imports are correct. All imports are at the module level as required.


19-38: LGTM!

Function decorator and signature follow the established pattern from other build strategies and correctly use ToolDomain.GUIDANCE.


40-76: LGTM!

High-level overview is clear and appropriately references the checklist tool for step-by-step guidance.


431-435: LGTM!

Registration function follows the established pattern from other build strategies.

Comment on lines 122 to 390

private val writers = mutableMapOf<String, StreamWriter>()

override fun start() {
// Initialize connections and writers
catalog.streams.forEach { stream ->
writers[stream.stream.name] = createWriter(stream)
}
}

override fun accept(message: AirbyteMessage) {
when (message.type) {
Type.RECORD -> {
val streamName = message.record.stream
writers[streamName]?.write(message.record.data)
}
Type.STATE -> {
// Flush buffers and commit
writers.values.forEach { it.flush() }
}
}
}

override fun close() {
writers.values.forEach { it.close() }
}
}
```


```kotlin
class BufferedConsumer(
private val config: JsonNode,
private val catalog: ConfiguredAirbyteCatalog,
private val bufferSize: Int = 1000
) : AirbyteMessageConsumer {

private val buffers = mutableMapOf<String, MutableList<JsonNode>>()

override fun accept(message: AirbyteMessage) {
when (message.type) {
Type.RECORD -> {
val streamName = message.record.stream
val buffer = buffers.getOrPut(streamName) { mutableListOf() }
buffer.add(message.record.data)

if (buffer.size >= bufferSize) {
flushBuffer(streamName)
}
}
Type.STATE -> {
flushAllBuffers()
}
}
}

private fun flushBuffer(streamName: String) {
val buffer = buffers[streamName] ?: return
writers[streamName]?.writeBatch(buffer)
buffer.clear()
}
}
```
""",
"write_modes": '''# Write Modes Implementation


```kotlin
class AppendWriter(
private val tableName: String,
private val connection: Connection
) : StreamWriter {

override fun write(record: JsonNode) {
val sql = "INSERT INTO $tableName (${getColumns()}) VALUES (${getPlaceholders()})"
connection.prepareStatement(sql).use { stmt ->
setParameters(stmt, record)
stmt.executeUpdate()
}
}
}
```


```kotlin
class OverwriteWriter(
private val tableName: String,
private val connection: Connection
) : StreamWriter {

private var isFirstBatch = true

override fun writeBatch(records: List<JsonNode>) {
if (isFirstBatch) {
// Truncate or drop/recreate table
connection.createStatement().use {
it.execute("TRUNCATE TABLE $tableName")
}
isFirstBatch = false
}

// Insert records
records.forEach { write(it) }
}
}
```


```kotlin
class UpsertWriter(
private val tableName: String,
private val primaryKeys: List<String>,
private val connection: Connection
) : StreamWriter {

override fun write(record: JsonNode) {
val sql = buildUpsertSql()
connection.prepareStatement(sql).use { stmt ->
setParameters(stmt, record)
stmt.executeUpdate()
}
}

private fun buildUpsertSql(): String {
// PostgreSQL example
return """
INSERT INTO $tableName (${getColumns()})
VALUES (${getPlaceholders()})
ON CONFLICT (${primaryKeys.joinToString()})
DO UPDATE SET ${getUpdateClause()}
""".trimIndent()
}
}
```
''',
"batching": """# Batching Strategies


```kotlin
class BatchWriter(
private val batchSize: Int = 1000
) {
private val buffer = mutableListOf<JsonNode>()

fun addRecord(record: JsonNode) {
buffer.add(record)
if (buffer.size >= batchSize) {
flush()
}
}

fun flush() {
if (buffer.isEmpty()) return

val sql = buildBatchInsertSql(buffer.size)
connection.prepareStatement(sql).use { stmt ->
var paramIndex = 1
buffer.forEach { record ->
setParameters(stmt, record, paramIndex)
paramIndex += getColumnCount()
}
stmt.executeUpdate()
}
buffer.clear()
}
}
```


```kotlin
class TimeBasedBatchWriter(
private val flushIntervalMs: Long = 5000
) {
private val buffer = mutableListOf<JsonNode>()
private var lastFlushTime = System.currentTimeMillis()

fun addRecord(record: JsonNode) {
buffer.add(record)

val now = System.currentTimeMillis()
if (now - lastFlushTime >= flushIntervalMs) {
flush()
lastFlushTime = now
}
}
}
```
""",
"schema_mapping": '''# Schema Mapping and Type Conversion


```kotlin
object TypeMapper {
fun airbyteTypeToSqlType(airbyteType: JsonNode): String {
return when (airbyteType.get("type").asText()) {
"string" -> "VARCHAR"
"integer" -> "BIGINT"
"number" -> "DOUBLE"
"boolean" -> "BOOLEAN"
"array" -> "JSON"
"object" -> "JSON"
else -> "VARCHAR"
}
}

fun convertValue(value: JsonNode, targetType: String): Any? {
return when (targetType) {
"BIGINT" -> value.asLong()
"DOUBLE" -> value.asDouble()
"BOOLEAN" -> value.asBoolean()
"JSON" -> value.toString()
else -> value.asText()
}
}
}
```


```kotlin
class SchemaManager(private val connection: Connection) {

fun createTableFromAirbyteSchema(
tableName: String,
schema: JsonNode
) {
val columns = schema.get("properties").fields().asSequence()
.map { (name, type) ->
"$name ${TypeMapper.airbyteTypeToSqlType(type)}"
}
.joinToString(", ")

val sql = "CREATE TABLE IF NOT EXISTS $tableName ($columns)"
connection.createStatement().use { it.execute(sql) }
}
}
```
""",
"error_handling": """# Error Handling and Retry Logic


```kotlin
class RetryableWriter(
private val delegate: StreamWriter,
private val maxRetries: Int = 3
) : StreamWriter {

override fun write(record: JsonNode) {
var attempt = 0
var lastException: Exception? = null

while (attempt < maxRetries) {
try {
delegate.write(record)
return
} catch (e: SQLException) {
lastException = e
attempt++

if (isRetryable(e)) {
Thread.sleep(getBackoffDelay(attempt))
} else {
throw e
}
}
}

throw RuntimeException("Failed after $maxRetries attempts", lastException)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Address trailing whitespace in code examples.

The linter reports W293 warnings (blank line contains whitespace) at multiple lines within the embedded Kotlin code examples. While these don't affect functionality, removing trailing whitespace will clean up the code and satisfy the linter.

Run the following command to automatically fix trailing whitespace:

#!/bin/bash
# Remove trailing whitespace from the file
sed -i 's/[[:space:]]*$//' connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py
🧰 Tools
🪛 GitHub Actions: Linters

[warning] 122-122: W293 Blank line contains whitespace


[warning] 124-124: W293 Blank line contains whitespace


[warning] 131-131: W293 Blank line contains whitespace


[warning] 144-144: W293 Blank line contains whitespace


[warning] 158-158: W293 Blank line contains whitespace


[warning] 160-160: W293 Blank line contains whitespace


[warning] 167-167: W293 Blank line contains whitespace


[warning] 177-177: W293 Blank line contains whitespace


[warning] 194-194: W293 Blank line contains whitespace


[warning] 211-211: W293 Blank line contains whitespace


[warning] 213-213: W293 Blank line contains whitespace


[warning] 236-236: W293 Blank line contains whitespace


[warning] 244-244: W293 Blank line contains whitespace


[warning] 265-265: W293 Blank line contains whitespace


[warning] 272-272: W293 Blank line contains whitespace


[warning] 275-275: W293 Blank line contains whitespace


[warning] 297-297: W293 Blank line contains whitespace


[warning] 300-300: W293 Blank line contains whitespace


[warning] 326-326: W293 Blank line contains whitespace


[warning] 342-342: W293 Blank line contains whitespace


[warning] 367-367: W293 Blank line contains whitespace


[warning] 390-390: W293 Blank line contains whitespace

🤖 Prompt for AI Agents
In connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py
around lines 122-390 there are multiple embedded Kotlin code examples containing
trailing whitespace (linter W293). Remove trailing spaces from those example
blocks — e.g., run a file-wide trailing-whitespace strip (sed -i
's/[[:space:]]*$//'
connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py) or use
your editor/IDE to trim trailing whitespace and reformat the code blocks, then
re-run the linter to confirm W293 warnings are gone.

Comment on lines 310 to 358
"schema_mapping": '''# Schema Mapping and Type Conversion


```kotlin
object TypeMapper {
fun airbyteTypeToSqlType(airbyteType: JsonNode): String {
return when (airbyteType.get("type").asText()) {
"string" -> "VARCHAR"
"integer" -> "BIGINT"
"number" -> "DOUBLE"
"boolean" -> "BOOLEAN"
"array" -> "JSON"
"object" -> "JSON"
else -> "VARCHAR"
}
}

fun convertValue(value: JsonNode, targetType: String): Any? {
return when (targetType) {
"BIGINT" -> value.asLong()
"DOUBLE" -> value.asDouble()
"BOOLEAN" -> value.asBoolean()
"JSON" -> value.toString()
else -> value.asText()
}
}
}
```


```kotlin
class SchemaManager(private val connection: Connection) {

fun createTableFromAirbyteSchema(
tableName: String,
schema: JsonNode
) {
val columns = schema.get("properties").fields().asSequence()
.map { (name, type) ->
"$name ${TypeMapper.airbyteTypeToSqlType(type)}"
}
.joinToString(", ")

val sql = "CREATE TABLE IF NOT EXISTS $tableName ($columns)"
connection.createStatement().use { it.execute(sql) }
}
}
```
""",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Fix mismatched string quotes blocking module load.

The "schema_mapping" topic starts with triple single quotes (''') on line 310 but ends with triple double quotes (""") on line 358. This mismatch causes a syntax error that prevents the module from loading.

Apply this diff to fix the mismatch:

-""",
+''',
🧰 Tools
🪛 GitHub Actions: Linters

[warning] 326-326: W293 Blank line contains whitespace


[warning] 342-342: W293 Blank line contains whitespace

🤖 Prompt for AI Agents
In connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py
around lines 310 to 358, the multi-line string for "schema_mapping" begins with
triple single quotes (''') but is closed with triple double quotes ("""),
causing a syntax error; fix it by making the opening and closing delimiters
match (change the closing triple double quotes to triple single quotes or vice
versa) so the string is properly terminated and the module can load.

Comment on lines 359 to 422
"error_handling": """# Error Handling and Retry Logic


```kotlin
class RetryableWriter(
private val delegate: StreamWriter,
private val maxRetries: Int = 3
) : StreamWriter {

override fun write(record: JsonNode) {
var attempt = 0
var lastException: Exception? = null

while (attempt < maxRetries) {
try {
delegate.write(record)
return
} catch (e: SQLException) {
lastException = e
attempt++

if (isRetryable(e)) {
Thread.sleep(getBackoffDelay(attempt))
} else {
throw e
}
}
}

throw RuntimeException("Failed after $maxRetries attempts", lastException)
}

private fun isRetryable(e: SQLException): Boolean {
// Check for transient errors
return e.sqlState in listOf("08001", "08006", "40001")
}

private fun getBackoffDelay(attempt: Int): Long {
return (1000L * Math.pow(2.0, attempt.toDouble())).toLong()
}
}
```


```kotlin
class TransactionalWriter(
private val connection: Connection
) : StreamWriter {

override fun writeBatch(records: List<JsonNode>) {
connection.autoCommit = false
try {
records.forEach { write(it) }
connection.commit()
} catch (e: Exception) {
connection.rollback()
throw e
} finally {
connection.autoCommit = true
}
}
}
```
''',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Fix mismatched string quotes blocking module load.

The "error_handling" topic starts with triple double quotes (""") on line 359 but ends with triple single quotes (''') on line 422. This mismatch causes a syntax error that prevents the module from loading.

Apply this diff to fix the mismatch:

-''',
+""",
🧰 Tools
🪛 GitHub Actions: Linters

[warning] 367-367: W293 Blank line contains whitespace


[warning] 390-390: W293 Blank line contains whitespace

🤖 Prompt for AI Agents
In connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py
around lines 359 to 422, the multi-line string for "error_handling" opens with
triple double-quotes (""") but is closed with triple single-quotes ('''),
causing a syntax error; fix it by making the opening and closing quotes match
(change the closing quotes to triple double-quotes) so the string is properly
terminated and the module can load.

@aaronsteers aaronsteers changed the title feat: Add 3 new build strategy submodules (OpenAPI/Sonar, Kotlin Source, Kotlin Destination) (do not merge) feat: Add 3 new build strategy submodules (OpenAPI/Sonar, Kotlin Source, Kotlin Destination) Nov 19, 2025
@aaronsteers aaronsteers marked this pull request as ready for review November 19, 2025 22:46
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (6)
connector_builder_mcp/build_strategies/kotlin_source_v1/manifest_checks.py (1)

34-73: Align docstring with current placeholder behavior.

The function docstring and Field description promise "project structure and code" validation, but the implementation is a placeholder that only checks for project_path and returns a generic placeholder warning. To avoid overpromising to tool users until the real checks exist, consider updating the docstring to explicitly call this a lightweight/placeholder validation.

connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py (3)

310-358: Critical: Fix mismatched string quotes blocking module load.

The "schema_mapping" topic starts with triple single quotes (''') on line 310 but ends with triple double quotes (""") on line 358. This mismatch causes a syntax error that prevents the module from loading.

Apply this diff to fix the mismatch:

-""",
+''',

359-422: Critical: Fix mismatched string quotes blocking module load.

The "error_handling" topic starts with triple double quotes (""") on line 359 but ends with triple single quotes (''') on line 422. This mismatch causes a syntax error that prevents the module from loading.

Apply this diff to fix the mismatch:

-''',
+""",

122-390: Address trailing whitespace in code examples.

The linter reports W293 warnings (blank line contains whitespace) at multiple lines within the embedded Kotlin code examples. While these don't affect functionality, removing trailing whitespace will clean up the code and satisfy the linter.

Run the following command to automatically fix trailing whitespace:

#!/bin/bash
# Remove trailing whitespace from the file
sed -i 's/[[:space:]]*$//' connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py
connector_builder_mcp/build_strategies/kotlin_source_v1/guidance.py (1)

118-122: Clean up trailing whitespace on blank lines (W293).

Ruff reports W293 for blank lines with spaces in this Kotlin code block. Strip whitespace from the empty lines so they are truly blank, or run the project formatter to normalize them.

Run the following command to fix trailing whitespace:

#!/bin/bash
# Remove trailing whitespace from the file
sed -i 's/[[:space:]]*$//' connector_builder_mcp/build_strategies/kotlin_source_v1/guidance.py
connector_builder_mcp/build_strategies/openapi_sonar_v1/manifest_checks.py (1)

37-42: Documentation still doesn't match implementation.

This is the same issue flagged in the previous review: the Field description claims spec_content "Can be raw content or path to spec file," but the implementation only performs string checks (length, substring searches) and never attempts to load from a path. Passing a file path will produce misleading validation results.

As suggested in the previous review, either:

  • Update the description to clarify this expects raw OpenAPI spec content only, or
  • Implement path detection and file loading before validation
🧹 Nitpick comments (2)
connector_builder_mcp/build_strategies/kotlin_destination_v1/manifest_checks.py (1)

23-25: Use Field(default_factory=list) for mutable defaults in Pydantic models.

While Pydantic v2 handles mutable defaults better than v1, the recommended best practice is to use Field(default_factory=list) for list fields with defaults to avoid potential issues and follow Pydantic conventions.

Apply this diff:

-    errors: list[str] = []
-    warnings: list[str] = []
-    streams_found: list[str] = []
+    errors: list[str] = Field(default_factory=list)
+    warnings: list[str] = Field(default_factory=list)
+    streams_found: list[str] = Field(default_factory=list)
connector_builder_mcp/build_strategies/openapi_sonar_v1/manifest_checks.py (1)

19-25: Prefer Field(default_factory=list) for mutable defaults.

While Pydantic v2 handles bare = [] correctly, using Field(default_factory=list) is more explicit and aligns with best practices for mutable defaults.

Apply this diff:

 class OpenApiValidationResult(BaseModel):
     """Result of OpenAPI specification validation."""
 
     is_valid: bool
-    errors: list[str] = []
-    warnings: list[str] = []
-    resources_found: list[str] = []
+    errors: list[str] = Field(default_factory=list)
+    warnings: list[str] = Field(default_factory=list)
+    resources_found: list[str] = Field(default_factory=list)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c94798e and 6324c5f.

📒 Files selected for processing (8)
  • connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_destination_v1/manifest_checks.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_source_v1/guidance.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_source_v1/manifest_checks.py (1 hunks)
  • connector_builder_mcp/build_strategies/openapi_sonar_v1/build_strategy.py (1 hunks)
  • connector_builder_mcp/build_strategies/openapi_sonar_v1/manifest_checks.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • connector_builder_mcp/build_strategies/openapi_sonar_v1/build_strategy.py
  • connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: aaronsteers
Repo: airbytehq/connector-builder-mcp PR: 116
File: .github/workflows/ci-tests.yml:110-113
Timestamp: 2025-10-10T17:09:02.151Z
Learning: The connector-builder-mcp repository (airbytehq/connector-builder-mcp) is an internal/private repository that doesn't accept external contributions, so there are no forked PRs to consider in workflow configurations.
📚 Learning: 2025-10-11T02:19:05.231Z
Learnt from: aaronsteers
Repo: airbytehq/connector-builder-mcp PR: 136
File: connector_builder_agents/src/evals/evaluators.py:233-245
Timestamp: 2025-10-11T02:19:05.231Z
Learning: In the connector-builder-mcp repository Python files, all imports must be placed at the module level (top of the file), never inside functions or methods. This is a recurring issue that should be flagged during code reviews.

Applied to files:

  • connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py
  • connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py
📚 Learning: 2025-11-08T06:53:26.977Z
Learnt from: aaronsteers
Repo: airbytehq/connector-builder-mcp PR: 176
File: connector_builder_mcp/_manifest_history_utils.py:38-49
Timestamp: 2025-11-08T06:53:26.977Z
Learning: In the connector-builder-mcp repository, all imports must be at the module level (top of the file). Inline imports inside functions or methods are not allowed unless explicit permission is granted. This rule must never be violated.

Applied to files:

  • connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py
📚 Learning: 2025-10-10T17:57:12.175Z
Learnt from: aaronsteers
Repo: airbytehq/connector-builder-mcp PR: 113
File: connector_builder_agents/src/agents.py:113-124
Timestamp: 2025-10-10T17:57:12.175Z
Learning: In `connector_builder_agents/src/agents.py`, the spaces after `\n` in log messages (e.g., `\n Task Name:`) are intentional design choices to create indentation in logs for better readability.

Applied to files:

  • connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py
🧬 Code graph analysis (6)
connector_builder_mcp/build_strategies/openapi_sonar_v1/manifest_checks.py (2)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/openapi_sonar_v1/build_strategy.py (1)
  • register_manifest_check_tools (45-47)
connector_builder_mcp/build_strategies/kotlin_source_v1/manifest_checks.py (5)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py (1)
  • register_manifest_check_tools (44-46)
connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py (1)
  • register_manifest_check_tools (44-46)
connector_builder_mcp/build_strategies/openapi_sonar_v1/build_strategy.py (1)
  • register_manifest_check_tools (45-47)
connector_builder_mcp/build_strategies/openapi_sonar_v1/manifest_checks.py (1)
  • register_manifest_check_tools (91-97)
connector_builder_mcp/build_strategies/kotlin_source_v1/guidance.py (5)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py (1)
  • register_guidance_tools (39-41)
connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py (1)
  • register_guidance_tools (431-435)
connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py (1)
  • register_guidance_tools (39-41)
connector_builder_mcp/build_strategies/openapi_sonar_v1/guidance.py (1)
  • register_guidance_tools (201-205)
connector_builder_mcp/build_strategies/kotlin_destination_v1/manifest_checks.py (2)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py (1)
  • register_manifest_check_tools (44-46)
connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py (5)
connector_builder_mcp/build_strategies/base/build_strategy.py (1)
  • BuildStrategy (18-185)
connector_builder_mcp/build_strategies/kotlin_source_v1/guidance.py (1)
  • register_guidance_tools (307-311)
connector_builder_mcp/build_strategies/kotlin_source_v1/manifest_checks.py (1)
  • register_manifest_check_tools (76-82)
connector_builder_mcp/build_strategies/kotlin_source_v1/manifest_tests.py (1)
  • register_manifest_test_tools (92-98)
connector_builder_mcp/build_strategies/kotlin_source_v1/prompts.py (1)
  • register_prompts (92-98)
connector_builder_mcp/build_strategies/kotlin_destination_v1/guidance.py (6)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/kotlin_destination_v1/build_strategy.py (1)
  • register_guidance_tools (39-41)
connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py (1)
  • register_guidance_tools (39-41)
connector_builder_mcp/build_strategies/kotlin_source_v1/guidance.py (1)
  • register_guidance_tools (307-311)
connector_builder_mcp/build_strategies/openapi_sonar_v1/build_strategy.py (1)
  • register_guidance_tools (40-42)
connector_builder_mcp/build_strategies/openapi_sonar_v1/guidance.py (1)
  • register_guidance_tools (201-205)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Pytest (All, Python 3.10, Ubuntu)
  • GitHub Check: Pytest (All, Python 3.11, Ubuntu)
  • GitHub Check: Pytest (Fast)
🔇 Additional comments (6)
connector_builder_mcp/build_strategies/kotlin_destination_v1/manifest_checks.py (3)

1-16: LGTM!

The module structure, docstring, and imports are well-organized and follow the established patterns in the codebase.


28-73: LGTM!

The tool function follows the established MCP tool pattern correctly:

  • Proper decorator usage with appropriate flags for a validation tool
  • Clear parameter annotations with Field descriptions
  • Transparent placeholder implementation (warning added at line 64)
  • Appropriate parameter validation

The placeholder implementation is expected per the PR objectives.


76-82: LGTM!

The registration function correctly follows the established pattern for registering MCP tools by domain, consistent with the _mcp_utils.py implementation and usage in build_strategy.py.

connector_builder_mcp/build_strategies/kotlin_source_v1/build_strategy.py (1)

19-56: LGTM!

The strategy class properly extends BuildStrategy and follows the established pattern. All imports are at module level, registration methods correctly delegate to module-level functions, and the class structure aligns with the multi-strategy architecture.

connector_builder_mcp/build_strategies/kotlin_source_v1/guidance.py (1)

1-311: Well-structured guidance module.

The module follows the established pattern from other guidance modules, with consistent string delimiters throughout (no quote mismatches like in the destination variant). The topic-based documentation structure is clear and the registration function properly delegates to register_mcp_tools.

connector_builder_mcp/build_strategies/openapi_sonar_v1/manifest_checks.py (1)

91-97: LGTM!

The registration function correctly delegates to the centralized register_mcp_tools utility with the appropriate domain. This follows the established pattern from other build strategies.

Comment on lines +76 to +79
if "x-airbyte" not in spec_content:
warnings.append(
"No x-airbyte-* extensions found. You may need to add these to define resources."
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Case-sensitive check may miss extension variants.

The check for "x-airbyte" is case-sensitive, which could miss valid variants like "X-AIRBYTE" or "X-Airbyte" in the specification.

Apply this diff to make the check case-insensitive:

-    if "x-airbyte" not in spec_content:
+    if "x-airbyte" not in spec_content.lower():
         warnings.append(
             "No x-airbyte-* extensions found. You may need to add these to define resources."
         )
🤖 Prompt for AI Agents
In connector_builder_mcp/build_strategies/openapi_sonar_v1/manifest_checks.py
around lines 76 to 79, the code checks for the literal key "x-airbyte" which is
case-sensitive and will miss variants like "X-AIRBYTE" or "X-Airbyte"; replace
the single-key membership test with a case-insensitive scan over the
spec_content keys (e.g., check if any key.lower().startswith("x-airbyte") or
any("x-airbyte" in key.lower()) for key in spec_content) and append the same
warning only if no matching key is found.

- Rename openapi_sonar_v1 → declarative_openapi_v3
- Remove _v1 suffix from kotlin_source and kotlin_destination
- Update class names to match new module names
- Add Java 21 availability checks for Kotlin connectors
- Empty stream_tasks lists for DB connectors (no stream-level tasks)
- Update all imports and references in server.py

Co-Authored-By: AJ Steers <[email protected]>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (3)
connector_builder_mcp/build_strategies/declarative_openapi_v3/manifest_checks.py (1)

19-88: Tighten Pydantic defaults and make x-airbyte check case‑insensitive

Two small but worthwhile tweaks here:

  1. Pydantic list defaults (Lines 22‑25)
    OpenApiValidationResult uses errors: list[str] = [], warnings: list[str] = [], and resources_found: list[str] = []. In Pydantic it’s safer to use Field(default_factory=list) for mutable types to avoid any shared‑mutable‑default surprises and to follow common style:
-class OpenApiValidationResult(BaseModel):
-    """Result of OpenAPI specification validation."""
-
-    is_valid: bool
-    errors: list[str] = []
-    warnings: list[str] = []
-    resources_found: list[str] = []
+class OpenApiValidationResult(BaseModel):
+    """Result of OpenAPI specification validation."""
+
+    is_valid: bool
+    errors: list[str] = Field(default_factory=list)
+    warnings: list[str] = Field(default_factory=list)
+    resources_found: list[str] = Field(default_factory=list)
  1. Case‑insensitive x-airbyte detection (Lines 76‑79)
    As noted in a prior review on a sibling OpenAPI manifest‑checks module, checking for "x-airbyte" in a case‑sensitive way can miss variants like "X-AIRBYTE" or "X-Airbyte". Since spec_content is treated as text here, you can cheaply make this check case‑insensitive:
-    if "x-airbyte" not in spec_content:
+    if "x-airbyte" not in spec_content.lower():
         warnings.append(
             "No x-airbyte-* extensions found. You may need to add these to define resources."
         )
connector_builder_mcp/build_strategies/kotlin_destination/guidance.py (2)

310-358: Critical: Fix mismatched string quotes blocking module load.

The "schema_mapping" topic starts with triple single quotes (''') on line 310 but ends with triple double quotes (""") on line 358, causing a syntax error that prevents the module from loading.

Apply this diff to fix:

-""",
+''',

359-422: Critical: Fix mismatched string quotes blocking module load.

The "error_handling" topic starts with triple double quotes (""") on line 359 but ends with triple single quotes (''') on line 422, causing a syntax error that prevents the module from loading.

Apply this diff to fix:

-''',
+""",
🧹 Nitpick comments (5)
connector_builder_mcp/build_strategies/kotlin_destination/prompts.py (1)

20-101: Prompt definition is clear; verify prompt registration isn’t duplicated across strategies

The new_kotlin_destination_connector_prompt signature and content look good: parameters are well-documented via Field, defaults are handled safely, and the returned structure matches the MCP prompt expectations.

One thing to double‑check: register_prompts() calls register_mcp_prompts(app, domain=ToolDomain.PROMPTS), which iterates over all globally registered PROMPTS‑domain prompts. If other strategy modules (e.g., the OpenAPI prompts module) also call register_mcp_prompts for the same domain, the same prompts may be registered multiple times against the FastMCP app. Please confirm that either:

  • each domain is registered only once at the server level, or
  • register_mcp_prompts/app.prompt are idempotent with respect to prompt names.

If not, you may want to centralize PROMPTS registration or adjust these register_prompts methods to avoid duplicate registrations.

connector_builder_mcp/build_strategies/declarative_openapi_v3/prompts.py (1)

20-101: OpenAPI prompt wiring is good; ensure PROMPTS registration pattern is intentional

The new_openapi_connector_prompt API and content look consistent with the rest of the OpenAPI strategy (checklist + validation tooling), and the return shape matches the MCP prompt expectations.

As with the Kotlin destination prompts, register_prompts() delegates to register_mcp_prompts(app, domain=ToolDomain.PROMPTS), which operates over all globally registered PROMPTS‑domain prompts. If multiple modules/strategies each call this helper for the same domain, the same prompt names may be registered more than once. It would be good to confirm that:

  • PROMPTS registration is only invoked once per app, or
  • the underlying registration is idempotent with respect to prompt names.

If not, consider centralizing PROMPTS registration (e.g., in server.py) rather than per‑strategy, or introducing a guard to prevent duplicate registration.

connector_builder_mcp/build_strategies/declarative_openapi_v3/build_strategy.py (1)

31-37: Track the placeholder is_available() implementation.

The docstring mentions checking for connector-sdk availability, but the implementation always returns True. Consider adding a TODO or tracking issue for proper dependency detection.

Example implementation checking for connector-sdk modules:

 @classmethod
 def is_available(cls) -> bool:
     """Check if connector-sdk is available.

     Returns True if connector-sdk related modules are in sys.modules.
     """
-    return True  # For now, always available
+    import sys
+    # Check for connector-sdk or related modules
+    return any(
+        module_name.startswith("airbyte_cdk") 
+        for module_name in sys.modules.keys()
+    )
connector_builder_mcp/build_strategies/kotlin_source/build_strategy.py (1)

33-53: Improve Java version detection and extract duplicated code.

Two concerns:

  1. False positives: The check "21" in version_output could match unintended versions like "121" or version strings containing "21" in other contexts.

  2. Code duplication: This exact implementation appears in both KotlinSourceStrategy and KotlinDestinationStrategy.

Consider using a more precise regex pattern and extracting to a shared utility:

Create a shared utility in connector_builder_mcp/build_strategies/base/java_utils.py:

import re
import shutil
import subprocess

def is_java_21_available() -> bool:
    """Check if Java 21 is available.
    
    Returns True if Java 21 is installed and available.
    """
    java_path = shutil.which("java")
    if not java_path:
        return False

    try:
        result = subprocess.run(
            ["java", "-version"],
            capture_output=True,
            text=True,
            timeout=5,
        )
        version_output = result.stderr + result.stdout
        # Match version patterns like "21.0.x", "openjdk version \"21", etc.
        pattern = r'(openjdk\s+)?version\s+"?21\.'
        return bool(re.search(pattern, version_output, re.IGNORECASE))
    except (subprocess.TimeoutExpired, subprocess.SubprocessError):
        return False

Then update both strategies:

+from connector_builder_mcp.build_strategies.base.java_utils import is_java_21_available

 @classmethod
 def is_available(cls) -> bool:
     """Check if Java 21 is available.

     Returns True if Java 21 is installed and available.
     """
-    java_path = shutil.which("java")
-    if not java_path:
-        return False
-
-    try:
-        result = subprocess.run(
-            ["java", "-version"],
-            capture_output=True,
-            text=True,
-            timeout=5,
-        )
-        version_output = result.stderr + result.stdout
-        return "21" in version_output or "openjdk 21" in version_output.lower()
-    except (subprocess.TimeoutExpired, subprocess.SubprocessError):
-        return False
+    return is_java_21_available()
connector_builder_mcp/build_strategies/kotlin_source/manifest_tests.py (1)

31-89: Track placeholder implementation.

The function correctly validates inputs but returns a placeholder success result without actually testing the connector. This is noted in the PR description but should be tracked for future implementation.

Do you want me to open a tracking issue for implementing the actual Kotlin source stream testing logic?

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6324c5f and 7688d5b.

📒 Files selected for processing (22)
  • connector_builder_mcp/build_strategies/declarative_openapi_v3/__init__.py (1 hunks)
  • connector_builder_mcp/build_strategies/declarative_openapi_v3/build_strategy.py (1 hunks)
  • connector_builder_mcp/build_strategies/declarative_openapi_v3/checklist.yaml (1 hunks)
  • connector_builder_mcp/build_strategies/declarative_openapi_v3/guidance.py (1 hunks)
  • connector_builder_mcp/build_strategies/declarative_openapi_v3/manifest_checks.py (1 hunks)
  • connector_builder_mcp/build_strategies/declarative_openapi_v3/manifest_tests.py (1 hunks)
  • connector_builder_mcp/build_strategies/declarative_openapi_v3/prompts.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_destination/__init__.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_destination/build_strategy.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_destination/checklist.yaml (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_destination/guidance.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_destination/manifest_checks.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_destination/manifest_tests.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_destination/prompts.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_source/__init__.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_source/build_strategy.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_source/checklist.yaml (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_source/guidance.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_source/manifest_checks.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_source/manifest_tests.py (1 hunks)
  • connector_builder_mcp/build_strategies/kotlin_source/prompts.py (1 hunks)
  • connector_builder_mcp/server.py (4 hunks)
✅ Files skipped from review due to trivial changes (3)
  • connector_builder_mcp/build_strategies/kotlin_destination/init.py
  • connector_builder_mcp/build_strategies/declarative_openapi_v3/init.py
  • connector_builder_mcp/build_strategies/kotlin_source/init.py
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: aaronsteers
Repo: airbytehq/connector-builder-mcp PR: 116
File: .github/workflows/ci-tests.yml:110-113
Timestamp: 2025-10-10T17:09:02.151Z
Learning: The connector-builder-mcp repository (airbytehq/connector-builder-mcp) is an internal/private repository that doesn't accept external contributions, so there are no forked PRs to consider in workflow configurations.
📚 Learning: 2025-10-11T02:19:05.231Z
Learnt from: aaronsteers
Repo: airbytehq/connector-builder-mcp PR: 136
File: connector_builder_agents/src/evals/evaluators.py:233-245
Timestamp: 2025-10-11T02:19:05.231Z
Learning: In the connector-builder-mcp repository Python files, all imports must be placed at the module level (top of the file), never inside functions or methods. This is a recurring issue that should be flagged during code reviews.

Applied to files:

  • connector_builder_mcp/build_strategies/declarative_openapi_v3/prompts.py
📚 Learning: 2025-11-08T06:53:26.977Z
Learnt from: aaronsteers
Repo: airbytehq/connector-builder-mcp PR: 176
File: connector_builder_mcp/_manifest_history_utils.py:38-49
Timestamp: 2025-11-08T06:53:26.977Z
Learning: In the connector-builder-mcp repository, all imports must be at the module level (top of the file). Inline imports inside functions or methods are not allowed unless explicit permission is granted. This rule must never be violated.

Applied to files:

  • connector_builder_mcp/build_strategies/declarative_openapi_v3/prompts.py
  • connector_builder_mcp/server.py
🧬 Code graph analysis (16)
connector_builder_mcp/build_strategies/kotlin_source/manifest_checks.py (2)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/kotlin_source/build_strategy.py (1)
  • register_manifest_check_tools (61-63)
connector_builder_mcp/build_strategies/kotlin_destination/guidance.py (6)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/declarative_openapi_v3/build_strategy.py (1)
  • register_guidance_tools (40-42)
connector_builder_mcp/build_strategies/declarative_openapi_v3/guidance.py (1)
  • register_guidance_tools (201-205)
connector_builder_mcp/build_strategies/kotlin_destination/build_strategy.py (1)
  • register_guidance_tools (56-58)
connector_builder_mcp/build_strategies/kotlin_source/build_strategy.py (1)
  • register_guidance_tools (56-58)
connector_builder_mcp/build_strategies/kotlin_source/guidance.py (1)
  • register_guidance_tools (307-311)
connector_builder_mcp/build_strategies/declarative_openapi_v3/build_strategy.py (5)
connector_builder_mcp/build_strategies/base/build_strategy.py (1)
  • BuildStrategy (18-185)
connector_builder_mcp/build_strategies/declarative_openapi_v3/guidance.py (1)
  • register_guidance_tools (201-205)
connector_builder_mcp/build_strategies/declarative_openapi_v3/manifest_checks.py (1)
  • register_manifest_check_tools (91-97)
connector_builder_mcp/build_strategies/declarative_openapi_v3/manifest_tests.py (1)
  • register_manifest_test_tools (94-100)
connector_builder_mcp/build_strategies/declarative_openapi_v3/prompts.py (1)
  • register_prompts (95-101)
connector_builder_mcp/build_strategies/kotlin_destination/manifest_checks.py (5)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/declarative_openapi_v3/build_strategy.py (1)
  • register_manifest_check_tools (45-47)
connector_builder_mcp/build_strategies/kotlin_destination/build_strategy.py (1)
  • register_manifest_check_tools (61-63)
connector_builder_mcp/build_strategies/kotlin_source/build_strategy.py (1)
  • register_manifest_check_tools (61-63)
connector_builder_mcp/build_strategies/kotlin_source/manifest_checks.py (1)
  • register_manifest_check_tools (76-82)
connector_builder_mcp/build_strategies/kotlin_source/prompts.py (2)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_prompt (152-182)
  • register_mcp_prompts (282-308)
connector_builder_mcp/build_strategies/kotlin_source/build_strategy.py (1)
  • register_prompts (71-73)
connector_builder_mcp/build_strategies/declarative_openapi_v3/prompts.py (2)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_prompt (152-182)
  • register_mcp_prompts (282-308)
connector_builder_mcp/build_strategies/declarative_openapi_v3/build_strategy.py (1)
  • register_prompts (55-57)
connector_builder_mcp/build_strategies/declarative_openapi_v3/manifest_checks.py (1)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/kotlin_source/build_strategy.py (3)
connector_builder_mcp/build_strategies/base/build_strategy.py (1)
  • BuildStrategy (18-185)
connector_builder_mcp/build_strategies/kotlin_destination/build_strategy.py (5)
  • is_available (34-53)
  • register_guidance_tools (56-58)
  • register_manifest_check_tools (61-63)
  • register_manifest_test_tools (66-68)
  • register_prompts (71-73)
connector_builder_mcp/build_strategies/kotlin_source/guidance.py (1)
  • register_guidance_tools (307-311)
connector_builder_mcp/build_strategies/kotlin_source/guidance.py (3)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/declarative_openapi_v3/build_strategy.py (1)
  • register_guidance_tools (40-42)
connector_builder_mcp/build_strategies/kotlin_source/build_strategy.py (1)
  • register_guidance_tools (56-58)
connector_builder_mcp/build_strategies/declarative_openapi_v3/guidance.py (6)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/declarative_openapi_v3/build_strategy.py (1)
  • register_guidance_tools (40-42)
connector_builder_mcp/build_strategies/kotlin_destination/build_strategy.py (1)
  • register_guidance_tools (56-58)
connector_builder_mcp/build_strategies/kotlin_destination/guidance.py (1)
  • register_guidance_tools (431-435)
connector_builder_mcp/build_strategies/kotlin_source/build_strategy.py (1)
  • register_guidance_tools (56-58)
connector_builder_mcp/build_strategies/kotlin_source/guidance.py (1)
  • register_guidance_tools (307-311)
connector_builder_mcp/build_strategies/kotlin_destination/prompts.py (2)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_prompt (152-182)
  • register_mcp_prompts (282-308)
connector_builder_mcp/build_strategies/kotlin_destination/build_strategy.py (1)
  • register_prompts (71-73)
connector_builder_mcp/server.py (5)
connector_builder_mcp/build_strategies/declarative_openapi_v3/build_strategy.py (2)
  • DeclarativeOpenApiV3Strategy (20-57)
  • is_available (32-37)
connector_builder_mcp/build_strategies/declarative_yaml_v1/build_strategy.py (2)
  • DeclarativeYamlV1Strategy (22-61)
  • is_available (35-41)
connector_builder_mcp/build_strategies/kotlin_destination/build_strategy.py (2)
  • KotlinDestinationStrategy (22-73)
  • is_available (34-53)
connector_builder_mcp/build_strategies/kotlin_source/build_strategy.py (2)
  • KotlinSourceStrategy (22-73)
  • is_available (34-53)
connector_builder_mcp/build_strategies/base/build_strategy.py (2)
  • is_available (52-61)
  • register_all_mcp_callables (107-120)
connector_builder_mcp/build_strategies/kotlin_destination/build_strategy.py (6)
connector_builder_mcp/build_strategies/base/build_strategy.py (1)
  • BuildStrategy (18-185)
connector_builder_mcp/build_strategies/kotlin_source/build_strategy.py (5)
  • is_available (34-53)
  • register_guidance_tools (56-58)
  • register_manifest_check_tools (61-63)
  • register_manifest_test_tools (66-68)
  • register_prompts (71-73)
connector_builder_mcp/build_strategies/kotlin_destination/guidance.py (1)
  • register_guidance_tools (431-435)
connector_builder_mcp/build_strategies/kotlin_destination/manifest_checks.py (1)
  • register_manifest_check_tools (76-82)
connector_builder_mcp/build_strategies/kotlin_destination/manifest_tests.py (1)
  • register_manifest_test_tools (95-101)
connector_builder_mcp/build_strategies/kotlin_destination/prompts.py (1)
  • register_prompts (93-99)
connector_builder_mcp/build_strategies/kotlin_destination/manifest_tests.py (2)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/kotlin_destination/build_strategy.py (1)
  • register_manifest_test_tools (66-68)
connector_builder_mcp/build_strategies/declarative_openapi_v3/manifest_tests.py (2)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/declarative_openapi_v3/build_strategy.py (1)
  • register_manifest_test_tools (50-52)
connector_builder_mcp/build_strategies/kotlin_source/manifest_tests.py (2)
connector_builder_mcp/mcp/_mcp_utils.py (3)
  • ToolDomain (49-80)
  • mcp_tool (102-149)
  • register_mcp_tools (246-279)
connector_builder_mcp/build_strategies/declarative_openapi_v3/manifest_tests.py (1)
  • register_manifest_test_tools (94-100)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Pytest (All, Python 3.11, Ubuntu)
  • GitHub Check: Pytest (All, Python 3.10, Ubuntu)
  • GitHub Check: Pytest (Fast)
🔇 Additional comments (16)
connector_builder_mcp/build_strategies/kotlin_destination/checklist.yaml (1)

1-138: Kotlin destination checklist content and structure look solid

The checklist is well-structured (phased tasks, explicit readiness and finalization steps) and consistent with the broader MCP workflows (checklists, readiness checks, secrets guidance). I don’t see structural or logical issues in this YAML as written.

connector_builder_mcp/build_strategies/declarative_openapi_v3/checklist.yaml (1)

1-153: Declarative OpenAPI v3 checklist is consistent and actionable

The task breakdown (spec discovery/validation, resource enumeration, auth, special requirements, readiness/finalization) aligns well with an OpenAPI-based workflow and mirrors patterns used in other strategies. No structural or semantic issues stand out in this YAML.

connector_builder_mcp/build_strategies/declarative_openapi_v3/manifest_tests.py (1)

85-91: LGTM: Placeholder implementation noted.

The placeholder implementation is acknowledged in the PR objectives and appropriately returns a success result with empty data. This provides a working tool signature that can be implemented fully in future PRs.

connector_builder_mcp/build_strategies/kotlin_destination/manifest_tests.py (1)

87-92: LGTM: Placeholder implementation with appropriate validation.

The tool correctly validates all required inputs before returning a placeholder success result. The implementation structure is ready for the full testing logic to be added in future PRs.

connector_builder_mcp/server.py (1)

65-78: LGTM: Clean multi-strategy registration.

The collection-driven approach cleanly handles multiple strategies with availability checking. The logging of unavailable strategies (line 78) is helpful for debugging environment issues (e.g., missing Java 21 for Kotlin strategies).

connector_builder_mcp/build_strategies/kotlin_source/checklist.yaml (1)

1-131: LGTM: Comprehensive checklist structure.

The checklist provides clear, phased guidance for Kotlin source connector development. The 📝 markers effectively indicate outputs to share with users, and the task flow logically progresses through the development lifecycle.

connector_builder_mcp/build_strategies/kotlin_destination/manifest_checks.py (1)

60-73: LGTM: Validation tool structure ready for implementation.

The placeholder warning (line 64) appropriately indicates the current state. The validation result model and tool signature provide a solid foundation for adding actual validation logic in future PRs.

connector_builder_mcp/build_strategies/kotlin_destination/guidance.py (1)

1-435: Approve structure once syntax errors are fixed.

The guidance tool structure and documentation content are well-organized and comprehensive. However, the two critical syntax errors (lines 310-358 and 359-422) must be fixed before this file can load successfully.

connector_builder_mcp/build_strategies/declarative_openapi_v3/guidance.py (1)

1-205: LGTM: Clean guidance tool implementation.

The documentation structure is clear and comprehensive. All triple-quote delimiters match correctly, avoiding the syntax issues seen in the Kotlin destination guidance module.

connector_builder_mcp/build_strategies/kotlin_source/manifest_checks.py (1)

1-82: LGTM: Consistent validation tool pattern.

The structure mirrors the Kotlin destination manifest checks module, maintaining consistency across strategies. The placeholder implementation is appropriately flagged with a warning message.

connector_builder_mcp/build_strategies/declarative_openapi_v3/build_strategy.py (1)

39-57: LGTM!

Registration methods correctly delegate to their respective modules and follow the BuildStrategy pattern.

connector_builder_mcp/build_strategies/kotlin_source/guidance.py (1)

19-304: LGTM!

The guidance tool is well-structured with comprehensive documentation covering all key aspects of Kotlin source connector development. The topic-based navigation and fallback for unknown topics are well-implemented.

connector_builder_mcp/build_strategies/kotlin_source/build_strategy.py (1)

55-73: LGTM!

Registration methods correctly delegate to their respective modules and follow the BuildStrategy pattern.

connector_builder_mcp/build_strategies/kotlin_source/prompts.py (1)

1-98: LGTM!

The prompts module is well-implemented with comprehensive guidance for building Kotlin source connectors. The parameter handling and registration are correct.

connector_builder_mcp/build_strategies/kotlin_source/manifest_tests.py (1)

19-28: LGTM!

The result model is well-structured with appropriate field types and descriptions.

connector_builder_mcp/build_strategies/kotlin_destination/build_strategy.py (1)

55-73: LGTM!

Registration methods correctly delegate to their respective kotlin_destination modules and follow the BuildStrategy pattern.

Comment on lines +33 to +53
@classmethod
def is_available(cls) -> bool:
"""Check if Java 21 is available.

Returns True if Java 21 is installed and available.
"""
java_path = shutil.which("java")
if not java_path:
return False

try:
result = subprocess.run(
["java", "-version"],
capture_output=True,
text=True,
timeout=5,
)
version_output = result.stderr + result.stdout
return "21" in version_output or "openjdk 21" in version_output.lower()
except (subprocess.TimeoutExpired, subprocess.SubprocessError):
return False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Duplicate implementation - see KotlinSourceStrategy.

This is_available() method is identical to the one in kotlin_source/build_strategy.py (lines 33-53). Both the false positive risk in Java version detection and the code duplication issue were flagged in that file's review. Please apply the same refactoring to extract this into a shared utility.

@aaronsteers aaronsteers merged commit a157451 into main Nov 19, 2025
16 checks passed
@aaronsteers aaronsteers deleted the devin/1763589811-add-build-strategy-submodules branch November 19, 2025 23:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants