Skip to content
Closed
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,5 @@ TODO.md
.pr-train.yml
migration-storybook.log

# amplify settings
apps/*/amplify_outputs.json
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.

# 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;
25 changes: 25 additions & 0 deletions apps/mcp-ui-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "@lg-apps/mcp-ui-app",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"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": {
"@aws-amplify/backend": "^1.18.0",
"@aws-amplify/backend-cli": "^1.8.0",
"@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={[]} />;
}
Loading
Loading