Skip to content

Tier 4: typed signatures, dotted naming, modern MCP fields, and Arazzo workflows - #28

Merged
frontegg-david merged 10 commits into
mainfrom
typescript-and-azzoro
Aug 13, 2026
Merged

Tier 4: typed signatures, dotted naming, modern MCP fields, and Arazzo workflows#28
frontegg-david merged 10 commits into
mainfrom
typescript-and-azzoro

Conversation

@frontegg-david

@frontegg-david frontegg-david commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Tier 4 of the roadmap — the strategic bets. Four features, each landed as a single commit with its tests and docs, each followed by an adversarial review pass whose confirmed findings landed as a fix: commit. 1,029 tests, 100% statements/branches/functions/lines enforced throughout.

T4-1 — TypeScript call signatures (emitTypeSignatures)

generateTools({ emitTypeSignatures: true }) renders each tool's call contract as metadata.typescript = { signature, declaration } — a one-line arrow type plus a self-contained declaration block (JSDoc from schema descriptions, named <ToolName>Input/<ToolName>Output types, declare function). Computed on the FINAL schemas (post formats/depth/trims/client-target); recomputed on collision-dedup renames; return types are the unwrapped response (FrontMCP's {status, ok, data, error} wrapping happens downstream). Also exported standalone (emitToolTypeScript, toPascalIdentifier). Review hardening: union/intersection roots emit type aliases (never invalid interface X {...} | {...}), */* content-types and statuses escaped in variant comments, reserved-word function names suffixed (deletedelete_), printer depth follows maxSchemaDepth, non-finite literals degrade to number, crafted cyclic type arrays can't overflow the stack.

T4-1b — dottedNaming preset

Opt-in naming preset producing two-segment ns.method names bindable as CodeCall sandbox namespaces (await billing.listInvoices({...})): first tag → first path segment → api, exactly one dot, both halves identifier-safe. NamingStrategy.conflictResolver is now optional (defaults to the location-prefix resolver) and toolNameGenerator receives the operation as a 4th argument. Review hardening: digit-leading namespaces get a letter guard (3rd-partyn3rd_party — a _ guard would be trimmed by name normalization), the reserved list mirrors CodeCall's actual sandbox globals, and class-based strategies keep their this binding.

T4-3 — Modern-spec surface

  • _meta on tools: opt-in emitMeta emits dev.agentfront.openapi/operation (path/method/operationId/tags/deprecated/specTitle/specVersion); x-mcp.meta / x-frontmcp.meta pass through even without the flag. The reserved dev.agentfront.openapi/ namespace cannot be spoofed by extensions, and pollution-gadget keys (__proto__/constructor/prototype) are stripped recursively (confirmed exploitable via both JSON and YAML parse paths before the fix).
  • icons on tools from x-frontmcp.icons/x-mcp.icons, plus opt-in info['x-logo'] fallback (inheritDocumentIcons); src restricted to https:/data: per the documented contract.
  • x-mcp-header markers on every header-located input property (always on; survives conflict renames and all client targets) so generic bridges can route headers without the mapper.
  • deriveSecurityElicitations(tool) — MCP-elicitation-shaped { message, requestedSchema } credential descriptors per security scheme (bearer/basic/digest/apiKey/oauth2/oidc), pure data.

T4-2 — fromArazzo() (full Arazzo 1.0)

One consolidated McpOpenAPITool per workflow: inputs → input schema, outputs → best-effort derived output schema, and a pure serializable IR on metadata.workflow — each operation step embeds its resolved inputSchema/outputSchema/mapper/security/servers so executors need no second spec pass (operation.mapper feeds buildHttpRequest directly). Multi-source (sources map; URLs never fetched), operationId/operationPath/nested-workflowId steps, full runtime-expression AST (incl. $message.), $components inlining (dotted names supported), reusable objects fully re-validated after resolution, dependsOn/invocation cycle detection with cross-document dependsOn expressions carried verbatim, request bodies with pointer-keyed expression substitution lists, and the same schema pipeline as generateTool (ArazzoGenerateOptions, including emitTypeSignatures). Documents are normalized via a JSON round-trip: YAML anchors expand (every aliased expression occurrence is recorded), YAML-only scalars become JSON forms, cyclic/absurdly-deep inputs fail as ArazzoError instead of crashing. New ArazzoError carries a JSON-Pointer path for every failure.

New docs

docs/type-signatures.md, docs/modern-mcp-fields.md, docs/arazzo.md, plus updates to naming-strategies, configuration, api-reference, x-frontmcp, annotations, README, CLAUDE.md.

Test plan

  • yarn test:coverage — 1,029 tests, 100% statements/branches/functions/lines (enforced), exit 0
  • npx tsc -p tsconfig.lib.json --noEmit — clean
  • yarn build — CJS + ESM + declarations clean
  • Four adversarial review passes (one per feature commit); every confirmed finding fixed with a regression test — including three classes of invalid-TypeScript emission, a confirmed prototype-pollution forwarding gadget, namespace-binding loss under name normalization, and five Arazzo spec-conformance gaps verified against the published 1.0 spec

Summary by CodeRabbit

  • New Features
    • Added Arazzo workflow support with runtime expressions, validation, source resolution, and consolidated workflow tools.
    • Added TypeScript call-signature and declaration generation.
    • Added tool metadata, icons, header annotations, and security elicitation descriptors.
    • Added dotted namespace.method naming presets with collision handling.
    • Exposed new workflow, naming, elicitation, and type-signature APIs.
  • Documentation
    • Added guides and API references for workflows, modern MCP fields, signatures, configuration, naming, and icons.
  • Tests
    • Expanded coverage for workflows, metadata, naming, signatures, and security behavior.

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0ae33249-60b3-4b91-855b-28a833c8eec3

📥 Commits

Reviewing files that changed from the base of the PR and between 2470c65 and ae80ad3.

📒 Files selected for processing (1)
  • docs/x-frontmcp.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/x-frontmcp.md

Walkthrough

The PR adds Arazzo workflow conversion, runtime-expression parsing, TypeScript tool contracts, dotted naming, security elicitations, MCP metadata, icons, wire-header preservation, public exports, documentation, and tests.

Changes

MCP generation extensions

Layer / File(s) Summary
Public contracts and exports
src/arazzo-types.ts, src/types.ts, src/errors.ts, src/index.ts, docs/api-reference.md
Adds public types, options, errors, APIs, and exports for Arazzo, workflow IR, runtime expressions, icons, metadata, signatures, naming, and security elicitations.
Arazzo parsing and workflow conversion
src/arazzo.ts, src/arazzo-expressions.ts, src/__tests__/arazzo.spec.ts, docs/arazzo.md
Validates Arazzo input, resolves sources and operations, builds workflow IR, derives output schemas, parses expressions, and emits consolidated workflow tools.
Metadata, icons, and wire-header preservation
src/annotations.ts, src/generator.ts, src/parameter-resolver.ts, src/__tests__/annotations.spec.ts, src/__tests__/generator.spec.ts, docs/modern-mcp-fields.md, docs/x-frontmcp.md
Adds sanitized extension metadata, icon precedence and validation, optional operation metadata, document-logo inheritance, and x-mcp-header preservation.
TypeScript signatures and naming strategies
src/type-signature.ts, src/naming-presets.ts, src/__tests__/type-signature.spec.ts, src/__tests__/naming-presets.spec.ts, docs/type-signatures.md, docs/naming-strategies.md
Adds schema-to-TypeScript rendering, dotted tool naming, collision handling, and expanded naming callbacks.
Security elicitations and documentation
src/elicitation.ts, src/__tests__/elicitation.spec.ts, docs/*.md, README.md, CLAUDE.md, jest.config.js
Adds security-scheme elicitation descriptors and documents the new APIs, fields, configuration, errors, and type-only coverage exclusion.

Estimated code review effort: 5 (Critical) | ~120 minutes

Mergeability Score: 🔵 Low · up to ae80a

The PR adds substantial new API and workflow capabilities, but the documentation example for accessing tool metadata and icons remains incomplete and could mislead users. Merge is reasonable with explicit owner follow-up to correct that example.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant fromArazzo
  participant generateTools
  participant parseRuntimeExpression
  Caller->>fromArazzo: Submit Arazzo document and OpenAPI sources
  fromArazzo->>generateTools: Resolve source operations and schemas
  fromArazzo->>parseRuntimeExpression: Parse workflow expressions
  parseRuntimeExpression-->>fromArazzo: Return expression ASTs
  fromArazzo-->>Caller: Return consolidated MCP workflow tools
Loading

Possibly related PRs

Poem

A rabbit maps workflows bright,
With dotted names aligned just right.
Icons bloom and schemas sing,
Runtime paths link everything.
“Typed tools!” the rabbit cheers,
As Arazzo takes to MCP’s ears. 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 49.35% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the four main feature areas added by the pull request.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch typescript-and-azzoro

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

Comment thread src/__tests__/annotations.spec.ts Fixed
Comment thread src/__tests__/type-signature.spec.ts Fixed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (2)
src/generator.ts (1)

236-260: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider sharing one icon-source validator.

iconsFromInfoLogo repeats the https:/data: scheme rule that isAllowedIconSrc implements in src/annotations.ts. Export one helper and call it from both places, so the two paths cannot drift.

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

In `@src/generator.ts` around lines 236 - 260, The icon scheme validation is
duplicated between iconsFromInfoLogo and isAllowedIconSrc. Export the existing
validator from annotations.ts, then reuse it in iconsFromInfoLogo instead of
maintaining a separate https:/data: check, preserving the current
accepted-source behavior in both paths.
src/__tests__/integration.spec.ts (1)

743-744: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Prefer a static import of the barrel over require.

require('../index') returns an untyped module and can trip @typescript-eslint/no-require-imports in a TypeScript spec. A namespace import keeps the public-entrypoint-only rule and restores type checking on the asserted fields.

♻️ Proposed refactor
-describe('Tier 4 surface through the entrypoint', () => {
-  /* eslint-disable `@typescript-eslint/no-explicit-any` */
-  const lib = require('../index');
+import * as lib from '../index';
+
+describe('Tier 4 surface through the entrypoint', () => {
+  /* eslint-disable `@typescript-eslint/no-explicit-any` */

Move the import to the top of the file with the other imports.

As per coding guidelines: "Integration tests: src/__tests__/integration.spec.ts (full pipeline, imports from entrypoint only)". A static import of ../index still satisfies that rule.

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

In `@src/__tests__/integration.spec.ts` around lines 743 - 744, Replace the
dynamic require in integration.spec.ts with a top-level namespace import from
../index, remove the explicit-any ESLint suppression, and update usages as
needed so the asserted public-entrypoint fields retain static type checking.

Source: Coding guidelines

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

Inline comments:
In `@docs/annotations.md`:
- Line 45: Update the documentation references for extension overrides: in
docs/annotations.md, revise the x-frontmcp section statement and the
extractExtensionOverrides result to include meta and icons; in
docs/x-frontmcp.md, extend the FrontMcpExtensionData type definition with meta
and icons.

In `@docs/naming-strategies.md`:
- Around line 113-118: Update the documented NamingStrategy interface block to
match the exported type: make conflictResolver optional with the default
location-prefix behavior, and change toolNameGenerator to accept the fourth
operation argument. Keep the surrounding naming strategy documentation
unchanged.

In `@src/__tests__/annotations.spec.ts`:
- Around line 277-282: Update the test “cleanses meta arrays and scalars in
place” to construct the array item via JSON.parse, matching the setup used by
the nearby test around line 267, so __proto__ is an own key and the assertion
verifies cleanseMeta removes it from nested array objects.

In `@src/arazzo.ts`:
- Around line 396-401: Guard both document-supplied component lookups in
src/arazzo.ts:396-401 and src/arazzo.ts:424-428 with
Object.prototype.hasOwnProperty.call and require the resolved target to be an
object before accepting it. Update the $components parameters lookup around the
existing expectedGroup/name logic and the components.inputs lookup before
toJsonSchema, preserving the existing unknown-reference ArazzoError behavior for
inherited, missing, or non-object values.

In `@src/type-signature.ts`:
- Around line 365-374: Update the empty-properties branch in paramList to
recognize root oneOf, anyOf, allOf, enum, or const schemas as data-carrying and
return an input parameter instead of '()'. Preserve the existing no-argument
behavior only for genuinely closed, empty object roots, and add a test covering
a root oneOf input schema through the standalone entrypoint.

---

Nitpick comments:
In `@src/__tests__/integration.spec.ts`:
- Around line 743-744: Replace the dynamic require in integration.spec.ts with a
top-level namespace import from ../index, remove the explicit-any ESLint
suppression, and update usages as needed so the asserted public-entrypoint
fields retain static type checking.

In `@src/generator.ts`:
- Around line 236-260: The icon scheme validation is duplicated between
iconsFromInfoLogo and isAllowedIconSrc. Export the existing validator from
annotations.ts, then reuse it in iconsFromInfoLogo instead of maintaining a
separate https:/data: check, preserving the current accepted-source behavior in
both paths.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 15db536f-1e29-4eab-9858-3249ce09a51d

📥 Commits

Reviewing files that changed from the base of the PR and between 807ab81 and f94a527.

📒 Files selected for processing (31)
  • CLAUDE.md
  • README.md
  • docs/annotations.md
  • docs/api-reference.md
  • docs/arazzo.md
  • docs/configuration.md
  • docs/modern-mcp-fields.md
  • docs/naming-strategies.md
  • docs/type-signatures.md
  • docs/x-frontmcp.md
  • jest.config.js
  • src/__tests__/annotations.spec.ts
  • src/__tests__/arazzo.spec.ts
  • src/__tests__/elicitation.spec.ts
  • src/__tests__/errors.spec.ts
  • src/__tests__/generator.spec.ts
  • src/__tests__/integration.spec.ts
  • src/__tests__/naming-presets.spec.ts
  • src/__tests__/type-signature.spec.ts
  • src/annotations.ts
  • src/arazzo-expressions.ts
  • src/arazzo-types.ts
  • src/arazzo.ts
  • src/elicitation.ts
  • src/errors.ts
  • src/generator.ts
  • src/index.ts
  • src/naming-presets.ts
  • src/parameter-resolver.ts
  • src/type-signature.ts
  • src/types.ts

Comment thread docs/annotations.md
Comment thread docs/naming-strategies.md
Comment thread src/__tests__/annotations.spec.ts
Comment thread src/arazzo.ts
Comment thread src/type-signature.ts
…okup guards, composed input roots, and doc sync

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@docs/x-frontmcp.md`:
- Around line 188-189: Update the FrontMcpExtensionData access example to
destructure both meta and icons alongside the existing fields, keeping the
example synchronized with the documented type definition.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: dfb6844d-ccbd-47b6-bf3b-b8166d61144a

📥 Commits

Reviewing files that changed from the base of the PR and between f94a527 and 2470c65.

📒 Files selected for processing (10)
  • docs/annotations.md
  • docs/naming-strategies.md
  • docs/x-frontmcp.md
  • src/__tests__/annotations.spec.ts
  • src/__tests__/arazzo.spec.ts
  • src/__tests__/type-signature.spec.ts
  • src/annotations.ts
  • src/arazzo.ts
  • src/generator.ts
  • src/type-signature.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/tests/annotations.spec.ts
  • src/annotations.ts
  • docs/annotations.md
  • src/type-signature.ts
  • src/generator.ts
  • src/arazzo.ts

Comment thread docs/x-frontmcp.md
@frontegg-david
frontegg-david merged commit eb07387 into main Aug 13, 2026
8 checks passed
@frontegg-david
frontegg-david deleted the typescript-and-azzoro branch August 13, 2026 00:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant