-
Notifications
You must be signed in to change notification settings - Fork 4
feat: Add end-to-end tests for direct usage and stdio transport in FrontMCP #205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
📝 WalkthroughWalkthroughAdds a transport-free Direct MCP server and in-memory transport factory, stdio server support, an E2E Notes demo app (tools/resources/prompts) with comprehensive direct+stdio tests and configs, SDK type/export expansions, and CI workflow adjustments for ngrok and publishing. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant DirectServer as DirectMcpServerImpl
participant Scope
participant Flow as Flow System
participant Handler as Tool/Resource/Prompt
Client->>DirectServer: callTool(name, args, options{authContext})
DirectServer->>Scope: runFlow("callTool", { sessionId, authInfo, payload })
Scope->>Flow: dispatch flow
Flow->>Handler: invoke handler
Handler-->>Flow: return output / throw
Flow-->>Scope: FlowControl.respond(output)
Scope-->>DirectServer: respond payload
DirectServer-->>Client: CallToolResult
sequenceDiagram
participant CLI
participant StdioEntrypoint
participant FrontMcp as FrontMcpInstance
participant MCP as MCP Server
participant StdioTransport as Stdio ServerTransport
participant OS as OS Signals
CLI->>StdioEntrypoint: start
StdioEntrypoint->>FrontMcp: runStdio(serverConfig)
FrontMcp->>MCP: init MCP server with capabilities
FrontMcp->>StdioTransport: create & attach transport
FrontMcp->>OS: register SIGINT/SIGTERM handlers
OS->>FrontMcp: SIGINT/SIGTERM
FrontMcp->>MCP: graceful shutdown
FrontMcp-->>StdioEntrypoint: resolve
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🤖 Fix all issues with AI agents
In @apps/e2e/demo-e2e-direct/src/apps/notes/tools/create-note.tool.ts:
- Line 31: The current ID generation for the note (id: `note-${Date.now()}` in
create-note.tool.ts) risks collisions under concurrent E2E runs; replace this
with a true UUID generator (e.g., use crypto.randomUUID() or the project's UUID
helper in @frontmcp/utils if available) so the id becomes unique (e.g., prefixed
with "note-") and update any imports accordingly.
In @apps/e2e/demo-e2e-direct/src/main.ts:
- Around line 12-23: The port value parsed with parseInt can be NaN; validate
the parsed result (the port constant created from parseInt(process.env['PORT']
?? '3015', 10)) and fall back to the default (3015) when it's not a finite
positive integer before passing it into the FrontMcp http config; update the
port variable (or introduce validatedPort) and use that in the FrontMcp({ http:
{ port: validatedPort }}) for the Server class to ensure the server always
receives a valid port.
In @apps/e2e/demo-e2e-direct/tsconfig.app.json:
- Around line 12-13: tsconfig.app.json currently excludes e2e tests via the
"exclude" array so e2e tests get no static type-checking; add a solution by
creating a separate tsconfig.e2e.json that includes "e2e/**/*.ts" and extends
the base config (so e2e files are type-checked without affecting app build) and
then add a CI/run target named "typecheck:e2e" (or a package script) that runs
tsc --noEmit -p tsconfig.e2e.json; alternatively, if you prefer a single config,
adjust the "include" to cover "e2e/**/*.ts" for a dedicated typecheck job, but
prefer the separate tsconfig.e2e.json plus the "typecheck:e2e" target for
clarity and CI integration.
In @libs/sdk/src/front-mcp/front-mcp.ts:
- Around line 97-101: The code is casting raw config to FrontMcpConfigType which
bypasses Zod defaults; instead call frontMcpMetadataSchema.parse(options) to
validate and apply defaults before constructing a FrontMcpInstance (replace the
cast in createForGraph and any other places that cast FrontMcpConfigInput to
FrontMcpConfigType, e.g., the other factory/constructor call around the later
cast), and pass the parsed result into the FrontMcpInstance constructor so
providers/tools/serve defaults are correctly applied.
In @libs/sdk/src/index.ts:
- Around line 149-160: The export statements are emitting runtime bindings for
two type-only interfaces: change the exports for CreateInMemoryServerOptions and
InMemoryServerResult to type-only exports (use "export type {
CreateInMemoryServerOptions, InMemoryServerResult }") wherever you currently
export them alongside createInMemoryServer/transport values (e.g., the module
that exports createInMemoryServer and the transport index), so the bundler/TS
emit treats them as types only and no runtime values are emitted.
In @libs/sdk/src/transport/index.ts:
- Around line 32-35: Add documentation for the newly exported public API symbols
by creating or updating files under docs/draft/docs to describe TransportType,
TransportKey, createInMemoryServer, CreateInMemoryServerOptions, and
InMemoryServerResult; include a brief overview of the in-memory server feature,
usage examples for createInMemoryServer (setup, common options from
CreateInMemoryServerOptions, and returned InMemoryServerResult shape), and links
or cross-references to transport.types and in-memory-server implementations so
consumers can find detailed type and behavior info.
🧹 Nitpick comments (13)
apps/e2e/demo-e2e-direct/e2e/stdio-transport.e2e.test.ts (2)
76-96: Strengthen assertions to validate response structure.The tool invocation tests verify that operations don't error but don't validate the actual response content. Consider adding assertions to verify response shape and expected data.
💡 Example: Add response structure validation
// Create a note const createResult = await client!.callTool({ name: 'create-note', arguments: { title: 'Stdio Test Note', content: 'Created via stdio transport' }, }); expect(createResult).toBeDefined(); expect(createResult.isError).not.toBe(true); +expect(createResult.content).toBeDefined(); +expect(Array.isArray(createResult.content)).toBe(true); // List notes const listResult = await client!.callTool({ name: 'list-notes', arguments: {}, }); expect(listResult).toBeDefined(); expect(listResult.isError).not.toBe(true); +expect(listResult.content).toBeDefined(); +expect(Array.isArray(listResult.content)).toBe(true); +expect(listResult.content.length).toBeGreaterThanOrEqual(1);
21-44: Silent error swallowing in cleanup could mask issues.The
afterEachhook silently ignores all errors during client and transport cleanup. While this prevents cleanup failures from affecting test results, it could hide legitimate issues like resource leaks or improper shutdown sequences.Consider logging suppressed errors to aid debugging:
💡 Suggested improvement
afterEach(async () => { // Cleanup client first if (client) { try { await client.close(); } catch (err) { - // Ignore close errors + // Log but don't fail on close errors + console.warn('Client close error (non-fatal):', err); } client = null; } // Cleanup transport (this kills the spawned process) if (transport) { try { await transport.close(); } catch (err) { - // Ignore close errors + console.warn('Transport close error (non-fatal):', err); } transport = null; } // Give process time to cleanup await new Promise((resolve) => setTimeout(resolve, 200)); });apps/e2e/demo-e2e-direct/src/main.ts (1)
14-36: Avoid config drift:@FrontMcp({...})andserverConfigare already diverging.Right now
serverConfigdiffers from the decorator config (httpmissing;logging.enableConsoleonly in one place). Consider defining one config object and reusing it for both the decorator and exports (optionally overridinghttp/loggingper entrypoint).Possible refactor
import { FrontMcp, LogLevel } from '@frontmcp/sdk'; import { NotesApp } from './apps/notes'; -const port = parseInt(process.env['PORT'] ?? '3015', 10); +const portFromEnv = Number(process.env['PORT']); +const port = Number.isFinite(portFromEnv) ? portFromEnv : 3015; + +export const serverConfig = { + info: { name: 'Demo E2E Direct', version: '0.1.0' }, + apps: [NotesApp], + logging: { level: LogLevel.Verbose, enableConsole: true }, + http: { port }, + auth: { mode: 'public' as const }, +}; @FrontMcp({ - info: { name: 'Demo E2E Direct', version: '0.1.0' }, - apps: [NotesApp], - logging: { level: LogLevel.Verbose }, - http: { port }, - auth: { - mode: 'public', - }, + ...serverConfig, }) export default class Server {} - -/** - * Export the configuration for direct usage testing. - * This allows tests to import the config directly. - */ -export const serverConfig = { - info: { name: 'Demo E2E Direct', version: '0.1.0' }, - apps: [NotesApp], - logging: { level: LogLevel.Verbose, enableConsole: true }, - auth: { - mode: 'public' as const, - }, -};apps/e2e/demo-e2e-direct/project.json (1)
8-35: Nx targets look coherent for a Node E2E demo; small maintainability tweak forserve.Consider referencing the configured
outputPathto reduce coupling to the literal dist path.Example tweak
"serve": { "executor": "nx:run-commands", "dependsOn": ["build"], "options": { - "command": "node dist/apps/e2e/demo-e2e-direct/main.js", + "command": "node {options.outputPath}/main.js", "cwd": "{workspaceRoot}" } },apps/e2e/demo-e2e-direct/e2e/direct-usage.e2e.test.ts (2)
179-183: Consider adding error type verification.While checking the error message is good, per testing guidelines, consider also verifying the error type using
instanceofchecks for better test coverage.💡 Suggested enhancement
it('should throw after dispose', async () => { await server.dispose(); - await expect(server.listTools()).rejects.toThrow('disposed'); + await expect(server.listTools()).rejects.toThrow(); + try { + await server.listTools(); + } catch (error) { + expect(error).toBeInstanceOf(Error); + expect(error.message).toContain('disposed'); + } });
347-366: Enhance concurrent test to verify ID uniqueness.This test exercises concurrent note creation (which is great!), but doesn't verify that all created notes have unique IDs. Given the ID collision risk identified in
create-note.tool.ts, this test should verify uniqueness to catch potential race conditions.🧪 Suggested enhancement
const results = await Promise.all(promises); // All should succeed results.forEach((result) => { expect(result.isError).not.toBe(true); }); + // Verify all notes have unique IDs + const listResult = await server.callTool('list-notes', {}); + const notes = JSON.parse(listResult.content[0].text).notes; + const ids = notes.map(n => n.id); + const uniqueIds = new Set(ids); + expect(uniqueIds.size).toBe(10); await server.dispose();libs/sdk/src/front-mcp/front-mcp.ts (2)
249-257: Signal handlers may swallow errors during shutdown.The
asynccallbacks forSIGINTandSIGTERMdo not catch errors frommcpServer.close(). If closing fails, the error is silently ignored beforeprocess.exit(0). Consider wrapping in try-catch and logging failures, or using a non-zero exit code on error.Proposed improvement for graceful shutdown
// Handle graceful shutdown process.on('SIGINT', async () => { + try { await mcpServer.close(); - process.exit(0); + process.exit(0); + } catch { + process.exit(1); + } }); process.on('SIGTERM', async () => { + try { await mcpServer.close(); - process.exit(0); + process.exit(0); + } catch { + process.exit(1); + } });
241-243: Theanycast is justified but could be narrowed.The
eslint-disablecomment documents theanyusage. The MCP SDK handler type incompatibility is a known limitation. Consider adding a brief inline comment explaining why this cast is necessary for maintainability.libs/sdk/src/transport/in-memory-server.ts (2)
106-134: Capability building logic is duplicated withrunStdio.This capability detection and
serverOptionsconstruction is nearly identical to lines 203-233 infront-mcp.ts. Consider extracting a shared helper function (e.g.,buildMcpServerOptions(scope)) to centralize this logic and avoid drift.// Example shared helper in a common module export function buildMcpServerOptions(scope: Scope) { const hasRemoteApps = scope.apps?.getApps().some((app) => app.isRemote) ?? false; const hasPrompts = scope.prompts.hasAny() || hasRemoteApps; const hasResources = scope.resources.hasAny() || hasRemoteApps; // ... rest of capability building return serverOptions; }
144-158: Multipleanycasts are necessary but warrant documentation.The MCP SDK's handler types don't align directly with the wrapped handler signature. The
eslint-disablecomments are present, but a brief code comment explaining why these casts are unavoidable would help future maintainers understand this isn't technical debt to address.libs/sdk/src/direct/direct-server.ts (3)
82-84: Use a specific MCP error class for disposed state check.Per coding guidelines for
libs/{sdk,adapters}/**, use specific error classes with MCP error codes instead of generic errors. The disposed check throws a genericError.Proposed fix
if (this._isDisposed) { - throw new Error('DirectMcpServer has been disposed'); + throw new InternalMcpError('DirectMcpServer has been disposed'); }
38-47: The double castas unknown as Partial<AuthInfo>may hide type mismatches.The cast through
unknownbypasses all type checking. If theAuthInfointerface changes upstream, this code won't surface compile-time errors. Consider either:
- Defining a local type that matches the expected shape
- Using a type assertion function with runtime validation
The comment on line 38 explains the intent, but this pattern is fragile.
175-180: Empty catch block silently ignores cleanup errors.While cleanup errors are often non-critical, silently swallowing them makes debugging harder. Consider logging the error at debug level or adding a comment explaining why errors are intentionally ignored.
Proposed improvement
try { await this.scope.transportService.destroy(); - } catch { - // Ignore cleanup errors + } catch (error) { + // Cleanup errors are non-critical - log for debugging but don't propagate + // since the server is being disposed anyway }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (25)
apps/e2e/demo-e2e-direct/e2e/direct-usage.e2e.test.tsapps/e2e/demo-e2e-direct/e2e/stdio-transport.e2e.test.tsapps/e2e/demo-e2e-direct/jest.e2e.config.tsapps/e2e/demo-e2e-direct/project.jsonapps/e2e/demo-e2e-direct/src/apps/notes/data/notes.store.tsapps/e2e/demo-e2e-direct/src/apps/notes/index.tsapps/e2e/demo-e2e-direct/src/apps/notes/prompts/summarize-notes.prompt.tsapps/e2e/demo-e2e-direct/src/apps/notes/resources/notes-list.resource.tsapps/e2e/demo-e2e-direct/src/apps/notes/tools/create-note.tool.tsapps/e2e/demo-e2e-direct/src/apps/notes/tools/list-notes.tool.tsapps/e2e/demo-e2e-direct/src/main.tsapps/e2e/demo-e2e-direct/src/stdio-entrypoint.tsapps/e2e/demo-e2e-direct/tsconfig.app.jsonapps/e2e/demo-e2e-direct/tsconfig.jsonapps/e2e/demo-e2e-direct/webpack.config.jsapps/e2e/demo-e2e-public/src/main.tslibs/sdk/src/common/metadata/front-mcp.metadata.tslibs/sdk/src/direct/direct-server.tslibs/sdk/src/direct/direct.types.tslibs/sdk/src/direct/index.tslibs/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/index.tslibs/sdk/src/transport/in-memory-server.tslibs/sdk/src/transport/index.tslibs/sdk/src/transport/transport.types.ts
💤 Files with no reviewable changes (1)
- apps/e2e/demo-e2e-public/src/main.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Use strict TypeScript mode with noanytypes without strong justification
Avoid non-null assertions (!) - use proper error handling and type guards instead
Use@frontmcp/utilsfor cryptographic operations instead ofnode:cryptodirectly
Use@frontmcp/utilsfor file system operations instead offs/promisesornode:fsdirectly
Files:
libs/sdk/src/transport/transport.types.tsapps/e2e/demo-e2e-direct/src/apps/notes/data/notes.store.tsapps/e2e/demo-e2e-direct/src/apps/notes/index.tsapps/e2e/demo-e2e-direct/jest.e2e.config.tslibs/sdk/src/direct/index.tslibs/sdk/src/transport/index.tsapps/e2e/demo-e2e-direct/src/apps/notes/prompts/summarize-notes.prompt.tslibs/sdk/src/front-mcp/front-mcp.tsapps/e2e/demo-e2e-direct/e2e/stdio-transport.e2e.test.tsapps/e2e/demo-e2e-direct/e2e/direct-usage.e2e.test.tslibs/sdk/src/transport/in-memory-server.tslibs/sdk/src/direct/direct-server.tsapps/e2e/demo-e2e-direct/src/stdio-entrypoint.tsapps/e2e/demo-e2e-direct/src/apps/notes/tools/list-notes.tool.tslibs/sdk/src/common/metadata/front-mcp.metadata.tslibs/sdk/src/direct/direct.types.tslibs/sdk/src/index.tsapps/e2e/demo-e2e-direct/src/apps/notes/tools/create-note.tool.tsapps/e2e/demo-e2e-direct/src/apps/notes/resources/notes-list.resource.tsapps/e2e/demo-e2e-direct/src/main.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
UsegetCapabilities()for dynamic capability exposure instead of hardcoding capabilities
Files:
libs/sdk/src/transport/transport.types.tslibs/sdk/src/direct/index.tslibs/sdk/src/transport/index.tslibs/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/transport/in-memory-server.tslibs/sdk/src/direct/direct-server.tslibs/sdk/src/common/metadata/front-mcp.metadata.tslibs/sdk/src/direct/direct.types.tslibs/sdk/src/index.ts
libs/sdk/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
libs/sdk/**/*.{ts,tsx}: Preferinterfacefor defining object shapes in TypeScript, avoidanytypes
Use type parameters with constraints instead of unconstrained generics withanydefaults
Validate URIs per RFC 3986 at metadata level usingisValidMcpUrirefinement
UsechangeScopeinstead ofscopein 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 ofPromise<unknown>for MCP entry methods
Useunknowninstead ofanyfor 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/transport/transport.types.tslibs/sdk/src/direct/index.tslibs/sdk/src/transport/index.tslibs/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/transport/in-memory-server.tslibs/sdk/src/direct/direct-server.tslibs/sdk/src/common/metadata/front-mcp.metadata.tslibs/sdk/src/direct/direct.types.tslibs/sdk/src/index.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/transport/transport.types.tslibs/sdk/src/direct/index.tslibs/sdk/src/transport/index.tslibs/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/transport/in-memory-server.tslibs/sdk/src/direct/direct-server.tslibs/sdk/src/common/metadata/front-mcp.metadata.tslibs/sdk/src/direct/direct.types.tslibs/sdk/src/index.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.test.{ts,tsx}: Achieve 95%+ test coverage across all metrics (statements, branches, functions, lines)
Use Jest for testing with 95%+ coverage requirement and 100% test pass rate
Do not use prefixes like 'PT-001' in test names
Do not skip constructor validation tests for error classes and types
Includeinstanceofchecks in tests for error classes to verify proper error hierarchy
Files:
apps/e2e/demo-e2e-direct/e2e/stdio-transport.e2e.test.tsapps/e2e/demo-e2e-direct/e2e/direct-usage.e2e.test.ts
libs/*/src/index.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Export everything users need through barrel exports (index.ts), do not add backwards compatibility aliases
Files:
libs/sdk/src/index.ts
🧠 Learnings (26)
📚 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:
apps/e2e/demo-e2e-direct/src/apps/notes/data/notes.store.tslibs/sdk/src/direct/index.tsapps/e2e/demo-e2e-direct/tsconfig.app.jsonlibs/sdk/src/common/metadata/front-mcp.metadata.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:
apps/e2e/demo-e2e-direct/src/apps/notes/index.tslibs/sdk/src/direct/index.tsapps/e2e/demo-e2e-direct/tsconfig.jsonapps/e2e/demo-e2e-direct/webpack.config.jsapps/e2e/demo-e2e-direct/src/stdio-entrypoint.tslibs/sdk/src/common/metadata/front-mcp.metadata.tslibs/sdk/src/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/universal/**/*.{ts,tsx} : Universal app shell (UniversalApp, FrontMCPProvider) must provide platform-agnostic React context and initialization
Applied to files:
apps/e2e/demo-e2e-direct/src/apps/notes/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} : Create shared base classes for common functionality like ExecutionContextBase for ToolContext and ResourceContext
Applied to files:
apps/e2e/demo-e2e-direct/src/apps/notes/index.tsapps/e2e/demo-e2e-direct/src/apps/notes/tools/list-notes.tool.tsapps/e2e/demo-e2e-direct/src/apps/notes/tools/create-note.tool.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} : Use Jest for testing with 95%+ coverage requirement and 100% test pass rate
Applied to files:
apps/e2e/demo-e2e-direct/jest.e2e.config.tsapps/e2e/demo-e2e-direct/tsconfig.app.json
📚 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:
apps/e2e/demo-e2e-direct/jest.e2e.config.tsapps/e2e/demo-e2e-direct/tsconfig.jsonapps/e2e/demo-e2e-direct/e2e/stdio-transport.e2e.test.tsapps/e2e/demo-e2e-direct/tsconfig.app.json
📚 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:
apps/e2e/demo-e2e-direct/jest.e2e.config.tsapps/e2e/demo-e2e-direct/tsconfig.jsonapps/e2e/demo-e2e-direct/tsconfig.app.jsonapps/e2e/demo-e2e-direct/src/apps/notes/tools/list-notes.tool.tsapps/e2e/demo-e2e-direct/src/apps/notes/tools/create-note.tool.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} : Do not use prefixes like 'PT-001' in test names
Applied to files:
apps/e2e/demo-e2e-direct/jest.e2e.config.tsapps/e2e/demo-e2e-direct/tsconfig.app.json
📚 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 : Use proper ES module imports instead of `require()` for SDK imports; avoid dynamic require of `frontmcp/sdk` modules
Applied to files:
libs/sdk/src/direct/index.tslibs/sdk/src/front-mcp/front-mcp.tsapps/e2e/demo-e2e-direct/src/stdio-entrypoint.tslibs/sdk/src/common/metadata/front-mcp.metadata.tslibs/sdk/src/direct/direct.types.tslibs/sdk/src/index.ts
📚 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/**/*plugin.ts : Use module augmentation for context properties via `declare module 'frontmcp/sdk'` combined with runtime plugin metadata `contextExtensions`, not module-level side effects
Applied to files:
libs/sdk/src/direct/index.tslibs/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/common/metadata/front-mcp.metadata.tslibs/sdk/src/direct/direct.types.tslibs/sdk/src/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/sdk/src/direct/index.tslibs/sdk/src/transport/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/direct/index.tslibs/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/transport/in-memory-server.tslibs/sdk/src/direct/direct-server.tslibs/sdk/src/common/metadata/front-mcp.metadata.tslibs/sdk/src/direct/direct.types.tslibs/sdk/src/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 **/*.{ts,tsx} : Use `frontmcp/utils` for cryptographic operations instead of `node:crypto` directly
Applied to files:
libs/sdk/src/direct/index.tslibs/sdk/src/front-mcp/front-mcp.tsapps/e2e/demo-e2e-direct/src/stdio-entrypoint.tslibs/sdk/src/common/metadata/front-mcp.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 **/*.{ts,tsx} : Use strict TypeScript mode with no `any` types without strong justification
Applied to files:
apps/e2e/demo-e2e-direct/tsconfig.jsonapps/e2e/demo-e2e-direct/tsconfig.app.json
📚 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 : Configure approval requirements on tools using the `approval` decorator property with fields: `required`, `defaultScope`, `category`, `riskLevel`, and `approvalMessage`
Applied to files:
apps/e2e/demo-e2e-direct/tsconfig.json
📚 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 file system operations instead of `fs/promises` or `node:fs` directly
Applied to files:
libs/sdk/src/front-mcp/front-mcp.tsapps/e2e/demo-e2e-direct/e2e/direct-usage.e2e.test.tsapps/e2e/demo-e2e-direct/src/stdio-entrypoint.tslibs/sdk/src/common/metadata/front-mcp.metadata.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:
apps/e2e/demo-e2e-direct/webpack.config.js
📚 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/**/*.test.{ts,tsx} : Use React Testing Library for component tests and include SSR/hydration tests for all interactive components
Applied to files:
apps/e2e/demo-e2e-direct/tsconfig.app.json
📚 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/**/{package.json,*.ts,*.tsx,*.js,*.jsx} : Do not add React dependencies to frontmcp/uipack - it must remain React-free. Use frontmcp/ui for React components.
Applied to files:
apps/e2e/demo-e2e-direct/tsconfig.app.json
📚 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:
apps/e2e/demo-e2e-direct/tsconfig.app.json
📚 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/**/{src}/**/*.{ts,tsx} : Do not use `any` type without justification in TypeScript code
Applied to files:
apps/e2e/demo-e2e-direct/tsconfig.app.json
📚 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/**/*plugin.ts : Extend ExecutionContextBase with plugin-specific properties using module declaration (`declare module 'frontmcp/sdk'`) combined with `contextExtensions` in plugin metadata
Applied to files:
libs/sdk/src/common/metadata/front-mcp.metadata.tslibs/sdk/src/direct/direct.types.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} : Use `unknown` instead of `any` for generic type parameter defaults (not for MCP protocol types)
Applied to files:
libs/sdk/src/common/metadata/front-mcp.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,adapters}/**/*.{ts,tsx} : Use specific error classes with MCP error codes instead of generic errors
Applied to files:
libs/sdk/src/common/metadata/front-mcp.metadata.tslibs/sdk/src/direct/direct.types.tslibs/sdk/src/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: Nx-based monorepo build system - use commands like `nx build sdk`, `nx test ast-guard`, `nx run-many -t test`
Applied to files:
apps/e2e/demo-e2e-direct/project.json
📚 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/sdk/src/index.ts
🧬 Code graph analysis (9)
apps/e2e/demo-e2e-direct/src/apps/notes/prompts/summarize-notes.prompt.ts (3)
libs/sdk/src/index.ts (1)
GetPromptResult(34-34)apps/e2e/demo-e2e-direct/src/apps/notes/data/notes.store.ts (1)
notesStore(32-32)apps/e2e/demo-e2e-orchestrated/src/apps/notes/prompts/summarize-notes.prompt.ts (1)
SummarizeNotesPrompt(19-38)
apps/e2e/demo-e2e-direct/webpack.config.js (1)
libs/uipack/src/handlebars/index.ts (1)
join(419-419)
apps/e2e/demo-e2e-direct/e2e/direct-usage.e2e.test.ts (4)
apps/e2e/demo-e2e-direct/src/apps/notes/data/notes.store.ts (1)
notesStore(32-32)libs/sdk/src/direct/direct.types.ts (1)
DirectMcpServer(85-170)apps/e2e/demo-e2e-direct/src/main.ts (1)
serverConfig(29-36)libs/sdk/src/transport/in-memory-server.ts (1)
createInMemoryServer(89-177)
libs/sdk/src/transport/in-memory-server.ts (2)
libs/sdk/src/scope/scope.instance.ts (1)
Scope(37-384)libs/sdk/src/transport/mcp-handlers/index.ts (1)
createMcpHandlers(17-56)
apps/e2e/demo-e2e-direct/src/stdio-entrypoint.ts (2)
libs/sdk/src/front-mcp/front-mcp.ts (1)
FrontMcpInstance(10-259)apps/e2e/demo-e2e-direct/src/main.ts (1)
serverConfig(29-36)
apps/e2e/demo-e2e-direct/src/apps/notes/tools/list-notes.tool.ts (3)
libs/cli/src/templates/3rd-party-integration/src/tools/example.list.ts (1)
inputSchema(12-17)apps/e2e/demo-e2e-direct/src/apps/notes/tools/create-note.tool.ts (1)
Tool(22-41)apps/e2e/demo-e2e-direct/src/apps/notes/data/notes.store.ts (1)
notesStore(32-32)
apps/e2e/demo-e2e-direct/src/apps/notes/tools/create-note.tool.ts (3)
libs/cli/src/templates/3rd-party-integration/src/tools/example.list.ts (1)
inputSchema(12-17)apps/e2e/demo-e2e-direct/src/apps/notes/tools/list-notes.tool.ts (1)
Tool(22-36)apps/e2e/demo-e2e-direct/src/apps/notes/data/notes.store.ts (1)
notesStore(32-32)
apps/e2e/demo-e2e-direct/src/apps/notes/resources/notes-list.resource.ts (1)
apps/e2e/demo-e2e-direct/src/apps/notes/data/notes.store.ts (1)
notesStore(32-32)
apps/e2e/demo-e2e-direct/src/main.ts (1)
apps/e2e/demo-e2e-public/src/main.ts (1)
FrontMcp(6-15)
⏰ 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 (19)
apps/e2e/demo-e2e-direct/jest.e2e.config.ts (1)
1-44: LGTM!The Jest e2e configuration is well-structured with appropriate settings for end-to-end testing. The sequential execution (
maxWorkers: 1), extended timeout (60s), and decorator support align well with the direct MCP server testing requirements.libs/sdk/src/direct/direct.types.ts (1)
1-170: LGTM!The type definitions are well-structured and follow all coding guidelines:
- Uses
interfacefor object shapes as recommended- All MCP methods return strictly typed
Promise<XxxResult>responses- No
anytypes used- Comprehensive JSDoc documentation with usage examples
The design provides a clean, type-safe API for transport-free MCP server access.
Based on coding guidelines requiring strictly typed MCP protocol responses.
apps/e2e/demo-e2e-direct/tsconfig.json (1)
1-15: LGTM!Standard TypeScript project references configuration with proper decorator support for the SDK.
apps/e2e/demo-e2e-direct/src/apps/notes/data/notes.store.ts (1)
8-30: No thread safety concerns. TheNotesStoreclass operations are safe despite concurrent test scenarios. JavaScript's single-threaded event loop ensures that allMapoperations (set,get,delete) execute atomically, even when concurrent async calls are made viaPromise.all(). The "concurrent" test operations are concurrent at the network/Promise level, not at the actual JavaScript execution level, so synchronization mechanisms are not required.apps/e2e/demo-e2e-direct/src/stdio-entrypoint.ts (1)
11-18: LGTM! Clean stdio entrypoint implementation.The entrypoint is well-structured with proper ES module imports, clear error handling, and appropriate process exit behavior. The inline documentation provides helpful usage examples for both development and production scenarios.
libs/sdk/src/transport/transport.types.ts (1)
7-7: LGTM! Appropriate transport type extension.The addition of
'in-memory'and'stdio'to theTransportTypeunion properly supports the new transport modes introduced in this PR. This is a non-breaking public API extension that enables the direct usage and stdio transport capabilities.libs/sdk/src/direct/index.ts (1)
1-9: LGTM! Proper barrel export pattern.The module correctly exports the Direct MCP Server API surface using type-only exports for interfaces and a concrete export for the implementation. This follows SDK best practices and provides a clean public API entry point.
As per coding guidelines: properly exports public APIs through appropriate entry points.
libs/sdk/src/common/metadata/front-mcp.metadata.ts (1)
218-222: LGTM! Proper configuration type exports.The new type exports correctly leverage Zod's
z.inferandz.inpututilities to provide distinct types for configuration before and after defaults are applied. The inline comments clearly document the distinction between input and output types, which improves developer experience when using the SDK.apps/e2e/demo-e2e-direct/src/apps/notes/index.ts (1)
1-14: Clean app registration; wiring is straightforward and readable.apps/e2e/demo-e2e-direct/src/apps/notes/tools/create-note.tool.ts (1)
5-17: LGTM: Well-structured schemas.The schemas properly use
.strict()to prevent extra properties and include helpful descriptions for API documentation.apps/e2e/demo-e2e-direct/src/apps/notes/resources/notes-list.resource.ts (1)
25-32: LGTM: Clean resource implementation.The resource properly implements the ResourceContext pattern with a clear output schema and straightforward execution logic.
apps/e2e/demo-e2e-direct/e2e/direct-usage.e2e.test.ts (2)
1-24: LGTM: Well-documented test file with proper setup.The file header clearly explains the purpose and use cases. The
beforeEachcleanup ensures test isolation.
20-392: Excellent E2E test coverage.The test suite comprehensively covers:
- Direct server lifecycle and operations
- In-memory transport and MCP client integration
- Tool, resource, and prompt operations
- Auth context propagation and dynamic updates
- Concurrent operations
- Error handling and cleanup
This aligns well with the PR objectives for testing direct usage and transport capabilities.
apps/e2e/demo-e2e-direct/webpack.config.js (1)
1-28: LGTM: Well-configured webpack setup for E2E testing.The configuration is appropriate for a Node.js E2E test application:
- Development mode with source maps for debugging
- External dependencies properly handled
- Building from source for accurate testing
- No optimization for faster builds
libs/sdk/src/front-mcp/front-mcp.ts (1)
133-150: LGTM! ThecreateDirectmethod is well-documented and properly validates scopes.The implementation correctly disables HTTP transport, validates that at least one scope exists before returning, and wraps the scope in
DirectMcpServerImpl. The JSDoc examples are helpful for users.libs/sdk/src/transport/in-memory-server.ts (2)
1-11: LGTM! Proper imports following coding guidelines.The use of
@frontmcp/utilsforrandomUUIDinstead ofnode:cryptodirectly aligns with the coding guidelines.
167-176: LGTM! Clean API surface with proper cleanup.The returned object provides a clear interface with
clientTransport,setAuthInfo, andclose. Theclosemethod correctly unregisters from the notification service before closing the server.apps/e2e/demo-e2e-direct/src/apps/notes/tools/list-notes.tool.ts (1)
1-36: LGTM! Well-structured tool following established patterns.The
ListNotesToolfollows the same structure asCreateNoteToolshown in the relevant code snippets. The zod schemas are properly defined, type inference is used correctly, and the tool decorator configuration is complete. The underscore prefix on_inputcorrectly signals the unused parameter.libs/sdk/src/direct/direct-server.ts (1)
109-163: LGTM! All MCP operations return strictly typed protocol responses.The methods
listTools,callTool,listResources,listResourceTemplates,readResource,listPrompts, andgetPromptall return properly typed MCP protocol results (e.g.,Promise<ListToolsResult>,Promise<CallToolResult>). This follows the coding guideline to "return strictly typed MCP protocol responses instead ofPromise<unknown>for MCP entry methods."
apps/e2e/demo-e2e-direct/src/apps/notes/prompts/summarize-notes.prompt.ts
Show resolved
Hide resolved
apps/e2e/demo-e2e-direct/src/apps/notes/tools/create-note.tool.ts
Outdated
Show resolved
Hide resolved
…r handling in direct usage tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 12
🤖 Fix all issues with AI agents
In @.github/workflows/pr-testing-registry.yml:
- Around line 22-26: The workflow currently concatenates the user-controlled
input inputs.ngrok_domain into NGROK_CMD and executes it, enabling command
injection; fix by validating/sanitizing ngrok_domain (allow only a strict
whitelist pattern such as [a-z0-9.-]+, reject empty or dangerous characters like
;|&$`<>\"\' and spaces), and stop building a shell string—pass the domain as a
separate argument to the ngrok invocation or use the runner’s exec/array-style
command form so it is not interpreted by a shell; update the NGROK_CMD usage and
any other concatenations in the workflow (including the referenced block around
lines 142-169) to use this safe-argument approach and input validation.
- Around line 411-495: The printed install commands incorrectly reference a
scoped CLI package @frontmcp/cli but the actual CLI is unscoped frontmcp; update
the npm and yarn lists in the Print install commands step to remove any "npm
install @frontmcp/cli@$VERSION" and "yarn add @frontmcp/cli@$VERSION" entries
and replace them where appropriate with the unscoped frontmcp references (e.g.,
use npm install -g frontmcp@$VERSION --registry=$REGISTRY and npx
--registry=$REGISTRY frontmcp@$VERSION), and adjust the .npmrc note text so it
explicitly states the CLI is unscoped and must be installed with the --registry
flag.
- Around line 224-240: PKG_NAME can be set to the string "null" when jq returns
null; change the jq call to capture its output into a temp variable (e.g.,
PKG_NAME_RAW=$(jq -r '.name // empty' "libs/$pkg/dist/package.json"
2>/dev/null)) and then set PKG_NAME="${PKG_NAME_RAW:-@frontmcp/$pkg}" (or
explicitly test for empty/"null" and fallback) before publishing; update the
PKG_NAME assignment in the loop that builds LIBS_PACKAGES so missing or null
names use the default @frontmcp/$pkg rather than "null".
- Around line 138-141: Replace the global installation of the wrong package by
changing the install command to use the official, pinned ngrok SDK: replace the
current `npm install -g ngrok` invocation with `npm install -g
@ngrok/ngrok@1.5.2` so the subsequent `npx ngrok` commands (the ones that run
`config add-authtoken`, `--domain`, `--log=stdout` in the workflow) use the
maintained @ngrok/ngrok package and a fixed version to avoid breaking changes.
In @apps/e2e/demo-e2e-direct/e2e/direct-usage.e2e.test.ts:
- Around line 189-288: The test uses unsafe any casts for scope and auth info;
fix by importing the concrete Scope class and UserClaim type, retrieve the scope
via const scopeEntry = frontMcp.getScopes()[0]; narrow it with a runtime check
(e.g., if (!(scopeEntry instanceof Scope)) throw) and then pass the narrowed
scope to createInMemoryServer instead of using "as any", and replace
setAuthInfo({...} as any) with a fully-formed UserClaim object (including
required fields like sub and any other mandatory properties) so setAuthInfo is
called with the proper UserClaim type.
In @libs/sdk/src/direct/direct-server.ts:
- Around line 69-72: buildHandlerContext currently ignores
DirectCallOptions.metadata so request metadata never reaches flows/handlers;
update buildHandlerContext (the method that returns { authInfo }) to extract
options?.metadata and include it in the returned context object (e.g., return {
authInfo, metadata: options?.metadata }) so handlers can access it as part of
ctx, or if you prefer to drop support remove metadata from the DirectCallOptions
type and all callers—preferably wire options.metadata into the ctx returned by
buildHandlerContext.
- Around line 77-103: The runFlow method currently casts flowName to any when
calling this.scope.runFlowForOutput and throws a generic InternalMcpError for
non-respond FlowControl cases; update runFlow to type flowName to the proper
flow union (e.g., FlowName or the known flow type used by
scope.runFlowForOutput) instead of using "as any", call
this.scope.runFlowForOutput with the correctly typed flowName, and when catching
a FlowControl with types like "fail" or "abort" include the FlowControl
output/details in the thrown InternalMcpError (e.g., include e.output or
stringify it) so failures surface actionable information.
- Around line 28-47: In buildAuthInfo, avoid coercing a missing token into an
empty string and remove the double-cast: construct a Partial<AuthInfo> object
and only add the token property when authContext?.token is defined (omit token
entirely for unauth calls), keep sessionId/user/scopes/clientId/extra as before
(use user.sub for clientId), and return the object typed as Partial<AuthInfo>
without using "as unknown as Partial<AuthInfo>".
In @libs/sdk/src/front-mcp/front-mcp.ts:
- Around line 142-160: In createDirect (public static async createDirect)
replace the generic throw new Error('No scopes initialized...') with throwing an
InternalMcpError so SDK consumers get MCP-specific errors; locate the
createDirect method on FrontMcpInstance usage, import or reference
InternalMcpError, and throw new InternalMcpError('No scopes initialized. Ensure
at least one app is configured.') (or equivalent message) instead of Error to
follow libs/sdk error conventions.
In @libs/sdk/src/index.ts:
- Around line 148-161: The new public exports (DirectMcpServer,
DirectAuthContext, DirectCallOptions, DirectRequestMetadata,
createInMemoryServer, CreateInMemoryServerOptions, InMemoryServerResult,
TransportType, TransportKey) were added to the SDK but lack corresponding
documentation; add concise doc pages for each exported type/function describing
purpose, API surface, parameters/types, and a short usage example, and register
those pages in the docs navigation/TOC so they appear under the public SDK docs;
ensure the docs mention how DirectMcpServer differs from HTTP server usage and
show createInMemoryServer example for testing/integration, and include type
references for CreateInMemoryServerOptions/InMemoryServerResult and
TransportType/TransportKey.
In @libs/sdk/src/transport/index.ts:
- Around line 31-33: The current export re-exports TransportType and
TransportKey as value exports which can introduce runtime artifacts; change the
export to type-only re-exports for TransportType and TransportKey (e.g., use
export type { TransportType, TransportKey } from './transport.types') while
keeping SupportedTransport as a normal export from
'./adapters/transport.local.adapter' so only the type definitions are
re-exported at compile time.
🧹 Nitpick comments (5)
apps/e2e/demo-e2e-direct/project.json (1)
36-52: Clarify the distinction between "test" and "test:e2e" targets.Both targets use the same Jest configuration file (
jest.e2e.config.ts) but differ primarily in therunInBandoption and output paths. This creates potential confusion about which target to use.Consider:
- If both targets serve distinct purposes, document the difference (e.g., parallel vs. sequential execution) in comments or README
- If one is redundant, consolidate to a single target
- Alternatively, use different config files if they're meant for different test suites
apps/e2e/demo-e2e-direct/tsconfig.e2e.json (1)
1-9: Looks good for E2E type-checking;exclude: []is likely unnecessary.Minor: omitting
excludeentirely keeps the config simpler unless you’re intentionally overriding an inherited exclude list. Based on learnings, keep strict TS inherited from the base config.apps/e2e/demo-e2e-direct/src/main.ts (1)
12-15: Harden port validation (upper bound + integer).
parseIntgives an integer, but adding an explicit<= 65535bound avoids odd configs.Proposed diff
-const rawPort = parseInt(process.env['PORT'] ?? '3015', 10); -const port = Number.isFinite(rawPort) && rawPort > 0 ? rawPort : 3015; +const rawPort = Number.parseInt(process.env['PORT'] ?? '3015', 10); +const port = Number.isInteger(rawPort) && rawPort > 0 && rawPort <= 65535 ? rawPort : 3015;libs/sdk/src/transport/index.ts (1)
66-79: Export shape is clear; consider consolidating./in-memory-serverexports.Optional cleanup: re-export function + types in one statement to reduce repetition.
apps/e2e/demo-e2e-direct/e2e/direct-usage.e2e.test.ts (1)
348-405: Make concurrent test cleanup resilient (dispose/close infinally).If an expectation fails, the server/client may leak and cascade failures in later tests.
Proposed diff
it('should handle concurrent tool calls via createDirect', async () => { - const server = await FrontMcpInstance.createDirect(serverConfig); + const server = await FrontMcpInstance.createDirect(serverConfig); + try { // Create multiple notes concurrently const promises = Array.from({ length: 10 }, (_, i) => server.callTool('create-note', { title: `Concurrent Note ${i}`, content: `Content ${i}`, }), ); const results = await Promise.all(promises); ... - await server.dispose(); + } finally { + await server.dispose(); + } });
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
.github/workflows/pr-testing-registry.ymlapps/e2e/demo-e2e-direct/e2e/direct-usage.e2e.test.tsapps/e2e/demo-e2e-direct/e2e/stdio-transport.e2e.test.tsapps/e2e/demo-e2e-direct/project.jsonapps/e2e/demo-e2e-direct/src/apps/notes/tools/create-note.tool.tsapps/e2e/demo-e2e-direct/src/main.tsapps/e2e/demo-e2e-direct/tsconfig.e2e.jsonlibs/sdk/src/direct/direct-server.tslibs/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/index.tslibs/sdk/src/transport/index.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/e2e/demo-e2e-direct/src/apps/notes/tools/create-note.tool.ts
- apps/e2e/demo-e2e-direct/e2e/stdio-transport.e2e.test.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Use strict TypeScript mode with noanytypes without strong justification
Avoid non-null assertions (!) - use proper error handling and type guards instead
Use@frontmcp/utilsfor cryptographic operations instead ofnode:cryptodirectly
Use@frontmcp/utilsfor file system operations instead offs/promisesornode:fsdirectly
Files:
apps/e2e/demo-e2e-direct/src/main.tsapps/e2e/demo-e2e-direct/e2e/direct-usage.e2e.test.tslibs/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/direct/direct-server.tslibs/sdk/src/transport/index.tslibs/sdk/src/index.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.test.{ts,tsx}: Achieve 95%+ test coverage across all metrics (statements, branches, functions, lines)
Use Jest for testing with 95%+ coverage requirement and 100% test pass rate
Do not use prefixes like 'PT-001' in test names
Do not skip constructor validation tests for error classes and types
Includeinstanceofchecks in tests for error classes to verify proper error hierarchy
Files:
apps/e2e/demo-e2e-direct/e2e/direct-usage.e2e.test.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
UsegetCapabilities()for dynamic capability exposure instead of hardcoding capabilities
Files:
libs/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/direct/direct-server.tslibs/sdk/src/transport/index.tslibs/sdk/src/index.ts
libs/sdk/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
libs/sdk/**/*.{ts,tsx}: Preferinterfacefor defining object shapes in TypeScript, avoidanytypes
Use type parameters with constraints instead of unconstrained generics withanydefaults
Validate URIs per RFC 3986 at metadata level usingisValidMcpUrirefinement
UsechangeScopeinstead ofscopein 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 ofPromise<unknown>for MCP entry methods
Useunknowninstead ofanyfor 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/front-mcp/front-mcp.tslibs/sdk/src/direct/direct-server.tslibs/sdk/src/transport/index.tslibs/sdk/src/index.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/front-mcp/front-mcp.tslibs/sdk/src/direct/direct-server.tslibs/sdk/src/transport/index.tslibs/sdk/src/index.ts
libs/*/src/index.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Export everything users need through barrel exports (index.ts), do not add backwards compatibility aliases
Files:
libs/sdk/src/index.ts
🧠 Learnings (29)
📚 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 strict TypeScript mode with no `any` types without strong justification
Applied to files:
apps/e2e/demo-e2e-direct/tsconfig.e2e.json
📚 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} : Use Jest for testing with 95%+ coverage requirement and 100% test pass rate
Applied to files:
apps/e2e/demo-e2e-direct/tsconfig.e2e.json
📚 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} : Do not use prefixes like 'PT-001' in test names
Applied to files:
apps/e2e/demo-e2e-direct/tsconfig.e2e.json
📚 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} : Do not skip constructor validation tests for error classes and types
Applied to files:
apps/e2e/demo-e2e-direct/tsconfig.e2e.json
📚 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:
apps/e2e/demo-e2e-direct/tsconfig.e2e.json
📚 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:
apps/e2e/demo-e2e-direct/tsconfig.e2e.json
📚 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:
apps/e2e/demo-e2e-direct/src/main.ts.github/workflows/pr-testing-registry.ymllibs/sdk/src/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 **/*.{ts,tsx} : Use `frontmcp/utils` for file system operations instead of `fs/promises` or `node:fs` directly
Applied to files:
apps/e2e/demo-e2e-direct/e2e/direct-usage.e2e.test.tslibs/sdk/src/front-mcp/front-mcp.ts.github/workflows/pr-testing-registry.yml
📚 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 : Use proper ES module imports instead of `require()` for SDK imports; avoid dynamic require of `frontmcp/sdk` modules
Applied to files:
libs/sdk/src/front-mcp/front-mcp.ts.github/workflows/pr-testing-registry.ymllibs/sdk/src/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/front-mcp/front-mcp.tslibs/sdk/src/direct/direct-server.tslibs/sdk/src/transport/index.tslibs/sdk/src/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 **/*.{ts,tsx} : Use `frontmcp/utils` for cryptographic operations instead of `node:crypto` directly
Applied to files:
libs/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/index.ts
📚 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/**/*plugin.ts : Use module augmentation for context properties via `declare module 'frontmcp/sdk'` combined with runtime plugin metadata `contextExtensions`, not module-level side effects
Applied to files:
libs/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/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} : Use `unknown` instead of `any` for generic type parameter defaults (not for MCP protocol types)
Applied to files:
libs/sdk/src/front-mcp/front-mcp.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/front-mcp/front-mcp.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/front-mcp/front-mcp.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} : Use type parameters with constraints instead of unconstrained generics with `any` defaults
Applied to files:
libs/sdk/src/front-mcp/front-mcp.ts
📚 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/**/*plugin.ts : Extend ExecutionContextBase with plugin-specific properties using module declaration (`declare module 'frontmcp/sdk'`) combined with `contextExtensions` in plugin metadata
Applied to files:
libs/sdk/src/front-mcp/front-mcp.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/**/{package.json,*.ts,*.tsx,*.js,*.jsx} : Do not add React dependencies to frontmcp/uipack - it must remain React-free. Use frontmcp/ui for React components.
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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/package.json : The frontmcp/ui package requires React as a peer dependency (^18.0.0 || ^19.0.0)
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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: Organize code following the frontmcp/uipack directory structure (adapters/, bundler/, theme/, renderers/, validation/, etc.)
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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/package.json : Entry points must match the documented paths: frontmcp/ui/react, frontmcp/ui/renderers, frontmcp/ui/render, frontmcp/ui/universal, frontmcp/ui/bundler, frontmcp/ui/bridge, frontmcp/ui/components, frontmcp/ui/layouts, frontmcp/ui/web-components
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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/**/{build,bundler}/**/*.{ts,tsx,js,jsx} : For server-side MDX rendering with bundled React, use frontmcp/ui/renderers instead of frontmcp/uipack/renderers
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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: Nx-based monorepo build system - use commands like `nx build sdk`, `nx test ast-guard`, `nx run-many -t test`
Applied to files:
apps/e2e/demo-e2e-direct/project.json
📚 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/sdk/src/direct/direct-server.tslibs/sdk/src/transport/index.tslibs/sdk/src/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/sdk/src/transport/index.tslibs/sdk/src/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/sdk/src/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/renderers/**/*.renderer.ts : Server-side renderers must export both named exports (ReactRenderer, MdxRenderer) and default instances (reactRenderer, mdxRenderer) with consistent interface patterns
Applied to files:
libs/sdk/src/index.ts
📚 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 : Avoid using `node:crypto` directly; always use `frontmcp/utils` for cross-platform cryptographic support
Applied to files:
libs/sdk/src/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} : Centralize record types in common/records and import from there, not from module-specific files
Applied to files:
libs/sdk/src/index.ts
🧬 Code graph analysis (4)
apps/e2e/demo-e2e-direct/src/main.ts (1)
apps/e2e/demo-e2e-public/src/main.ts (1)
FrontMcp(6-15)
apps/e2e/demo-e2e-direct/e2e/direct-usage.e2e.test.ts (7)
apps/e2e/demo-e2e-direct/src/apps/notes/data/notes.store.ts (1)
notesStore(32-32)libs/sdk/src/index.ts (3)
DirectMcpServer(154-154)FrontMcpInstance(21-21)createInMemoryServer(157-157)libs/sdk/src/direct/direct.types.ts (1)
DirectMcpServer(85-170)libs/sdk/src/front-mcp/front-mcp.ts (1)
FrontMcpInstance(17-280)apps/e2e/demo-e2e-direct/src/main.ts (1)
serverConfig(37-37)libs/sdk/src/transport/index.ts (1)
createInMemoryServer(66-66)libs/sdk/src/transport/in-memory-server.ts (1)
createInMemoryServer(89-177)
libs/sdk/src/front-mcp/front-mcp.ts (5)
libs/sdk/src/common/metadata/front-mcp.metadata.ts (2)
FrontMcpConfigInput(222-222)frontMcpMetadataSchema(211-213)libs/sdk/src/direct/direct.types.ts (1)
DirectMcpServer(85-170)libs/sdk/src/direct/direct-server.ts (1)
DirectMcpServerImpl(53-183)libs/sdk/src/scope/scope.instance.ts (1)
Scope(37-384)libs/sdk/src/transport/mcp-handlers/index.ts (1)
createMcpHandlers(17-56)
libs/sdk/src/direct/direct-server.ts (2)
libs/sdk/src/direct/direct.types.ts (3)
DirectAuthContext(22-34)DirectMcpServer(85-170)DirectCallOptions(51-56)libs/sdk/src/common/interfaces/flow.interface.ts (1)
FlowControl(19-43)
⏰ 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 (7)
apps/e2e/demo-e2e-direct/project.json (3)
1-6: LGTM - Well-structured project metadata.The project metadata follows Nx conventions with clear, descriptive tags that will aid in filtering and organizing e2e test projects.
7-27: LGTM - Appropriate build configuration.The build target is correctly configured for a Node.js application with webpack and TypeScript. The
generatePackageJson: trueoption ensures the app can be deployed standalone, which is appropriate for an e2e test application.
28-35: LGTM - Serve target correctly configured.The serve target properly depends on the build target and runs the compiled application from the workspace root.
apps/e2e/demo-e2e-direct/src/main.ts (1)
20-25: Nice: sharedbaseConfigreduces drift between HTTP + direct usage.This matches the goal of keeping demo config consistent across transports.
Also applies to: 27-37
apps/e2e/demo-e2e-direct/e2e/direct-usage.e2e.test.ts (1)
20-186: Strong coverage of direct tool/resource/prompt surface; disposal behavior is asserted.The structure maps well to the new API surface (direct + lifecycle).
libs/sdk/src/front-mcp/front-mcp.ts (1)
104-110: Good: parse config for graph creation to apply defaults consistently.libs/sdk/src/direct/direct-server.ts (1)
169-182: Dispose is idempotent and best-effort cleanup is reasonable here.
PR Testing Registry StoppedThe 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. |
There was a problem hiding this 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
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/pr-testing-registry.yml (1)
138-193: Shell injection vulnerability in ngrok command construction—use bash arrays instead of string concatenation.The code builds
NGROK_CMDas a string and uses unquoted variable expansion ($NGROK_CMD --domain=$NGROK_DOMAINfollowed by$NGROK_CMD --log=stdout), allowing command/argument injection viainputs.ngrok_domain.Additionally:
- After
npm install -g ngrok, use thengrokcommand directly instead ofnpx ngrokto avoid version mismatches or unexpected behavior.- Replace string concatenation with bash arrays and quote expansions to prevent shell injection.
Safer execution with bash arrays
- if [ -n "${NGROK_AUTH_TOKEN:-}" ]; then + if [ -n "${NGROK_AUTH_TOKEN:-}" ]; then echo "Configuring ngrok with auth token..." - npx ngrok config add-authtoken "$NGROK_AUTH_TOKEN" + ngrok config add-authtoken "$NGROK_AUTH_TOKEN" else echo "::warning::NGROK_AUTH_TOKEN not configured. Using ngrok without authentication (random URLs, rate limits may apply)." fi - NGROK_CMD="npx ngrok http 4873" + NGROK_CMD=(ngrok http 4873) if [ -n "${NGROK_DOMAIN:-}" ]; then if [ -z "${NGROK_AUTH_TOKEN:-}" ]; then echo "::error::Custom domain requires NGROK_AUTH_TOKEN to be configured" exit 1 fi echo "Using custom domain: $NGROK_DOMAIN" - NGROK_CMD="$NGROK_CMD --domain=$NGROK_DOMAIN" + NGROK_CMD+=(--domain="$NGROK_DOMAIN") fi # Start ngrok - $NGROK_CMD --log=stdout > /tmp/ngrok.log 2>&1 & + "${NGROK_CMD[@]}" --log=stdout > /tmp/ngrok.log 2>&1 &
🤖 Fix all issues with AI agents
In @.github/workflows/pr-testing-registry.yml:
- Around line 417-503: The workflow prints install commands that reference the
non-existent scoped package @frontmcp/cli and use Yarn Berry's unsupported
--registry flag; update the printed commands by removing any "npm install/yarn
add @frontmcp/cli" entries and replace CLI references with the unscoped package
name frontmcp where appropriate (e.g., npm install -g frontmcp@${VERSION} and
npx frontmcp@${VERSION}), and change all Yarn examples to instruct configuring
registry in .yarnrc.yml (use npmRegistryServer and npmScopes for @frontmcp)
rather than using --registry flags in the yarn add/global commands; keep the
.npmrc instructions for scoped packages as-is and ensure any remaining CLI
instructions that require a registry use npm (or npx --registry) instead of Yarn
flags.
🧹 Nitpick comments (1)
.github/workflows/pr-testing-registry.yml (1)
22-26: Good addition, but treatngrok_domainas untrusted input when building shell commands later.
You use this input to construct a command string later; ensure it can’t inject flags/commands via whitespace/shell metacharacters.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
.github/workflows/pr-testing-registry.yml
🧰 Additional context used
🧠 Learnings (8)
📚 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/**/{package.json,*.ts,*.tsx,*.js,*.jsx} : Do not add React dependencies to frontmcp/uipack - it must remain React-free. Use frontmcp/ui for React components.
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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:
.github/workflows/pr-testing-registry.yml
📚 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 : Use proper ES module imports instead of `require()` for SDK imports; avoid dynamic require of `frontmcp/sdk` modules
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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/package.json : The frontmcp/ui package requires React as a peer dependency (^18.0.0 || ^19.0.0)
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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 file system operations instead of `fs/promises` or `node:fs` directly
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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: Organize code following the frontmcp/uipack directory structure (adapters/, bundler/, theme/, renderers/, validation/, etc.)
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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/package.json : Entry points must match the documented paths: frontmcp/ui/react, frontmcp/ui/renderers, frontmcp/ui/render, frontmcp/ui/universal, frontmcp/ui/bundler, frontmcp/ui/bridge, frontmcp/ui/components, frontmcp/ui/layouts, frontmcp/ui/web-components
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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/**/{build,bundler}/**/*.{ts,tsx,js,jsx} : For server-side MDX rendering with bundled React, use frontmcp/ui/renderers instead of frontmcp/uipack/renderers
Applied to files:
.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: Build Libraries
- GitHub Check: Lint & Format Checks
- GitHub Check: Package E2E (Verdaccio)
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (4)
.github/workflows/pr-testing-registry.yml (4)
200-206: PR version derivation fromlibs/sdk/package.jsonis sensible and semver-friendly.
<current>-pr.<num>.<sha>should work well as a prerelease identifier.
231-246: Nice improvement: publishing/logging the real package name fromdist/package.json.
This should make publish summaries and troubleshooting more accurate (especially for the non-scopedfrontmcpCLI).
296-326: No changes needed.npx --registry=<url>is a supported npm CLI flag and works as written in the code. The flag is correctly positioned before the positional argument (frontmcp@...), which is the required syntax. The code snippet follows documented npx/npm practices and requires no adjustment.Likely an incorrect or invalid review comment.
28-31: Thepull-requests: writepermission is sufficient forgithub.rest.issues.createComment.
GitHub's REST API documentation explicitly allows eitherissues: writeorpull-requests: writefor the create-comment endpoint. The workflow currently has the correct permission to post PR comments, andissues: writeis not required.Likely an incorrect or invalid review comment.
…o handling in direct server
…d improve installation instructions for Yarn
PR Testing Registry StoppedThe temporary npm registry for this PR has been shut down. Reason: Timeout reached To start a new registry, trigger the "PR Testing Registry" workflow again. |
There was a problem hiding this 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
🤖 Fix all issues with AI agents
In @libs/sdk/src/front-mcp/front-mcp.ts:
- Line 160: Change the getScopes() return type from ScopeEntry[] to Scope[] in
both ScopeRegistry.getScopes and ScopeRegistryInterface.getScopes so callers no
longer need to assert types; update the signatures and any related type
imports/usages to reflect Scope[] and remove the unsafe cast at the
DirectMcpServerImpl construction (the new return type guarantees scopes[0] is a
Scope).
In @libs/sdk/src/transport/index.ts:
- Around line 67-80: Add new draft docs under docs/draft/docs that document the
three new public SDK transport exports: createInMemoryServer,
CreateInMemoryServerOptions, and InMemoryServerResult. Provide a brief overview
of each symbol, show usage examples for creating and tearing down an in-memory
MCP server, demonstrate configuring options via CreateInMemoryServerOptions, and
show how to consume the returned InMemoryServerResult (client transport, auth
setter, close), plus integration snippets for the SDK client, LangChain adapter,
and unit/integration testing patterns. Keep the files under docs/draft/docs/**
(not docs/docs/**), include headings, short code snippets, and a simple “when to
use” section for each API.
🧹 Nitpick comments (3)
libs/sdk/src/front-mcp/front-mcp.ts (1)
264-279: Signal handler exits with code 0 even on error.The SIGINT and SIGTERM handlers call
process.exit(0)even whenmcpServer.close()throws an error (lines 268, 276). This masks cleanup failures with a success exit code.Consider using
process.exit(1)when errors occur during shutdown to signal that the process did not terminate cleanly.♻️ Proposed fix
process.on('SIGINT', async () => { try { await mcpServer.close(); + process.exit(0); } catch (err) { console.error('Error closing MCP server:', err); + process.exit(1); } - process.exit(0); }); process.on('SIGTERM', async () => { try { await mcpServer.close(); + process.exit(0); } catch (err) { console.error('Error closing MCP server:', err); + process.exit(1); } - process.exit(0); });libs/sdk/src/direct/direct-server.ts (2)
39-39: Redundant fallback in clientId assignment.Line 39 uses
user.sub ?? 'direct', butuser.subis already guaranteed to be a string by line 37's logic (authContext.user.sub ?? 'direct'). The additional?? 'direct'fallback here is redundant.♻️ Simplify to remove redundant fallback
- const clientId = user.sub ?? 'direct'; + const clientId = user.sub;
116-117: Potential error from JSON.stringify on circular references.Line 117 uses
JSON.stringify(e.output)which could throw a TypeError ife.outputcontains circular references. While unlikely in practice, this could mask the original flow control error with a JSON serialization error.♻️ Add safe stringification
- const details = e.output ? `: ${JSON.stringify(e.output)}` : ''; + const details = e.output + ? `: ${JSON.stringify(e.output, (key, value) => + typeof value === 'object' && value !== null ? '[Circular]' : value + )}` + : ''; throw new InternalMcpError(`Flow ended with ${e.type}${details}`);Or simply omit the output stringification:
- const details = e.output ? `: ${JSON.stringify(e.output)}` : ''; - throw new InternalMcpError(`Flow ended with ${e.type}${details}`); + throw new InternalMcpError(`Flow ended with ${e.type}`);
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
.github/workflows/pr-testing-registry.ymllibs/sdk/src/direct/direct-server.tslibs/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/transport/index.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Use strict TypeScript mode with noanytypes without strong justification
Avoid non-null assertions (!) - use proper error handling and type guards instead
Use@frontmcp/utilsfor cryptographic operations instead ofnode:cryptodirectly
Use@frontmcp/utilsfor file system operations instead offs/promisesornode:fsdirectly
Files:
libs/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/direct/direct-server.tslibs/sdk/src/transport/index.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
UsegetCapabilities()for dynamic capability exposure instead of hardcoding capabilities
Files:
libs/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/direct/direct-server.tslibs/sdk/src/transport/index.ts
libs/sdk/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
libs/sdk/**/*.{ts,tsx}: Preferinterfacefor defining object shapes in TypeScript, avoidanytypes
Use type parameters with constraints instead of unconstrained generics withanydefaults
Validate URIs per RFC 3986 at metadata level usingisValidMcpUrirefinement
UsechangeScopeinstead ofscopein 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 ofPromise<unknown>for MCP entry methods
Useunknowninstead ofanyfor 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/front-mcp/front-mcp.tslibs/sdk/src/direct/direct-server.tslibs/sdk/src/transport/index.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/front-mcp/front-mcp.tslibs/sdk/src/direct/direct-server.tslibs/sdk/src/transport/index.ts
🧠 Learnings (29)
📚 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 : Use proper ES module imports instead of `require()` for SDK imports; avoid dynamic require of `frontmcp/sdk` modules
Applied to files:
libs/sdk/src/front-mcp/front-mcp.ts.github/workflows/pr-testing-registry.ymllibs/sdk/src/transport/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/front-mcp/front-mcp.tslibs/sdk/src/direct/direct-server.tslibs/sdk/src/transport/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 **/*.{ts,tsx} : Use `frontmcp/utils` for file system operations instead of `fs/promises` or `node:fs` directly
Applied to files:
libs/sdk/src/front-mcp/front-mcp.ts.github/workflows/pr-testing-registry.yml
📚 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/**/*plugin.ts : Use module augmentation for context properties via `declare module 'frontmcp/sdk'` combined with runtime plugin metadata `contextExtensions`, not module-level side effects
Applied to files:
libs/sdk/src/front-mcp/front-mcp.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/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/transport/index.ts
📚 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/**/*plugin.ts : Extend ExecutionContextBase with plugin-specific properties using module declaration (`declare module 'frontmcp/sdk'`) combined with `contextExtensions` in plugin metadata
Applied to files:
libs/sdk/src/front-mcp/front-mcp.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} : Use `unknown` instead of `any` for generic type parameter defaults (not for MCP protocol types)
Applied to files:
libs/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/direct/direct-server.tslibs/sdk/src/transport/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} : Validate inputs and outputs through parseOutput/safeParseOutput methods in validation flows
Applied to files:
libs/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/direct/direct-server.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/front-mcp/front-mcp.tslibs/sdk/src/direct/direct-server.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/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/direct/direct-server.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 URIs per RFC 3986 at metadata level using `isValidMcpUri` refinement
Applied to files:
libs/sdk/src/front-mcp/front-mcp.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/**/{src}/**/*.{ts,tsx,js,jsx} : Do not expose internal error details in public APIs - use sanitized error messages
Applied to files:
libs/sdk/src/front-mcp/front-mcp.ts
📚 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 : Do not expose internal error details in public-facing error messages
Applied to files:
libs/sdk/src/front-mcp/front-mcp.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} : Component hooks must properly handle loading and error states when calling MCP tools
Applied to files:
libs/sdk/src/front-mcp/front-mcp.ts
📚 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 : Avoid using `node:crypto` directly; always use `frontmcp/utils` for cross-platform cryptographic support
Applied to files:
libs/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/transport/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 **/*.{ts,tsx} : Avoid non-null assertions (`!`) - use proper error handling and type guards instead
Applied to files:
libs/sdk/src/front-mcp/front-mcp.tslibs/sdk/src/direct/direct-server.ts
📚 Learning: 2025-11-05T15:00:47.800Z
Learnt from: frontegg-david
Repo: agentfront/frontmcp PR: 11
File: libs/core/src/auth/jwks/jwks.service.ts:62-0
Timestamp: 2025-11-05T15:00:47.800Z
Learning: In the FrontMCP codebase (libs/core/src/auth/jwks/jwks.service.ts), the verifyGatewayToken method intentionally skips signature verification when running in development-only no-auth mode, using decodeJwtPayloadSafe instead of jwtVerify. This is a deliberate design for local development convenience and should not be flagged as a security issue when the PR or code context indicates development/no-auth mode.
Applied to files:
libs/sdk/src/direct/direct-server.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} : Do not mutate rawInput in flows - use state.set() for managing flow state instead
Applied to files:
libs/sdk/src/direct/direct-server.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} : Fail fast on invalid hook flows by validating hooks match their entry type
Applied to files:
libs/sdk/src/direct/direct-server.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: Use yarn as the package manager for the monorepo
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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/package.json : The frontmcp/ui package requires React as a peer dependency (^18.0.0 || ^19.0.0)
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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: Organize code following the frontmcp/uipack directory structure (adapters/, bundler/, theme/, renderers/, validation/, etc.)
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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/package.json : Entry points must match the documented paths: frontmcp/ui/react, frontmcp/ui/renderers, frontmcp/ui/render, frontmcp/ui/universal, frontmcp/ui/bundler, frontmcp/ui/bridge, frontmcp/ui/components, frontmcp/ui/layouts, frontmcp/ui/web-components
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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/sdk/src/transport/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} : Centralize record types in common/records and import from there, not from module-specific files
Applied to files:
libs/sdk/src/transport/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 **/*.{ts,tsx} : Use strict TypeScript mode with no `any` types without strong justification
Applied to files:
libs/sdk/src/transport/index.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/**/{src}/**/*.{ts,tsx} : Do not use `any` type without justification in TypeScript code
Applied to files:
libs/sdk/src/transport/index.ts
📚 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 : Avoid using `any` type without justification in TypeScript files
Applied to files:
libs/sdk/src/transport/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/**/*.{ts,tsx} : Avoid using any type without justification; all props, return types, and generics must be properly typed
Applied to files:
libs/sdk/src/transport/index.ts
⏰ 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 (8)
libs/sdk/src/transport/index.ts (1)
32-33: LGTM: Type-only exports are correctly structured.The type-only exports for
TransportTypeandTransportKeyfollow TypeScript best practices and are consistent with the existing export pattern in this barrel file.libs/sdk/src/front-mcp/front-mcp.ts (1)
256-256: LGTM - Type cast justification is clear.The comment on lines 253-255 properly explains why the
anycast is necessary here - the MCP SDK's handler type expects a specific context shape, but the wrapped handlers preserve all context properties via pass-through.libs/sdk/src/direct/direct-server.ts (2)
127-181: LGTM - Strictly typed MCP protocol responses.All operation methods correctly return strictly typed MCP protocol response types (
Promise<ListToolsResult>,Promise<CallToolResult>, etc.) as required by the coding guidelines.
187-200: LGTM - Proper resource cleanup with defensive coding.The dispose method implements proper cleanup with:
- Idempotent behavior (safe to call multiple times)
- Defensive check for transportService existence
- Best-effort cleanup that doesn't throw
- Appropriate use of console.debug for non-critical warnings
.github/workflows/pr-testing-registry.yml (4)
143-157: LGTM - Robust domain validation prevents injection.The domain validation properly prevents command injection by:
- Allowing only safe characters (alphanumeric, dots, hyphens)
- Explicitly rejecting shell metacharacters that could enable command injection
- Validating the format before use
173-189: LGTM - Safe command construction prevents shell injection.The ngrok command construction uses bash arrays with proper expansion (
"${NGROK_ARGS[@]}") which safely prevents shell injection even with untrusted input. Combined with the earlier domain validation, this provides defense-in-depth.
256-262: LGTM - Dynamic package name detection handles scoped and non-scoped packages.The logic correctly handles both scoped (@frontmcp/*) and non-scoped (frontmcp CLI) packages by reading the actual package name from the built package.json, with a sensible fallback for missing names.
322-352: LGTM - Clear documentation distinguishes scoped vs non-scoped packages.The documentation correctly explains that:
- The CLI (
frontmcp) is non-scoped and requires--registryflag- SDK packages (
@frontmcp/*) are scoped and work with.npmrcconfigurationThis helps prevent common user confusion when installing from the test registry.
…d improve installation instructions for Yarn
There was a problem hiding this 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
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
.github/workflows/pr-testing-registry.yml
🧰 Additional context used
🧠 Learnings (8)
📚 Learning: 2025-11-16T22:47:05.139Z
Learnt from: frontegg-david
Repo: agentfront/frontmcp PR: 50
File: docs/docs/v/0.1/getting-started/welcome.mdx:2-3
Timestamp: 2025-11-16T22:47:05.139Z
Learning: In the agentfront/frontmcp repository, the docs/docs/v/** directory governance rule prohibiting manual edits applies to already-frozen releases, but does not preclude initial setup and bootstrap commits that establish the versioned docs structure.
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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: Use yarn as the package manager for the monorepo
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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 : Use proper ES module imports instead of `require()` for SDK imports; avoid dynamic require of `frontmcp/sdk` modules
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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/package.json : The frontmcp/ui package requires React as a peer dependency (^18.0.0 || ^19.0.0)
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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 file system operations instead of `fs/promises` or `node:fs` directly
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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: Organize code following the frontmcp/uipack directory structure (adapters/, bundler/, theme/, renderers/, validation/, etc.)
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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/package.json : Entry points must match the documented paths: frontmcp/ui/react, frontmcp/ui/renderers, frontmcp/ui/render, frontmcp/ui/universal, frontmcp/ui/bundler, frontmcp/ui/bridge, frontmcp/ui/components, frontmcp/ui/layouts, frontmcp/ui/web-components
Applied to files:
.github/workflows/pr-testing-registry.yml
📚 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/**/{build,bundler}/**/*.{ts,tsx,js,jsx} : For server-side MDX rendering with bundled React, use frontmcp/ui/renderers instead of frontmcp/uipack/renderers
Applied to files:
.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: Build Libraries
- GitHub Check: Lint & Format Checks
- GitHub Check: Package E2E (Verdaccio)
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (7)
.github/workflows/pr-testing-registry.yml (7)
22-26: LGTM! Well-defined optional input.The ngrok domain input is properly structured with clear description and sensible defaults.
143-157: Solid domain validation for injection prevention.The two-tier validation approach (format check + dangerous character rejection) effectively prevents command injection. The regex requirement for at least 2 alphanumeric characters is strict but appropriate for ngrok domains.
159-214: Excellent security improvements with array-based command construction.The refactored ngrok setup properly prevents shell injection via array expansion and validates auth token requirements for custom domains. The optional auth token with warnings provides good user experience.
244-304: Robust package name derivation with proper fallback handling.The updated publishing logic correctly derives package names from dist/package.json with appropriate fallback to scoped naming. The use of
jq's// emptyoperator combined with bash null/empty checks provides solid error handling.
305-376: Excellent documentation improvements for registry usage.The expanded artifact documentation clearly explains the distinction between scoped and unscoped packages, provides comprehensive install commands, and includes helpful configuration examples. This significantly improves the user experience.
443-524: Helpful addition for user guidance and debugging.The comprehensive install commands step provides clear, actionable guidance for different package managers and package types. The repeated emphasis on CLI scoping requirements helps prevent common user errors.
215-228: Version calculation logic is sound.All packages in the monorepo share consistent versioning (currently 0.7.2), confirming the assumption that the SDK package.json can serve as the authoritative source for the PR version base. The prerelease version format follows semver conventions correctly.
Summary by CodeRabbit
New Features
Tests
Chores
✏️ Tip: You can customize this high-level summary in your review settings.