Skip to content

fix: derive execute() input/output types from schemas in tool template#428

Open
frontegg-david wants to merge 1 commit into
mainfrom
fix/405-create-tool-inferred-types
Open

fix: derive execute() input/output types from schemas in tool template#428
frontegg-david wants to merge 1 commit into
mainfrom
fix/405-create-tool-inferred-types

Conversation

@frontegg-david
Copy link
Copy Markdown
Contributor

@frontegg-david frontegg-david commented May 17, 2026

Summary by CodeRabbit

  • New Features

    • Tool input/output types are now automatically derived from schemas using schema validators instead of manual type annotations.
    • Improved schema-first development pattern with standardized folder-per-tool organization.
  • Documentation

    • Updated guides and examples demonstrating schema-driven type derivation for tool development.
    • Enhanced documentation with file organization best practices and common tool patterns.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 17, 2026

📝 Walkthrough

Walkthrough

The PR standardizes FrontMCP tool class design by hoisting inputSchema and outputSchema to module scope and deriving TypeScript input/output types using ToolInputOf<> and ToolOutputOf<> utility types. The generator template, tests, examples, and reference documentation are updated to consistently apply this pattern.

Changes

Schema-Derived Typing Pattern Implementation

Layer / File(s) Summary
Generator Template and Test
libs/nx-plugin/src/generators/tool/files/__fileName__.tool.ts__tmpl__, libs/nx-plugin/src/generators/tool/tool.spec.ts
The tool template now hoists inputSchema/outputSchema constants and exports derived ToolInputOf<> and ToolOutputOf<> type aliases. The execute() method signature uses these generated types with an explicit Promise return type. A new generator test (issue #405) validates that the template correctly emits schema-derived types and removes legacy inline execute input-shape annotations.
Example Documentation
libs/skills/catalog/frontmcp-development/examples/create-tool/basic-class-tool.md, tool-with-di-and-errors.md, tool-with-rate-limiting-and-progress.md
Three examples are refactored to demonstrate the schema-derived pattern. The basic example shows co-located schema and tool files with ToolInputOf<>/ToolOutputOf<> imports. The DI example adds folder-per-tool organization with a dedicated schema module and barrel exports. The rate-limiting example adds explicit schema snippets and updates execute() signatures to use derived types.
Reference Documentation
libs/skills/catalog/frontmcp-development/references/create-tool.md
The create-tool reference is restructured to standardize schema-driven typing: class-based examples now hoist schemas and derive execute() types, a new "File layout" section describes flat-sibling vs folder-per-tool structures with barrel export patterns, and a "Derive `execute()` types" section details the pattern with equivalent typing forms. The common patterns table and examples listing are updated to align with the new guidance.
Skills Manifest Metadata
libs/skills/catalog/skills-manifest.json
The skill catalog entry for create-tool is updated to reflect schema-derived typing, emphasizing ToolInputOf<>/ToolOutputOf<> usage and updated file organization for all three class-based tool examples.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related issues

Poem

🐰 With schemas hoisted high and types derived below,
The tools now speak in harmony—no duplication's woe!
From template down through examples bright,
Each pattern gleams with consistent light. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: hoisting schemas to top-level and deriving execute() types via ToolInputOf/ToolOutputOf in the tool template, which is the core change across all files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/405-create-tool-inferred-types

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

Copy link
Copy Markdown
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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
libs/skills/catalog/frontmcp-development/examples/create-tool/tool-with-rate-limiting-and-progress.md (1)

88-96: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Import BatchProcessTool in the app snippet.

The snippet references BatchProcessTool but does not import it.

Suggested fix
 // src/apps/main/index.ts
 import { App } from '`@frontmcp/sdk`';
+import { BatchProcessTool } from './tools/batch-process.tool';
 
 `@App`({
   name: 'main',
   tools: [BatchProcessTool],
 })
 class MainApp {}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@libs/skills/catalog/frontmcp-development/examples/create-tool/tool-with-rate-limiting-and-progress.md`
around lines 88 - 96, The snippet uses BatchProcessTool in the App decorator but
never imports it; add an import for BatchProcessTool at the top of the file
(before the `@App` usage), referencing the module that exports it (the example's
BatchProcessTool module or package) and ensure the exported symbol name matches
(BatchProcessTool) so MainApp can compile.
libs/skills/catalog/frontmcp-development/examples/create-tool/basic-class-tool.md (1)

59-66: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add missing GreetUserTool import in app snippet.

tools: [GreetUserTool] is referenced without an import, so the example is not copy-paste runnable.

Suggested fix
 // src/apps/main/index.ts
 import { App } from '`@frontmcp/sdk`';
+import { GreetUserTool } from './tools/greet-user.tool';
 
 `@App`({
   name: 'main',
   tools: [GreetUserTool],
 })
 class MainApp {}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@libs/skills/catalog/frontmcp-development/examples/create-tool/basic-class-tool.md`
around lines 59 - 66, The example snippet references GreetUserTool but does not
import it; update the top of the snippet (where imports are declared) to add an
import for GreetUserTool so the code is runnable—e.g., import GreetUserTool from
its module alongside the existing App import—ensuring the symbols GreetUserTool,
App, and MainApp are all resolved.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@libs/skills/catalog/frontmcp-development/examples/create-tool/tool-with-di-and-errors.md`:
- Around line 22-30: The unlabeled fenced code block showing the project tree
triggers MD040; update the triple-backtick fence in
libs/skills/catalog/frontmcp-development/examples/create-tool/tool-with-di-and-errors.md
to include a language tag (e.g., ```text) so the file-tree block is labeled,
preserving the exact contents between the backticks; this will satisfy the
linter without changing the displayed tree.

In `@libs/skills/catalog/frontmcp-development/references/create-tool.md`:
- Around line 106-111: The markdown examples in create-tool.md are missing
language tags on their directory-tree code fences (triggering MD040); update
both code fences (the block shown at lines ~106-111 and the similar block at
~115-123) to include a language tag such as "text" (e.g., change ``` to ```text)
and apply the suggested content updates (use the alternative expanded tree
sample) so the fenced blocks are properly labeled and the examples match the
repo style.

---

Outside diff comments:
In
`@libs/skills/catalog/frontmcp-development/examples/create-tool/basic-class-tool.md`:
- Around line 59-66: The example snippet references GreetUserTool but does not
import it; update the top of the snippet (where imports are declared) to add an
import for GreetUserTool so the code is runnable—e.g., import GreetUserTool from
its module alongside the existing App import—ensuring the symbols GreetUserTool,
App, and MainApp are all resolved.

In
`@libs/skills/catalog/frontmcp-development/examples/create-tool/tool-with-rate-limiting-and-progress.md`:
- Around line 88-96: The snippet uses BatchProcessTool in the App decorator but
never imports it; add an import for BatchProcessTool at the top of the file
(before the `@App` usage), referencing the module that exports it (the example's
BatchProcessTool module or package) and ensure the exported symbol name matches
(BatchProcessTool) so MainApp can compile.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6099cd94-13c8-455f-a809-131c37e20ad0

📥 Commits

Reviewing files that changed from the base of the PR and between 4328981 and a14639f.

📒 Files selected for processing (7)
  • libs/nx-plugin/src/generators/tool/files/__fileName__.tool.ts__tmpl__
  • libs/nx-plugin/src/generators/tool/tool.spec.ts
  • libs/skills/catalog/frontmcp-development/examples/create-tool/basic-class-tool.md
  • libs/skills/catalog/frontmcp-development/examples/create-tool/tool-with-di-and-errors.md
  • libs/skills/catalog/frontmcp-development/examples/create-tool/tool-with-rate-limiting-and-progress.md
  • libs/skills/catalog/frontmcp-development/references/create-tool.md
  • libs/skills/catalog/skills-manifest.json

Comment on lines +22 to +30
```
src/apps/main/
├── tokens.ts # shared DI tokens
└── tools/
└── delete-record/
├── delete-record.schema.ts # input/output schemas + derived types
├── delete-record.tool.ts # @Tool class, execute()
└── index.ts # barrel re-export
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a language tag to the file-tree code fence.

This fence is unlabeled and triggers MD040 (fenced-code-language).

Suggested fix
-```
+```text
 src/apps/main/
 ├── tokens.ts                              # shared DI tokens
 └── tools/
     └── delete-record/
         ├── delete-record.schema.ts        # input/output schemas + derived types
         ├── delete-record.tool.ts          # `@Tool` class, execute()
         └── index.ts                       # barrel re-export
</details>

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.22.1)</summary>

[warning] 22-22: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
@libs/skills/catalog/frontmcp-development/examples/create-tool/tool-with-di-and-errors.md
around lines 22 - 30, The unlabeled fenced code block showing the project tree
triggers MD040; update the triple-backtick fence in
libs/skills/catalog/frontmcp-development/examples/create-tool/tool-with-di-and-errors.md
to include a language tag (e.g., ```text) so the file-tree block is labeled,
preserving the exact contents between the backticks; this will satisfy the
linter without changing the displayed tree.


</details>

<!-- fingerprinting:phantom:triton:hawk -->

<!-- This is an auto-generated comment by CodeRabbit -->

Comment on lines +106 to +111
```
src/apps/<app>/tools/
├── get-weather.tool.ts # @Tool class, execute()
├── get-weather.schema.ts # input/output schemas + derived types
└── get-weather.tool.spec.ts # unit tests
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Label both directory-tree code fences to satisfy markdownlint.

Both fences are missing a language tag and trigger MD040.

Suggested fix
-```
+```text
 src/apps/<app>/tools/
 ├── get-weather.tool.ts        # `@Tool` class, execute()
 ├── get-weather.schema.ts      # input/output schemas + derived types
 └── get-weather.tool.spec.ts   # unit tests

- +text
src/apps//tools/
└── get-weather/
├── get-weather.tool.ts # @Tool class, execute()
├── get-weather.schema.ts # input/output schemas + derived types
├── get-weather.tool.spec.ts # unit tests
├── index.ts # barrel re-export
└── … # tool-local helpers, fixtures, error types

Also applies to: 115-123

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 106-106: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libs/skills/catalog/frontmcp-development/references/create-tool.md` around
lines 106 - 111, The markdown examples in create-tool.md are missing language
tags on their directory-tree code fences (triggering MD040); update both code
fences (the block shown at lines ~106-111 and the similar block at ~115-123) to
include a language tag such as "text" (e.g., change ``` to ```text) and apply
the suggested content updates (use the alternative expanded tree sample) so the
fenced blocks are properly labeled and the examples match the repo style.

@github-actions
Copy link
Copy Markdown
Contributor

Performance Test Results

Status: ✅ All tests passed

Summary

Project Tests Passed Warnings Failed Leaks
✅ demo-e2e-agents 4 4 0 0 0
✅ demo-e2e-cache 11 11 0 0 0
✅ demo-e2e-codecall 4 4 0 0 0
✅ demo-e2e-config 4 4 0 0 0
✅ demo-e2e-direct 3 3 0 0 0
✅ demo-e2e-elicitation 1 1 0 0 0
✅ demo-e2e-errors 4 4 0 0 0
✅ demo-e2e-hooks 3 3 0 0 0
✅ demo-e2e-multiapp 4 4 0 0 0
✅ demo-e2e-notifications 3 3 0 0 0
✅ demo-e2e-openapi 2 2 0 0 0
✅ demo-e2e-providers 4 4 0 0 0
✅ demo-e2e-public 4 4 0 0 0
✅ demo-e2e-redis 15 15 0 0 0
✅ demo-e2e-remember 4 4 0 0 0
✅ demo-e2e-remote 5 5 0 0 0
✅ demo-e2e-serverless 2 2 0 0 0
✅ demo-e2e-skills 15 15 0 0 0
✅ demo-e2e-standalone 2 2 0 0 0
✅ demo-e2e-transport-recreation 3 3 0 0 0
✅ demo-e2e-ui 4 4 0 0 0

Total: 101 tests across 21 projects

📊 View full report in workflow run


Generated at: 2026-05-17T09:18:18.017Z
Commit: 14e92f80

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

create-tool skill: recommend deriving execute() types from schemas + folder-per-tool layout

1 participant