Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ jobs:
path: |
charts/*/dist/*
chat/*/dist/*
mcp-ui/*/dist/*
packages/*/dist/*
tools/*/dist/*
key: ${{ runner.os }}-build-cache-${{ hashFiles('package.json', 'pnpm-lock.yaml', '**/src/') }}
Expand Down Expand Up @@ -64,7 +65,7 @@ jobs:

- name: Build
if: ${{ steps.build-cache.outputs.cache-hit != 'true' }}
run: pnpm build
run: pnpm build:packages

- uses: actions/cache/save@v4
name: Save build cache
Expand All @@ -73,6 +74,7 @@ jobs:
path: |
charts/*/dist/*
chat/*/dist/*
mcp-ui/*/dist/*
packages/*/dist/*
tools/*/dist/*
key: ${{ steps.build-cache.outputs.cache-primary-key }}
Expand Down Expand Up @@ -111,6 +113,7 @@ jobs:
path: |
charts/*/dist/*
chat/*/dist/*
mcp-ui/*/dist/*
packages/*/dist/*
tools/*/dist/*
key: ${{needs.build.outputs.cache-primary-key}}
Expand Down Expand Up @@ -150,6 +153,7 @@ jobs:
path: |
charts/*/dist/*
chat/*/dist/*
mcp-ui/*/dist/*
packages/*/dist/*
tools/*/dist/*
key: ${{needs.build.outputs.cache-primary-key}}
Expand Down Expand Up @@ -201,6 +205,7 @@ jobs:
path: |
charts/*/dist/*
chat/*/dist/*
mcp-ui/*/dist/*
packages/*/dist/*
tools/*/dist/*
key: ${{needs.build.outputs.cache-primary-key}}
Expand Down Expand Up @@ -246,6 +251,7 @@ jobs:
path: |
charts/*/dist/*
chat/*/dist/*
mcp-ui/*/dist/*
packages/*/dist/*
tools/*/dist/*
key: ${{needs.build.outputs.cache-primary-key}}
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/react17.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ jobs:
path: |
charts/*/dist/*
chat/*/dist/*
mcp-ui/*/dist/*
packages/*/dist/*
tools/*/dist/*
key: ${{ runner.os }}-REACT17-build-cache-${{ hashFiles('package.json', 'pnpm-lock.yaml', '**/src/') }}
Expand All @@ -51,7 +52,7 @@ jobs:
run: pnpm install --prefer-offline # Intentionally not using --frozen-lockfile to allow for pnpm-lock.yaml updates

- name: Build packages
run: pnpm build
run: pnpm build --filter=!'@lg-apps/*'

- uses: actions/cache/save@v4
name: Save build cache
Expand All @@ -60,6 +61,7 @@ jobs:
path: |
charts/*/dist/*
chat/*/dist/*
mcp-ui/*/dist/*
packages/*/dist/*
tools/*/dist/*
key: ${{ steps.build-cache.outputs.cache-primary-key }}
Expand All @@ -85,6 +87,7 @@ jobs:
path: |
charts/*/dist/*
chat/*/dist/*
mcp-ui/*/dist/*
packages/*/dist/*
tools/*/dist/*
key: ${{needs.build.outputs.cache-primary-key}}
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ jobs:
chat/*/dist/*
chat/*/tsdoc.json
chat/*/stories.js
mcp-ui/*/dist/*
packages/*/dist/*
packages/*/tsdoc.json
packages/*/stories.js
Expand All @@ -58,7 +59,7 @@ jobs:

- name: Build
if: ${{ steps.build-cache.outputs.cache-hit != 'true' }}
run: pnpm build
run: pnpm build:packages

- name: Generate docs
if: ${{ steps.build-cache.outputs.cache-hit != 'true' }}
Expand All @@ -75,6 +76,7 @@ jobs:
chat/*/dist/*
chat/*/tsdoc.json
chat/*/stories.js
mcp-ui/*/dist/*
packages/*/dist/*
packages/*/tsdoc.json
packages/*/stories.js
Expand Down Expand Up @@ -118,6 +120,7 @@ jobs:
chat/*/dist/*
chat/*/tsdoc.json
chat/*/stories.js
mcp-ui/*/dist/*
packages/*/dist/*
packages/*/tsdoc.json
packages/*/stories.js
Expand Down Expand Up @@ -171,6 +174,7 @@ jobs:
chat/*/dist/*
chat/*/tsdoc.json
chat/*/stories.js
mcp-ui/*/dist/*
packages/*/dist/*
packages/*/tsdoc.json
packages/*/stories.js
Expand Down Expand Up @@ -232,6 +236,7 @@ jobs:
chat/*/dist/*
chat/*/tsdoc.json
chat/*/stories.js
mcp-ui/*/dist/*
packages/*/dist/*
packages/*/tsdoc.json
packages/*/stories.js
Expand Down Expand Up @@ -284,6 +289,7 @@ jobs:
chat/*/dist/*
chat/*/tsdoc.json
chat/*/stories.js
mcp-ui/*/dist/*
packages/*/dist/*
packages/*/tsdoc.json
packages/*/stories.js
Expand Down
37 changes: 37 additions & 0 deletions apps/mcp-ui-app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would think that a benefit of keeping these different components in a monorepo is being able to centralize .gitignore patterns in the root .gitignore file. Is there an explicit reason we need a separate one defined here?


# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local
.env.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

73 changes: 73 additions & 0 deletions apps/mcp-ui-app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# MCP UI App

A Next.js application for the MCP UI, configured for iframe embedding with CORS and CSP headers.

## Getting Started

### 1. Environment Setup

Create a `.env.local` file in the app root with the following variables:

```bash
# Base URL for the application
NEXT_PUBLIC_BASE_URL=http://localhost:3000

# Allowed parent origins for iframe embedding (comma-separated)
ALLOWED_IFRAME_ORIGINS=http://localhost:3000,http://localhost:3001,https://your-app.com
```

Configuration options:

- `NEXT_PUBLIC_BASE_URL`: The base URL of your application
- `ALLOWED_IFRAME_ORIGINS`: Comma-separated list of allowed parent origins for iframe embedding

### 2. Install dependencies

```bash
pnpm install
```

### 3. Run the development server

```bash
pnpm dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

## Configuration

### Base URL

The base URL is configured via the `NEXT_PUBLIC_BASE_URL` environment variable and can be accessed in your code:

```typescript
import config from '@/config';

console.log(config.baseUrl); // http://localhost:3000
```

### CORS and Iframe Embedding

The app is configured with:

- **CORS headers**: Allow cross-origin requests from specified origins
- **CSP headers**: Content Security Policy appropriate for iframe embedding
- **Frame ancestors**: Controls which domains can embed this app in an iframe

To allow your app to be embedded in an iframe from specific domains, add them to the `ALLOWED_IFRAME_ORIGINS` environment variable.

## Build

This app is excluded from the default `pnpm build` command in the workspace. To build this app specifically, run:

```bash
cd apps/mcp-ui-app
pnpm build
```

Or from the workspace root:

```bash
pnpm build:apps
```
60 changes: 60 additions & 0 deletions apps/mcp-ui-app/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
transpilePackages: [
'@lg-mcp-ui/list-databases',
'@leafygreen-ui/card',
'@leafygreen-ui/typography',
'@leafygreen-ui/emotion',
'@leafygreen-ui/tokens',
'@leafygreen-ui/lib',
],

async headers() {
// Get allowed origins from environment variable
const allowedOrigins = process.env.ALLOWED_IFRAME_ORIGINS?.split(',') || [
'*',
];

return [
{
// Apply to all routes
source: '/:path*',
headers: [
// CORS headers for iframe embedding
{
key: 'Access-Control-Allow-Origin',
value: allowedOrigins[0] || '*', // Use first origin or wildcard
},
{
key: 'Access-Control-Allow-Methods',
value: 'GET, POST, PUT, DELETE, OPTIONS',
},
{
key: 'Access-Control-Allow-Headers',
value: 'Content-Type, Authorization',
},
{
key: 'Access-Control-Allow-Credentials',
value: 'true',
},
// Content Security Policy for iframe embedding
{
key: 'Content-Security-Policy',
value: [
"default-src 'self'",
"script-src 'self' 'unsafe-eval' 'unsafe-inline'",
"style-src 'self' 'unsafe-inline'",
"img-src 'self' data: https:",
"font-src 'self' data:",
"connect-src 'self'",
`frame-ancestors ${allowedOrigins.join(' ')}`, // Allows embedding in iframes from these origins
].join('; '),
},
],
},
];
},
};

module.exports = nextConfig;
24 changes: 24 additions & 0 deletions apps/mcp-ui-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "@lg-apps/mcp-ui-app",
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: This probably doesn't need to be scoped since we're not publishing it to npm

"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
Copy link
Collaborator

@TheSonOfThomp TheSonOfThomp Nov 7, 2025

Choose a reason for hiding this comment

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

Turbo is complaining that there's nothing to cache when I run this. Probable need to add a custom turbo config for the app that sets the outputs https://turborepo.com/docs/reference/configuration#outputs

    ...Finishing writing to cache...                                                                     
WARNING  no output files found for task @lg-apps/mcp-ui-app#build. Please check your `outputs` key in `turbo.json`

"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@lg-mcp-ui/list-databases": "workspace:*",
"next": "^14.2.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/node": "^20.12.5",
"@types/react": "18.2.23",
"@types/react-dom": "18.2.8",
"typescript": "~5.8.0"
}
}

19 changes: 19 additions & 0 deletions apps/mcp-ui-app/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import type { Metadata } from 'next';

export const metadata: Metadata = {
title: 'MCP UI App',
description: 'MCP UI Application',
};

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
8 changes: 8 additions & 0 deletions apps/mcp-ui-app/src/app/list-databases/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use client';

import React from 'react';
import { ListDatabases } from '@lg-mcp-ui/list-databases';

export default function ListDatabasesPage() {
return <ListDatabases databases={[]} />;
}
Comment on lines +1 to +8
Copy link
Collaborator

Choose a reason for hiding this comment

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

Future consideration — this could probably be a [microui].tsx slug file, with getStaticPaths checking for all the installed micro-ui packages

Loading
Loading