Skip to content

Conversation

smakosh
Copy link
Member

@smakosh smakosh commented Sep 27, 2025

  • Added functionality to handle GitHub personal access tokens for MCP tools.
  • Introduced a new button and dialog in the prompt input for token management.
  • Updated chat API to pass the GitHub token when available.
  • Removed the user provider component as it was no longer needed.
  • Enhanced state management for GitHub token in the API key hook.

Summary by CodeRabbit

  • New Features

    • Added GitHub connector: configure and persist a token in-app; token is sent with chat requests to enable MCP initialization and tools.
    • MCP tools are now included in streaming responses to the model.
  • Bug Fixes

    • Enforced authorized user check (401) and clearer gateway error handling (500).
    • Improved tool display titles and minor type cleanup.
    • Added API key fallback from request header when missing.
  • Chores

    • Removed legacy user provider and deprecated user headers from requests.

…nents

- Added functionality to handle GitHub personal access tokens for MCP tools.
- Introduced a new button and dialog in the prompt input for token management.
- Updated chat API to pass the GitHub token when available.
- Removed the user provider component as it was no longer needed.
- Enhanced state management for GitHub token in the API key hook.
@smakosh smakosh requested a review from steebchen September 27, 2025 23:07
@smakosh smakosh self-assigned this Sep 27, 2025
Copy link

bunnyshell bot commented Sep 27, 2025

❌ Preview Environment deleted from Bunnyshell

Available commands (reply to this comment):

  • 🚀 /bns:deploy to deploy the environment

Copy link
Contributor

coderabbitai bot commented Sep 27, 2025

Walkthrough

Enables MCP initialization in the chat API when a GitHub token is provided, adds githubToken to request payloads from the UI, introduces a connectors button to manage the token via localStorage, passes tools to the LLM gateway stream, removes UserProvider, and extends the API key hook to manage GitHub token state.

Changes

Cohort / File(s) Summary of edits
Chat API route
apps/playground/src/app/api/chat/route.ts
Activates MCP client creation via StreamableHTTPClientTransport when githubToken is present; adds githubToken to ChatRequestBody; enforces authorized user (401 if absent); sources API key from header fallback; passes MCP tools to LLM gateway stream; adjusts error handling (400/500).
Prompt input connectors UI
apps/playground/src/components/ai-elements/prompt-input.tsx
Adds PromptInputConnectorsButton with dialog to view/save/clear GitHub token in localStorage (llmgateway_github_token); introduces related UI components and Github icon; exports the new component.
Playground chat UI integration
apps/playground/src/components/playground/chat-ui.tsx
Renders PromptInputConnectorsButton; includes githubToken from localStorage in chat request bodies; updates ToolHeader usage (type as tool-${toolName}, adds title prop); minor typing cleanup.
API key and token hook
apps/playground/src/hooks/useApiKey.ts
Extends hook to manage GitHub token alongside API key; syncs from localStorage and storage events; exposes githubToken plus setGithubMcpToken/clearGithubMcpToken; emits GITHUB_TOKEN_CHANGED_EVENT; error handling mirrors API key paths.
Auth provider removal
apps/playground/src/components/auth/user-provider.tsx
Removes UserProvider component and its props interface; deletes client-side cache priming for /user/me.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant UI as Playground UI
  participant API as POST /api/chat
  participant MCP as MCP Client
  participant LLM as LLM Gateway

  UI->>API: Send chat request {messages, model, githubToken?, apiKey?}
  alt Authorized user missing
    API-->>UI: 401 Unauthorized
  else Valid request
    opt githubToken provided
      API->>MCP: Initialize transport (auth: githubToken)
      MCP-->>API: Connected + tools
    end
    API->>LLM: stream({messages, model, tools?, apiKey/header})
    alt Gateway success
      LLM-->>API: Stream tokens/events
      API-->>UI: Stream response
    else Gateway failure
      API-->>UI: 500 Error
    end
  end
Loading
sequenceDiagram
  autonumber
  participant User as User
  participant UI as PromptInputConnectorsButton
  participant LS as localStorage
  participant Chat as chat-ui.tsx

  User->>UI: Open Connectors dialog
  User->>UI: Enter/clear GitHub token
  UI->>LS: Save/remove llmgateway_github_token
  Note over UI,Chat: Token change event dispatched
  Chat->>LS: Read token when sending message
  Chat->>API: Include githubToken in request payload
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • steebchen

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title follows a concise conventional commit style and clearly communicates the primary addition of Connectors (MCPs) to the playground, which aligns with the main objective of integrating GitHub token support and MCP functionality.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/github-mcp

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
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
apps/playground/src/app/api/chat/route.ts (1)

25-56: Avoid caching the GitHub MCP client between requests

githubMCP/tools live at module scope, so the first request that supplies a token seeds a shared client for all subsequent requests (even for other users or when the token changes). That leaks credentials, reuses stale authorization, and lets tokenless calls keep using the prior user’s tools. Instantiate the MCP client inside the handler per request (or at least per token) instead of reusing a singleton.

-let githubMCP: experimental_MCPClient | null = null;
-let tools: any | null = null;
+type MCPClientTools = Awaited<
+	ReturnType<experimental_MCPClient["tools"]>
+> | undefined;
 
 export async function POST(req: Request) {
   const user = await getUser();
@@
-	if (!githubMCP && githubToken) {
-		const transport = new StreamableHTTPClientTransport(
+	let tools: MCPClientTools;
+	if (githubToken) {
+		const transport = new StreamableHTTPClientTransport(
 			new URL("https://api.githubcopilot.com/mcp"),
 			{
 				requestInit: {
 					method: "POST",
 					headers: {
 						Authorization: `Bearer ${githubToken}`,
 					},
 				},
 			},
 		);
-		githubMCP = await experimental_createMCPClient({ transport });
-
-		if (!tools) {
-			tools = await githubMCP.tools();
-		}
+		const githubMCP = await experimental_createMCPClient({ transport });
+		tools = await githubMCP.tools();
 	}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c11c04c and 5f16cbb.

📒 Files selected for processing (5)
  • apps/playground/src/app/api/chat/route.ts (3 hunks)
  • apps/playground/src/components/ai-elements/prompt-input.tsx (3 hunks)
  • apps/playground/src/components/auth/user-provider.tsx (0 hunks)
  • apps/playground/src/components/playground/chat-ui.tsx (5 hunks)
  • apps/playground/src/hooks/useApiKey.ts (3 hunks)
💤 Files with no reviewable changes (1)
  • apps/playground/src/components/auth/user-provider.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Never use any or as any in this TypeScript project unless absolutely necessary
Always use top-level import; never use require or dynamic import()

Files:

  • apps/playground/src/components/playground/chat-ui.tsx
  • apps/playground/src/hooks/useApiKey.ts
  • apps/playground/src/components/ai-elements/prompt-input.tsx
  • apps/playground/src/app/api/chat/route.ts
{apps,packages}/**/src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Always use top-level import; never use require() or dynamic import()

Files:

  • apps/playground/src/components/playground/chat-ui.tsx
  • apps/playground/src/hooks/useApiKey.ts
  • apps/playground/src/components/ai-elements/prompt-input.tsx
  • apps/playground/src/app/api/chat/route.ts
🧬 Code graph analysis (1)
apps/playground/src/components/playground/chat-ui.tsx (2)
apps/playground/src/components/ai-elements/tool.tsx (1)
  • ToolHeader (64-87)
apps/playground/src/components/ai-elements/prompt-input.tsx (1)
  • PromptInputConnectorsButton (545-613)
⏰ 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). (5)
  • GitHub Check: test / run
  • GitHub Check: build / run
  • GitHub Check: generate / run
  • GitHub Check: lint / run
  • GitHub Check: autofix
🔇 Additional comments (3)
apps/playground/src/components/playground/chat-ui.tsx (3)

204-210: Nice UI improvement for tool headers.

Passing the tool name into both the type and title fields keeps the collapsible labels meaningful for MCP responses. Looks good.


308-314: Good call on piping the GitHub token through the chat request.

Fetching from localStorage with a browser guard and normalizing to undefined fits the transport expectations cleanly.


342-348: Appreciate the dedicated connectors entry point.

Surfacing the GitHub token dialog alongside the existing tools menu keeps the UX focused without extra chrome.

Comment on lines +557 to +566
const save = () => {
if (typeof window !== "undefined") {
if (token) {
localStorage.setItem("llmgateway_github_token", token);
} else {
localStorage.removeItem("llmgateway_github_token");
}
}
setOpen(false);
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Dispatch the GitHub token change event after persisting

useApiKey relies on the llmgateway_github_token_changed custom event to refresh githubToken. Saving here only mutates localStorage, so components using useApiKey keep the stale value, meaning chat requests continue without the new token until the page is reloaded. Please emit the event (and on clear as well) so in-tab consumers update immediately.

 const save = () => {
   if (typeof window !== "undefined") {
     if (token) {
       localStorage.setItem("llmgateway_github_token", token);
     } else {
       localStorage.removeItem("llmgateway_github_token");
     }
+    window.dispatchEvent(new Event("llmgateway_github_token_changed"));
   }
   setOpen(false);
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const save = () => {
if (typeof window !== "undefined") {
if (token) {
localStorage.setItem("llmgateway_github_token", token);
} else {
localStorage.removeItem("llmgateway_github_token");
}
}
setOpen(false);
};
const save = () => {
if (typeof window !== "undefined") {
if (token) {
localStorage.setItem("llmgateway_github_token", token);
} else {
localStorage.removeItem("llmgateway_github_token");
}
window.dispatchEvent(new Event("llmgateway_github_token_changed"));
}
setOpen(false);
};
🤖 Prompt for AI Agents
In apps/playground/src/components/ai-elements/prompt-input.tsx around lines 557
to 566, saving/removing the GitHub token only updates localStorage which leaves
in-tab consumers using useApiKey stale; after calling localStorage.setItem or
localStorage.removeItem dispatch a browser event so listeners refresh: create
and dispatch a CustomEvent named "llmgateway_github_token_changed" (only when
window is defined) immediately after persisting or clearing the token so other
components update their githubToken without a reload, then close the modal as
before.

@smakosh smakosh changed the title feat(playground): integrate GitHub token support in chat and UI compo… feat(playground): Add Connectors aka MCPs Sep 28, 2025
@smakosh smakosh removed the request for review from steebchen September 28, 2025 15:17
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