Skip to content

Conversation

@frontegg-david
Copy link
Contributor

@frontegg-david frontegg-david commented Jan 11, 2026

Summary by CodeRabbit

  • New Features

    • Tools now expose raw output schemas in metadata and metadata propagation to tool listings improved.
    • New OpenAPI spec utilities to modify security and spec shapes; OpenAPI tools publish wrapped output schema info.
    • New standardized OpenAPI response shape exposed for consumers.
  • Bug Fixes

    • API responses now return structured result objects (status, ok, data, error) instead of throwing.
  • Tests

    • Updated unit tests and added extensive OpenAPI adapter integration tests covering many response/content scenarios.
  • Chores

    • Removed pre-version release hook from configuration.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 11, 2026

📝 Walkthrough

Walkthrough

OpenAPI response handling now returns structured OpenApiResponse objects (status/ok/data/error) instead of throwing; tools expose a rawOutputSchema and wrap outputs accordingly; new non-mutating OpenAPI spec utilities were added; extensive unit and integration tests validate these behaviors.

Changes

Cohort / File(s) Summary
OpenAPI response parsing & tool behavior
libs/adapters/src/openapi/openapi.utils.ts, libs/adapters/src/openapi/openapi.tool.ts
Added OpenApiResponse and changed parseResponse to return { status, ok, data, error } (no longer throwing); tool wraps outputs into a status/ok/data/error shape and exposes rawOutputSchema in tool metadata.
Spec utilities & exports
libs/adapters/src/openapi/openapi.spec-utils.ts, libs/adapters/src/openapi/index.ts
New non-mutating helpers: deepClone, forceJwtSecurity, removeSecurityFromOperations, plus types for OpenAPI docs/security; re-exported spec-utils and OpenApiResponse from index.
Tests — unit & edge cases
libs/adapters/src/openapi/__tests__/openapi-utils.spec.ts, libs/adapters/src/openapi/__tests__/openapi-edge-cases.spec.ts
Updated tests to expect structured OpenApiResponse shapes for JSON/text/invalid JSON and various HTTP statuses instead of thrown exceptions.
Integration tests / server
libs/adapters/src/openapi/__tests__/openapi-server.spec.ts
New in-process HTTP server tests with dynamic OpenAPI spec generation validating request/response flows, parsing across content-types, error metadata, and propagation of rawOutputSchema and wrapped responses.
SDK metadata & tokens
libs/sdk/src/common/metadata/tool.metadata.ts, libs/sdk/src/common/tokens/tool.tokens.ts
Added optional rawOutputSchema?: JsonSchema to ToolMetadata and FrontMcpToolTokens to include raw JSON Schema in serialized metadata.
Tool entries / instances / flows
libs/sdk/src/common/entries/tool.entry.ts, libs/sdk/src/tool/tool.instance.ts, libs/sdk/src/tool/flows/tools-list.flow.ts
Added rawOutputSchema property and getRawOutputSchema() on ToolEntry; ToolInstance reads rawOutputSchema from metadata; ToolsListFlow populates tool item outputSchema from getRawOutputSchema() when present.
Repository config
nx.json
Removed release pre-version hook (version.preVersionCommand).
CI comment behavior
.github/workflows/pr-testing-registry.yml
Switches PR registry comments to marker-based upsert (update existing comment or create new) for start/stop registry messages.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Adapter as OpenAPI Adapter
  participant Server as HTTP Server
  participant Tooling as Tool Metadata / MCP

  Client->>Adapter: invoke generated tool / make request
  Adapter->>Server: send HTTP request (method, path, body, headers)
  Server-->>Adapter: respond (status, headers, body)
  Adapter->>Adapter: parseResponse -> OpenApiResponse { status, ok, data, error }
  alt response.ok == false
    Adapter->>Tooling: produce MCP-compatible error payload (text + _meta with status/errorCode)
    Adapter-->>Client: return structured error payload
  else response.ok == true
    Adapter->>Tooling: attach rawOutputSchema and wrapped response metadata
    Adapter-->>Client: return { status, ok: true, data }
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • chore: sdk enhancements #177 — Modifies SDK tool metadata and tooling to expose tool output schemas; closely related to rawOutputSchema propagation changes.
  • feat(libs): New lib mcp-from-openapi  #54 — Integrates OpenAPI tooling and spec-driven generation; likely connected to new spec utilities and test scaffolding.
  • v0.4.0 #58 — Changes OpenAPI adapter response semantics and metadata exposure; overlaps with parseResponse/OpenApiResponse work.

Poem

🐰 I hopped through specs and parsing trees,
Wrapped responses tidy, no more thrown pleas,
Schemas laid bare, errors neatly signed,
Tests patter softly — all flows aligned,
A little rabbit cheers: build and breeze.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: enhancing OpenAPI response handling with structured error format and adding integration tests, which aligns with the substantial changes across multiple OpenAPI adapter files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 65.00%.

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


📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 54d1389 and ccb73ea.

📒 Files selected for processing (1)
  • .github/workflows/pr-testing-registry.yml
⏰ 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). (4)
  • GitHub Check: Lint & Format Checks
  • GitHub Check: Build Libraries
  • GitHub Check: Package E2E (Verdaccio)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (2)
.github/workflows/pr-testing-registry.yml (2)

391-446: Good improvement with marker-based upsert pattern.

The switch from always creating comments to finding and updating existing ones reduces noise on PRs. The implementation is clean and follows a standard pattern.

Minor consideration: listComments returns a maximum of 100 comments per page by default. For PRs with very long comment threads, the marker-based comment might not be found. This is unlikely for typical usage, but you could add pagination or increase per_page for robustness.

Optional: Add pagination safety
             // Find existing comment with our marker
             const { data: comments } = await github.rest.issues.listComments({
               owner: context.repo.owner,
               repo: context.repo.repo,
               issue_number: ${{ inputs.pr_number }},
+              per_page: 100,
             });

For full robustness, consider using github.paginate() to handle PRs with 100+ comments, though this is an edge case.


641-684: Consistent implementation for the stopped state.

Using the same marker as the start comment ensures the original "registry available" comment gets updated to show "registry stopped" rather than creating a duplicate. This provides a clean user experience where users always see the current state in a single comment.

The if: always() condition correctly ensures this runs even when the workflow is cancelled.


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

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

🤖 Fix all issues with AI agents
In @libs/sdk/src/tool/flows/tools-list.flow.ts:
- Around line 296-300: The call to getRawOutputSchema uses optional chaining but
the method is guaranteed by the resolvedTools z.instanceof(ToolEntry)
validation, so remove the optional chaining on the invocation; change the usage
to call tool.getRawOutputSchema() and keep the conditional only on its return
(outputSchemaRaw) before assigning to item.outputSchema, referencing the
getRawOutputSchema method on ToolEntry and the outputSchemaRaw/item.outputSchema
variables in the tools-list.flow.
🧹 Nitpick comments (5)
libs/adapters/src/openapi/openapi.utils.ts (1)

271-290: Consider edge case for empty error responses.

The error message derivation handles data.message, string data, and falls back to HTTP ${status} error. However, if data is an empty object {} or null, the fallback correctly triggers.

One minor observation: when data is an empty string "", it will be used as the error message (falsy but still a string type), which may not be ideal.

♻️ Optional: Handle empty string case
       error:
         typeof data === 'object' && data !== null && 'message' in data
           ? String((data as { message: unknown }).message)
-          : typeof data === 'string'
+          : typeof data === 'string' && data.length > 0
           ? data
           : `HTTP ${response.status} error`,
libs/adapters/src/openapi/openapi.spec-utils.ts (1)

49-54: Use structuredClone for more robust deep cloning.

The project requires Node.js >=22.0.0, which fully supports structuredClone (available since Node.js 17.0.0). While JSON.parse(JSON.stringify()) works for typical OpenAPI specs, structuredClone is more robust and handles edge cases like circular references or uncommon types that might appear in vendor extensions.

♻️ Refactor to structuredClone
 function deepClone<T>(obj: T): T {
-  return JSON.parse(JSON.stringify(obj));
+  return structuredClone(obj);
 }
libs/sdk/src/common/entries/tool.entry.ts (1)

58-76: Consider using a stricter type than any for rawOutputSchema.

The rawOutputSchema property and getRawOutputSchema() method use any type. While this follows the pattern of rawInputSchema on line 55, the coding guidelines prefer avoiding any types. Consider using unknown or importing the JSONSchema type from zod/v4/core as done in libs/adapters/src/openapi/openapi.tool.ts (line 11-14).

💡 Suggested improvement
+import type { JSONSchema } from 'zod/v4/core';
+
+/** JSON Schema type from Zod v4 */
+type JsonSchema = JSONSchema.JSONSchema;

 // Raw JSON Schema for output (for tool/list to expose)
-rawOutputSchema?: any;
+rawOutputSchema?: JsonSchema;

 /**
  * Accessor used by tools/list to expose the tool's output schema as JSON Schema.
  * Returns the raw JSON Schema representation if available.
  */
-getRawOutputSchema(): any | undefined {
+getRawOutputSchema(): JsonSchema | undefined {
   return this.rawOutputSchema;
 }
libs/adapters/src/openapi/__tests__/openapi-server.spec.ts (2)

373-399: Async route handler may cause issues with type consistency.

The POST /users handler (line 375) is declared async while other handlers are synchronous. The RouteHandler type (line 17) doesn't account for async handlers returning Promise<void>. While this works at runtime, the type mismatch could cause issues.

💡 Update RouteHandler type to support async
-type RouteHandler = (req: http.IncomingMessage, res: http.ServerResponse, params: Record<string, string>) => void;
+type RouteHandler = (req: http.IncomingMessage, res: http.ServerResponse, params: Record<string, string>) => void | Promise<void>;

482-495: Consider adding type annotations instead of any in test helper.

The toolFn parameter and return types use any. While acceptable in tests, adding minimal type information improves maintainability.

💡 Add basic type annotations
-  return (result.tools || []).map((toolFn: any) => {
-    const metadata = toolFn[FrontMcpToolTokens.metadata] || {};
+  return (result.tools || []).map((toolFn: unknown) => {
+    const fn = toolFn as Record<symbol | string, unknown>;
+    const metadata = (fn[FrontMcpToolTokens.metadata] as Record<string, unknown>) || {};
     return {
-      name: metadata.name || metadata.id,
+      name: (metadata.name || metadata.id) as string,
       metadata,
       // The tool function itself is the executor
-      executor: async (input: any, ctx: any) => {
-        return toolFn()(input, { context: ctx });
+      executor: async (input: Record<string, unknown>, ctx: Record<string, unknown>) => {
+        return (fn as () => (input: unknown, ctx: unknown) => unknown)()(input, { context: ctx });
       },
     };
   });
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0e981ac and 431b647.

📒 Files selected for processing (12)
  • libs/adapters/src/openapi/__tests__/openapi-edge-cases.spec.ts
  • libs/adapters/src/openapi/__tests__/openapi-server.spec.ts
  • libs/adapters/src/openapi/__tests__/openapi-utils.spec.ts
  • libs/adapters/src/openapi/index.ts
  • libs/adapters/src/openapi/openapi.spec-utils.ts
  • libs/adapters/src/openapi/openapi.tool.ts
  • libs/adapters/src/openapi/openapi.utils.ts
  • libs/sdk/src/common/entries/tool.entry.ts
  • libs/sdk/src/common/metadata/tool.metadata.ts
  • libs/sdk/src/common/tokens/tool.tokens.ts
  • libs/sdk/src/tool/flows/tools-list.flow.ts
  • libs/sdk/src/tool/tool.instance.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use strict TypeScript mode with no any types without strong justification
Avoid non-null assertions (!) - use proper error handling and type guards instead
Use @frontmcp/utils for cryptographic operations instead of node:crypto directly
Use @frontmcp/utils for file system operations instead of fs/promises or node:fs directly

Files:

  • libs/sdk/src/common/entries/tool.entry.ts
  • libs/sdk/src/common/tokens/tool.tokens.ts
  • libs/sdk/src/tool/flows/tools-list.flow.ts
  • libs/adapters/src/openapi/__tests__/openapi-edge-cases.spec.ts
  • libs/adapters/src/openapi/openapi.utils.ts
  • libs/adapters/src/openapi/openapi.tool.ts
  • libs/adapters/src/openapi/__tests__/openapi-server.spec.ts
  • libs/adapters/src/openapi/openapi.spec-utils.ts
  • libs/adapters/src/openapi/index.ts
  • libs/adapters/src/openapi/__tests__/openapi-utils.spec.ts
  • libs/sdk/src/common/metadata/tool.metadata.ts
  • libs/sdk/src/tool/tool.instance.ts
libs/{sdk,adapters}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

libs/{sdk,adapters}/**/*.{ts,tsx}: Use specific error classes with MCP error codes instead of generic errors
Use getCapabilities() for dynamic capability exposure instead of hardcoding capabilities

Files:

  • libs/sdk/src/common/entries/tool.entry.ts
  • libs/sdk/src/common/tokens/tool.tokens.ts
  • libs/sdk/src/tool/flows/tools-list.flow.ts
  • libs/adapters/src/openapi/__tests__/openapi-edge-cases.spec.ts
  • libs/adapters/src/openapi/openapi.utils.ts
  • libs/adapters/src/openapi/openapi.tool.ts
  • libs/adapters/src/openapi/__tests__/openapi-server.spec.ts
  • libs/adapters/src/openapi/openapi.spec-utils.ts
  • libs/adapters/src/openapi/index.ts
  • libs/adapters/src/openapi/__tests__/openapi-utils.spec.ts
  • libs/sdk/src/common/metadata/tool.metadata.ts
  • libs/sdk/src/tool/tool.instance.ts
libs/sdk/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

libs/sdk/**/*.{ts,tsx}: Prefer interface for defining object shapes in TypeScript, avoid any types
Use type parameters with constraints instead of unconstrained generics with any defaults
Validate URIs per RFC 3986 at metadata level using isValidMcpUri refinement
Use changeScope instead of scope in change event properties to avoid confusion with Scope class
Fail fast on invalid hook flows by validating hooks match their entry type
Centralize record types in common/records and import from there, not from module-specific files
Return strictly typed MCP protocol responses (e.g., Promise<GetPromptResult>) instead of Promise<unknown> for MCP entry methods
Use unknown instead of any for generic type parameter defaults (not for MCP protocol types)
Create shared base classes for common functionality like ExecutionContextBase for ToolContext and ResourceContext
Do not mutate rawInput in flows - use state.set() for managing flow state instead
Validate inputs and outputs through parseOutput/safeParseOutput methods in validation flows

Files:

  • libs/sdk/src/common/entries/tool.entry.ts
  • libs/sdk/src/common/tokens/tool.tokens.ts
  • libs/sdk/src/tool/flows/tools-list.flow.ts
  • libs/sdk/src/common/metadata/tool.metadata.ts
  • libs/sdk/src/tool/tool.instance.ts
libs/**

⚙️ CodeRabbit configuration file

libs/**: Contains publishable SDK libraries. Review for API correctness, breaking changes, and consistency with docs. When public APIs change, ensure there is a matching docs/draft/docs/** update (not direct edits under docs/docs/**).

Files:

  • libs/sdk/src/common/entries/tool.entry.ts
  • libs/sdk/src/common/tokens/tool.tokens.ts
  • libs/sdk/src/tool/flows/tools-list.flow.ts
  • libs/adapters/src/openapi/__tests__/openapi-edge-cases.spec.ts
  • libs/adapters/src/openapi/openapi.utils.ts
  • libs/adapters/src/openapi/openapi.tool.ts
  • libs/adapters/src/openapi/__tests__/openapi-server.spec.ts
  • libs/adapters/src/openapi/openapi.spec-utils.ts
  • libs/adapters/src/openapi/index.ts
  • libs/adapters/src/openapi/__tests__/openapi-utils.spec.ts
  • libs/sdk/src/common/metadata/tool.metadata.ts
  • libs/sdk/src/tool/tool.instance.ts
🧠 Learnings (15)
📚 Learning: 2026-01-06T02:34:55.689Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/plugins/CLAUDE.md:0-0
Timestamp: 2026-01-06T02:34:55.689Z
Learning: Applies to libs/plugins/**/*.ts : Extend tool metadata using `declare global` pattern to allow tools to specify plugin-specific options in their decorators

Applied to files:

  • libs/sdk/src/common/entries/tool.entry.ts
  • libs/sdk/src/common/metadata/tool.metadata.ts
📚 Learning: 2026-01-06T17:16:04.304Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-06T17:16:04.304Z
Learning: Applies to libs/sdk/**/*.{ts,tsx} : Validate inputs and outputs through parseOutput/safeParseOutput methods in validation flows

Applied to files:

  • libs/sdk/src/tool/flows/tools-list.flow.ts
📚 Learning: 2026-01-06T17:16:04.304Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-06T17:16:04.304Z
Learning: Applies to libs/sdk/**/*.{ts,tsx} : Create shared base classes for common functionality like ExecutionContextBase for ToolContext and ResourceContext

Applied to files:

  • libs/sdk/src/tool/flows/tools-list.flow.ts
📚 Learning: 2026-01-06T17:16:04.304Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-06T17:16:04.304Z
Learning: Applies to libs/sdk/**/*.{ts,tsx} : Centralize record types in common/records and import from there, not from module-specific files

Applied to files:

  • libs/sdk/src/tool/flows/tools-list.flow.ts
  • libs/adapters/src/openapi/index.ts
📚 Learning: 2026-01-06T17:16:04.304Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-06T17:16:04.304Z
Learning: Applies to libs/sdk/**/*.{ts,tsx} : Return strictly typed MCP protocol responses (e.g., `Promise<GetPromptResult>`) instead of `Promise<unknown>` for MCP entry methods

Applied to files:

  • libs/sdk/src/tool/flows/tools-list.flow.ts
📚 Learning: 2025-12-24T00:41:41.819Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/ui/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:41.819Z
Learning: Applies to libs/ui/src/react/hooks/**/*.{ts,tsx} : MCP bridge hooks (useMcpBridge, useCallTool, useToolInput, useToolOutput, useTheme) must be properly typed and handle loading/error states

Applied to files:

  • libs/sdk/src/tool/flows/tools-list.flow.ts
📚 Learning: 2026-01-04T14:35:18.366Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/uipack/CLAUDE.md:0-0
Timestamp: 2026-01-04T14:35:18.366Z
Learning: Applies to libs/uipack/**/{theme,adapters,bundler}/**/*.{test,spec}.{ts,tsx,js,jsx} : Test behavior across all supported platform configurations (OpenAI, Claude, etc.)

Applied to files:

  • libs/adapters/src/openapi/__tests__/openapi-edge-cases.spec.ts
  • libs/adapters/src/openapi/__tests__/openapi-server.spec.ts
  • libs/adapters/src/openapi/__tests__/openapi-utils.spec.ts
📚 Learning: 2026-01-06T17:16:04.304Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-06T17:16:04.304Z
Learning: Applies to **/*.test.{ts,tsx} : Include `instanceof` checks in tests for error classes to verify proper error hierarchy

Applied to files:

  • libs/adapters/src/openapi/__tests__/openapi-edge-cases.spec.ts
  • libs/adapters/src/openapi/__tests__/openapi-utils.spec.ts
📚 Learning: 2026-01-06T17:16:04.304Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-06T17:16:04.304Z
Learning: Applies to libs/{sdk,adapters}/**/*.{ts,tsx} : Use specific error classes with MCP error codes instead of generic errors

Applied to files:

  • libs/adapters/src/openapi/__tests__/openapi-edge-cases.spec.ts
📚 Learning: 2026-01-04T14:35:18.366Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/uipack/CLAUDE.md:0-0
Timestamp: 2026-01-04T14:35:18.366Z
Learning: Applies to libs/uipack/**/*.{test,spec}.{ts,tsx,js,jsx} : Every component and utility must test invalid inputs and edge cases

Applied to files:

  • libs/adapters/src/openapi/__tests__/openapi-server.spec.ts
📚 Learning: 2026-01-06T17:16:04.304Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-06T17:16:04.304Z
Learning: Applies to **/*.{ts,tsx} : Use `frontmcp/utils` for cryptographic operations instead of `node:crypto` directly

Applied to files:

  • libs/adapters/src/openapi/openapi.spec-utils.ts
📚 Learning: 2026-01-04T14:35:18.366Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/uipack/CLAUDE.md:0-0
Timestamp: 2026-01-04T14:35:18.366Z
Learning: Applies to libs/uipack/**/index.{ts,js} : Export all public APIs through appropriate entry points (frontmcp/uipack, frontmcp/uipack/adapters, frontmcp/uipack/theme, etc.)

Applied to files:

  • libs/adapters/src/openapi/index.ts
📚 Learning: 2026-01-06T17:16:04.304Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-06T17:16:04.304Z
Learning: Applies to libs/*/src/index.ts : Export everything users need through barrel exports (index.ts), do not add backwards compatibility aliases

Applied to files:

  • libs/adapters/src/openapi/index.ts
📚 Learning: 2026-01-06T17:16:04.304Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-06T17:16:04.304Z
Learning: Applies to libs/{sdk,adapters}/**/*.{ts,tsx} : Use `getCapabilities()` for dynamic capability exposure instead of hardcoding capabilities

Applied to files:

  • libs/adapters/src/openapi/index.ts
📚 Learning: 2025-12-24T00:41:41.819Z
Learnt from: CR
Repo: agentfront/frontmcp PR: 0
File: libs/ui/CLAUDE.md:0-0
Timestamp: 2025-12-24T00:41:41.819Z
Learning: Applies to libs/ui/src/bundler/**/*.{ts,tsx} : The bundler module must re-export utilities from frontmcp/uipack/bundler and provide SSR component bundling functionality

Applied to files:

  • libs/adapters/src/openapi/index.ts
🧬 Code graph analysis (6)
libs/sdk/src/common/tokens/tool.tokens.ts (1)
libs/sdk/src/common/tokens/base.tokens.ts (1)
  • tokenFactory (9-9)
libs/adapters/src/openapi/__tests__/openapi-edge-cases.spec.ts (1)
libs/adapters/src/openapi/openapi.utils.ts (1)
  • parseResponse (227-291)
libs/adapters/src/openapi/openapi.utils.ts (1)
libs/adapters/src/openapi/index.ts (1)
  • OpenApiResponse (4-4)
libs/adapters/src/openapi/openapi.tool.ts (1)
libs/adapters/src/openapi/openapi.utils.ts (1)
  • parseResponse (227-291)
libs/adapters/src/openapi/__tests__/openapi-server.spec.ts (2)
libs/sdk/src/tool/tool.registry.ts (1)
  • getTools (259-263)
libs/sdk/src/common/tokens/tool.tokens.ts (1)
  • FrontMcpToolTokens (5-20)
libs/adapters/src/openapi/__tests__/openapi-utils.spec.ts (2)
libs/adapters/src/openapi/__tests__/fixtures.ts (2)
  • mockFetchSuccess (250-259)
  • mockFetchError (261-269)
libs/adapters/src/openapi/openapi.utils.ts (1)
  • parseResponse (227-291)
⏰ 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). (4)
  • GitHub Check: Build Libraries
  • GitHub Check: Lint & Format Checks
  • GitHub Check: Package E2E (Verdaccio)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (18)
libs/adapters/src/openapi/index.ts (1)

3-4: LGTM!

The barrel exports correctly expose the new public API surface (forceJwtSecurity, removeSecurityFromOperations, OpenApiResponse) while keeping internal utilities private. This follows the project convention for library exports.

libs/adapters/src/openapi/openapi.utils.ts (2)

204-217: LGTM!

The OpenApiResponse interface is well-designed for structured error handling. Using unknown for data follows the coding guidelines, and the optional error field provides clear semantics for non-ok responses.


227-253: No breaking change to addressparseResponse is an internal utility function, not exported as part of the public SDK API. The sole internal consumer (openapi.tool.ts) has been properly updated to handle the structured OpenApiResponse return type with status, ok, data, and error fields.

Likely an incorrect or invalid review comment.

libs/adapters/src/openapi/openapi.spec-utils.ts (3)

6-44: LGTM!

The ForceSecurityOptions interface is well-documented with clear defaults and supports the common authentication schemes. The optional operations filter provides good flexibility for selective security application.


167-190: The as any cast is acceptable given OpenAPI type complexity.

The cast at line 168 is needed because OpenAPI path items have HTTP method properties that TypeScript doesn't narrow well with string indexing. The implementation correctly handles the operation object afterward.

The idempotent check at lines 185-189 prevents duplicate security requirements, which is good defensive coding.


204-236: LGTM!

The function correctly removes security by setting security: [] (which in OpenAPI semantics means "no authentication required" for that operation). The implementation follows the same non-mutating pattern as forceJwtSecurity.

libs/sdk/src/common/tokens/tool.tokens.ts (1)

13-13: LGTM!

The rawOutputSchema token follows the established pattern and is correctly placed alongside the existing rawInputSchema token.

libs/sdk/src/tool/flows/tools-list.flow.ts (1)

42-48: LGTM!

The type extension pattern is clean. Using Record<string, unknown> for the output schema aligns with JSON Schema representation and follows the coding guidelines to avoid any types.

libs/sdk/src/tool/tool.instance.ts (1)

63-71: LGTM!

The rawOutputSchema initialization follows the established pattern for rawInputSchema and correctly propagates the metadata field to the instance.

libs/sdk/src/common/metadata/tool.metadata.ts (2)

198-202: LGTM!

The rawOutputSchema property is properly typed as JsonSchema (from Zod v4) and the documentation clearly explains its purpose for OpenAPI tools and structured output exposure.


265-265: Consistent with existing pattern.

Using z.any().optional() for rawOutputSchema matches the approach used for rawInputSchema on line 263. While a stricter JSON Schema validator could be used, the pragmatic approach is acceptable given JSON Schema's complexity.

libs/adapters/src/openapi/__tests__/openapi-utils.spec.ts (1)

272-365: LGTM! Comprehensive test coverage for structured response format.

The updated tests properly verify the new OpenApiResponse structure across various scenarios:

  • JSON and text content types
  • Invalid JSON fallback to text
  • HTTP error codes (400, 401, 404, 500)
  • Error message extraction from JSON body

The assertions correctly match the expected behavior from parseResponse in openapi.utils.ts.

libs/adapters/src/openapi/openapi.tool.ts (2)

42-56: LGTM! Well-structured output schema wrapper.

The wrapped output schema correctly defines the response envelope with status, ok, data, and error fields. The required: ['status', 'ok'] ensures consistent response structure validation.


209-239: Response format asymmetry is intentional—no changes needed.

Error responses return MCP CallToolResult format directly (with content, isError, _meta) to signal error conditions, while successful responses return raw data ({ status, ok, data }) matching the declared wrappedOutputSchema. This is the intended design: the SDK's buildParsedToolResult transforms successful responses through the schema descriptor into MCP format, while errors bypass this transformation to set error flags. The pattern is correct and aligns with how the tool decorator processes tool outputs.

libs/adapters/src/openapi/__tests__/openapi-edge-cases.spec.ts (2)

412-433: LGTM! Properly tests structured error response with sensitive data handling.

The test correctly verifies that:

  1. Non-ok responses return structured objects (not exceptions)
  2. Error messages are extracted from JSON body
  3. Parsed body data is accessible in result.data

This aligns well with the new parseResponse behavior.


469-543: Good coverage of HTTP error status codes.

The tests comprehensively cover:

  • 400 Bad Request (JSON body)
  • 403 Forbidden (JSON body)
  • 429 Rate Limited (JSON body)
  • 502 Bad Gateway (HTML body)
  • 503 Service Unavailable (text body)

Each test correctly verifies ok, status, and data fields for the new structured error format.

libs/adapters/src/openapi/__tests__/openapi-server.spec.ts (2)

703-788: Excellent output schema verification tests.

The tests thoroughly verify:

  1. rawOutputSchema is present in tool metadata
  2. Wrapper structure includes status, ok, data, error fields
  3. All generated tools have consistent output schema
  4. Default data type when no response schema is defined

This ensures the rawOutputSchema propagation from openapi.tool.ts works correctly end-to-end.


1-94: Well-designed test server infrastructure.

The createTestServer helper with dynamic route matching and parameterized paths provides a solid foundation for integration testing. The pattern matching logic (lines 42-58) correctly handles path parameters like {id}.

@github-actions
Copy link
Contributor

PR Testing Registry Available

A temporary npm registry has been created for testing this PR.

Registry URL

https://8f0b79e6eb6d.ngrok.app

Version

0.7.2-pr.207.638dedb

Quick Install

npm install @frontmcp/sdk@0.7.2-pr.207.638dedb --registry=https://8f0b79e6eb6d.ngrok.app

.npmrc Configuration

@frontmcp:registry=https://8f0b79e6eb6d.ngrok.app

Note: This registry will be available for approximately 1 hour(s).

To stop the registry early, cancel the workflow run.


Registry started by @frontegg-david

@github-actions
Copy link
Contributor

PR Testing Registry Stopped

The temporary npm registry for this PR has been shut down.

Reason: Workflow cancelled

To start a new registry, trigger the "PR Testing Registry" workflow again.

@frontegg-david frontegg-david merged commit 186f94a into main Jan 11, 2026
25 checks passed
@frontegg-david frontegg-david deleted the fix-openapi-adapter branch January 11, 2026 23:34
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.

2 participants