Skip to content

Sweetmantech/myc 3643 api mcp mcp server#31

Merged
sweetmantech merged 4 commits intomainfrom
sweetmantech/myc-3643-api-mcp-mcp-server
Dec 6, 2025
Merged

Sweetmantech/myc 3643 api mcp mcp server#31
sweetmantech merged 4 commits intomainfrom
sweetmantech/myc-3643-api-mcp-mcp-server

Conversation

@sweetmantech
Copy link
Contributor

@sweetmantech sweetmantech commented Dec 6, 2025

Summary by CodeRabbit

  • New Features

    • New API endpoint exposing three tools: random number generation, integer addition, and a personalized greeting.
  • Chores

    • Added a dependency to support the new MCP-based API infrastructure.

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

@vercel
Copy link
Contributor

vercel bot commented Dec 6, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Updated (UTC)
recoup-api Ready Ready Preview Dec 6, 2025 4:19am

@coderabbitai
Copy link

coderabbitai bot commented Dec 6, 2025

Walkthrough

Adds a new MCP API route at app/mcp/route.ts that lazily creates and caches a paid MCP handler, registers three MCP tools (get_random_number, add, hello-remote), and exposes GET and POST endpoints. Also adds dependency x402-mcp and three tool-registration modules.

Changes

Cohort / File(s) Summary
MCP API Route
app/mcp/route.ts
New route that lazily initializes a singleton paid MCP handler (via createPaidMcpHandler), registers three tools, and exports GET(req: Request) and POST(req: Request) which delegate to the cached handler.
Tool registrations
lib/mcp/registerGetRandomNumberTool.ts, lib/mcp/registerAddTool.ts, lib/mcp/registerHelloRemoteTool.ts
Three new modules exporting functions that register MCP tools on a PaymentMcpServer: get_random_number (inputs: min, max → returns random integer as text), add (inputs: a, b → returns sum as text), and hello-remote (input: name → returns greeting as text). Use of @ts-expect-error casts for Zod typing compatibility present.
Dependency
package.json
Added dependency: x402-mcp (^0.1.1).

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Route as app/mcp/route.ts
    participant Handler as Paid MCP Handler
    participant Tools as Registered Tools

    rect rgb(200,220,255)
    Note over Client,Route: Initial request (no cached handler)
    Client->>Route: GET/POST /mcp
    Route->>Route: check cached handler
    Route->>Handler: createPaidMcpHandler(serverInfo, context)
    Handler->>Tools: register get_random_number
    Handler->>Tools: register add
    Handler->>Tools: register hello-remote
    Handler-->>Route: handler ready (cached)
    Route-->>Client: proxy response
    end

    rect rgb(220,255,220)
    Note over Client,Route: Subsequent requests (cached handler)
    Client->>Route: GET/POST /mcp
    Route->>Route: retrieve cached handler
    Route->>Handler: forward request
    Handler->>Tools: invoke requested tool
    Tools-->>Handler: tool result
    Handler-->>Route: response
    Route-->>Client: response
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Pay attention to: app/mcp/route.ts lazy initialization and caching logic (singleton lifecycle, error paths).
  • Verify tool input schemas and return payload shapes in lib/mcp/* modules.
  • Inspect @ts-expect-error usage around Zod casts for potential type-safety gaps.
  • Confirm package.json addition and any build implications.

Poem

🐰 A tiny route hopped up at dawn,
Three tools planted seeds on the lawn.
Cached and ready, they leap and play,
Hello, add, and numbers make my day.
Off I twitch — the MCP's on! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is vague and does not clearly describe the main changes. It mentions 'api mcp mcp server' with redundant terminology and lacks specificity about what was added or changed. Revise the title to be more descriptive and specific, such as 'Add MCP server with tools for random numbers, addition, and greetings' or 'Implement MCP handler with three tools and route endpoints'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sweetmantech/myc-3643-api-mcp-mcp-server

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

❤️ Share

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
app/mcp/route.ts (2)

34-48: Remove unnecessary optional chaining.

The optional chaining operators (?.) on lines 45-46 are unnecessary if the Zod schema validation works correctly. The inputSchema guarantees that args.a and args.b are integers, so they cannot be undefined.

Using optional chaining here could mask validation failures (e.g., if args is somehow undefined, args?.a + args?.b silently produces NaN instead of failing explicitly).

Apply this diff to simplify the code:

         async args => {
-          const result = args?.a + args?.b;
-          return { content: [{ type: "text", text: result?.toString() }] };
+          const result = args.a + args.b;
+          return { content: [{ type: "text", text: result.toString() }] };
         },

85-99: Consider adding error handling.

The GET and POST handlers correctly delegate to the shared handler instance. However, consider adding error handling to catch and log any initialization or request processing failures.

Example implementation:

export async function GET(req: Request) {
  try {
    const handler = await getHandler();
    return handler(req);
  } catch (error) {
    console.error('MCP GET handler error:', error);
    return new Response('Internal Server Error', { status: 500 });
  }
}

export async function POST(req: Request) {
  try {
    const handler = await getHandler();
    return handler(req);
  } catch (error) {
    console.error('MCP POST handler error:', error);
    return new Response('Internal Server Error', { status: 500 });
  }
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c43ab10 and 6a542cf.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • app/mcp/route.ts (1 hunks)
  • package.json (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
app/mcp/route.ts (1)
lib/const.ts (1)
  • SMART_ACCOUNT_ADDRESS (4-4)
⏰ 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). (1)
  • GitHub Check: Vercel Agent Review
🔇 Additional comments (2)
app/mcp/route.ts (2)

1-6: LGTM!

The imports and singleton handler pattern are appropriate for a Next.js API route. The lazy initialization approach ensures the handler is only created when needed.


49-61: LGTM!

The hello-remote tool implementation is clean and correct. The type assertion as const appropriately narrows the type for the content object.

},
},
async (args: { min: number; max: number }) => {
const randomNumber = Math.floor(Math.random() * (args.max - args.min + 1)) + args.min;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const randomNumber = Math.floor(Math.random() * (args.max - args.min + 1)) + args.min;
const min = Math.min(args.min, args.max);
const max = Math.max(args.min, args.max);
const randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;

The random number generation function doesn't validate that min is less than or equal to max. When min > max, the formula produces incorrect results instead of either swapping the values or returning an error.

View Details

Analysis

Random number generation function fails to handle min > max

What fails: The registerGetRandomNumberTool() function in lib/mcp/registerGetRandomNumberTool.ts generates incorrect random numbers when min > max, violating the documented contract: "Generates a random number between min and max (inclusive)."

How to reproduce:

// Simulate the original buggy implementation
const min = 5, max = 1;
const randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;
// Math.random() * (1 - 5 + 1) = Math.random() * (-3)
// Results in values between 2-4, never reaching full range

Result: When calling with min=5, max=1, the function returns values in range [2, 4] instead of generating a number between the min and max values.

Expected: The function should either:

  1. Swap the parameters internally to handle reversed inputs (implemented fix)
  2. Return an error for invalid input

Fix implemented: Added normalization to handle any parameter order:

const min = Math.min(args.min, args.max);
const max = Math.max(args.min, args.max);
const randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;

This ensures the function generates random numbers in the correct range regardless of parameter order, maintaining the documented contract.

@sweetmantech sweetmantech merged commit 421e15d into main Dec 6, 2025
2 of 3 checks passed
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
app/mcp/route.ts (1)

24-27: Consider sourcing serverInfo name/version from configuration instead of hardcoding.

Using "recoup-mcp" and "0.0.1" works, but these values are likely to change over time. Reading them from a central config or environment variables (with sensible defaults) would keep MCP metadata in sync with your actual service name and version without code changes.

lib/mcp/registerGetRandomNumberTool.ts (1)

21-26: Validate that min is not greater than max before generating the random number.

If a caller passes min > max, (args.max - args.min + 1) becomes negative and the returned value will be outside the intended range.

Add a simple guard before computing the random value:

-    async (args: { min: number; max: number }) => {
-      const randomNumber = Math.floor(Math.random() * (args.max - args.min + 1)) + args.min;
+    async (args: { min: number; max: number }) => {
+      if (args.min > args.max) {
+        throw new Error("min must be less than or equal to max");
+      }
+      const randomNumber = Math.floor(Math.random() * (args.max - args.min + 1)) + args.min;
       return {
         content: [{ type: "text", text: randomNumber.toString() }],
       };
     },
🧹 Nitpick comments (1)
lib/mcp/registerAddTool.ts (1)

14-18: Reduce repeated @ts-expect-error casts for the input schema.

The add tool (and other MCP tools) repeat the same @ts-expect-error cast for Zod number schemas. That works, but it scatters a fragile type suppression across multiple files and could hide future type drift between your Zod version and x402-mcp’s expectations.

Consider centralizing this into a small helper or alias so the suppression lives in one place, for example:

// e.g. in a shared mcp/zod-compat module
// @ts-expect-error - Zod version mismatch with x402-mcp types
export const intNumberSchema = z.number().int() as z.ZodType<number>;

and then:

inputSchema: {
  a: intNumberSchema,
  b: intNumberSchema,
}

This keeps runtime behavior unchanged while making the type workaround easier to audit and eventually remove.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6a542cf and 8c71308.

📒 Files selected for processing (4)
  • app/mcp/route.ts (1 hunks)
  • lib/mcp/registerAddTool.ts (1 hunks)
  • lib/mcp/registerGetRandomNumberTool.ts (1 hunks)
  • lib/mcp/registerHelloRemoteTool.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
app/mcp/route.ts (4)
lib/mcp/registerGetRandomNumberTool.ts (1)
  • registerGetRandomNumberTool (10-28)
lib/mcp/registerAddTool.ts (1)
  • registerAddTool (10-26)
lib/mcp/registerHelloRemoteTool.ts (1)
  • registerHelloRemoteTool (10-24)
lib/const.ts (1)
  • SMART_ACCOUNT_ADDRESS (4-4)
⏰ 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). (1)
  • GitHub Check: Vercel Agent Review
🔇 Additional comments (2)
lib/mcp/registerHelloRemoteTool.ts (1)

10-23: LGTM – greeting tool registration is clear and consistent.

The schema, handler signature, and returned content structure align with the other MCP tools and look good as-is.

app/mcp/route.ts (1)

15-37: Lazy singleton initialization of the MCP handler looks good.

The getHandler pattern cleanly ensures tools are registered once and the same createPaidMcpHandler instance is reused by both GET and POST, which keeps setup overhead low and avoids duplicated registration logic.

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

Comments