Codebase Navigator Skill
Comprehensive guide to understanding and navigating the MCP Finance application structure, including both frontend (Next.js) and backend (Python MCP) components.
Project Structure Overview
nextjs-mcp-finance/
├── src/
│ ├── app/ # Next.js App Router pages
│ │ ├── (auth)/ # Auth-protected route group
│ │ ├── (public)/ # Public route group
│ │ ├── api/ # API routes (backend endpoints)
│ │ ├── layout.tsx # Root layout
│ │ └── page.tsx # Home page
│ ├── components/ # React components
│ │ ├── ui/ # Reusable UI components
│ │ └── features/ # Feature-specific components
│ ├── lib/ # Utilities and helpers
│ │ ├── db/ # Database schema and client
│ │ ├── api/ # API client helpers
│ │ ├── mcp/ # MCP server integration
│ │ └── utils/ # Utility functions
│ └── types/ # TypeScript type definitions
├── public/ # Static assets
├── __tests__/ # Unit tests
├── e2e/ # E2E tests
├── .claude/ # Claude Code configuration
│ ├── CLAUDE.md # Project guidelines
│ ├── rules/ # Project-specific rules
│ └── skills/ # Reusable skills
├── .env # Environment variables (DO NOT COMMIT)
├── .env.example # Template for env vars
├── package.json # Dependencies
├── tsconfig.json # TypeScript config
├── next.config.js # Next.js config
└── drizzle.config.ts # Database migration config
Frontend Architecture (Next.js)
App Router Structure
The application uses Next.js 16 App Router with organized route groups:
Public Routes (src/app/(public)/)
/- Landing/home page/sign-in- Clerk sign-in page/sign-up- Clerk sign-up page
Protected Routes (src/app/(auth)/)
These routes require authentication via Clerk:
/dashboard- Main dashboard/portfolio- User portfolio view/stocks/[symbol]- Individual stock pages/transactions- Transaction history/settings- User settings
API Routes (src/app/api/)
RESTful API endpoints:
/api/health # Health check
/api/stocks # Stock operations
/api/stocks/[symbol] # Stock details
/api/stocks/favorite # Favorite management
/api/transactions # Transaction operations
/api/webhooks/clerk # Clerk webhook handler
/api/webhooks/stripe # Stripe webhook handler
/api/mcp/[endpoint] # MCP server proxy
Component Organization
UI Components (src/components/ui/)
Reusable, unstyled components from Radix UI:
Button.tsx- Button componentCard.tsx- Card containerDialog.tsx- Modal dialogInput.tsx- Text inputTable.tsx- Data tableBadge.tsx- Status badge
Usage Pattern:
import { Button } from '@/components/ui/button';
export function MyComponent() {
return <Button => {}}>Click me</Button>;
}
Feature Components (src/components/features/)
Business logic components that use UI components:
StockChart.tsx- Stock price chartTransactionForm.tsx- Form for creating transactionsPortfolioSummary.tsx- Portfolio overview widgetStockSearch.tsx- Stock search functionality
Server Components vs Client Components
Default: Server Components
- Fetch data directly in components
- No client-side JavaScript overhead
- Access database and MCP server directly
// Server Component (default)
import { getStocks } from '@/lib/api/stocks';
export default async function StocksPage() {
const stocks = await getStocks();
return (
<div>
{stocks.map(stock => (
<StockCard key={stock.id} stock={stock} />
))}
</div>
);
}
Client Components: When Needed
- Interactive features (forms, buttons, state)
- Browser APIs (localStorage, window)
- Real-time updates (WebSocket)
// Client Component (explicit)
'use client';
import { useState } from 'react';
export function CounterButton() {
const [count, setCount] = useState(0);
return (
<button => setCount(count + 1)}>
Count: {count}
</button>
);
}
Data Fetching Patterns
Server Component Data Fetching
// src/lib/api/stocks.ts
export async function getStocks() {
const response = await fetch('http://localhost:8000/api/stocks', {
headers: {
'Authorization': `Bearer ${process.env.MCP_API_KEY}`,
},
});
if (!response.ok) {
throw new Error(`Failed to fetch stocks: ${response.statusText}`);
}
return response.json();
}
// In a Server Component
import { getStocks } from '@/lib/api/stocks';
export default async function Dashboard() {
const stocks = await getStocks();
return <StockList stocks={stocks} />;
}
Client-Side Data Fetching
Uses TanStack Query for caching and state management:
// src/lib/api/hooks.ts
import { useQuery } from '@tanstack/react-query';
export function useStocks() {
return useQuery({
queryKey: ['stocks'],
queryFn: async () => {
const response = await fetch('/api/stocks');
return response.json();
},
});
}
// In a Client Component
'use client';
import { useStocks } from '@/lib/api/hooks';
export function StockList() {
const { data: stocks, isLoading, error } = useStocks();
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<ul>
{stocks.map(stock => (
<li key={stock.symbol}>{stock.name}</li>
))}
</ul>
);
}
Database Schema (Drizzle ORM)
Located in src/lib/db/schema/:
Core Tables
Users Table
users {
id: text (primary key)
email: varchar (unique)
name: text
createdAt: timestamp
updatedAt: timestamp
}
Stocks Table
stocks {
id: text (primary key)
symbol: varchar (unique)
name: text
currentPrice: decimal
lastUpdated: timestamp
createdAt: timestamp
}
UserStocks (Favorites/Holdings)
userStocks {
id: text (primary key)
userId: text (FK → users.id)
stockId: text (FK → stocks.id)
quantity: integer
createdAt: timestamp
}
Transactions Table
transactions {
id: text (primary key)
userId: text (FK → users.id)
symbol: varchar
type: enum ('buy' | 'sell')
quantity: integer
price: decimal
total: decimal
createdAt: timestamp
}
Backend Architecture (Python MCP)
The Python backend runs as an MCP (Model Context Protocol) server, providing:
- Real-time stock market data
- Technical analysis
- AI-powered trading recommendations
MCP Server Location
../ (parent directory)
├── python_backend/ # Python MCP server
│ ├── src/
│ │ ├── mcp_server.py # Main MCP server
│ │ ├── stock_service.py # Stock data fetching
│ │ ├── analysis.py # Technical analysis
│ │ └── models.py # Data models
│ ├── requirements.txt
│ └── environment.yml
Key Services
Stock Service
Fetches real-time market data:
async def get_stock_data(symbol: str) -> StockData:
# Returns current price, volume, market cap, etc.
# Uses yfinance or real market data API
Analysis Service
Performs technical analysis:
def calculate_indicators(stock_data) -> Indicators:
# RSI, MACD, Moving Averages
# Trend analysis
Recommendation Service
Generates trading signals:
def generate_signal(stock_data, indicators) -> TradingSignal:
# BUY, SELL, HOLD
# Confidence score
Key File Locations
Finding Frontend Files
To find a component:
# Search by component name
grep -r "export function StockCard" src/components/
# List all components
find src/components -name "*.tsx" -type f
To find API routes:
# List all API endpoints
find src/app/api -name "route.ts" -type f
# Example: Find stock API
cat src/app/api/stocks/route.ts
Finding Backend Files
Python MCP server:
# From gcp app w mcp directory
ls -la python_backend/
ls -la python_backend/src/
# Run the MCP server
python python_backend/src/mcp_server.py
Common Development Tasks
Adding a New API Endpoint
Create route file:
mkdir -p src/app/api/[resource] touch src/app/api/[resource]/route.tsImplement endpoint:
// src/app/api/[resource]/route.ts import { auth } from "@clerk/nextjs/server"; import { validateInput } from "@/lib/validation"; export async function GET(request: Request) { const { userId } = await auth(); if (!userId) { return Response.json({ error: "Unauthorized" }, { status: 401 }); } // Fetch from database const data = await db.query.myTable.findMany({ where: eq(myTable.userId, userId), }); return Response.json({ success: true, data }); }Test with API skill:
curl http://localhost:3000/api/[resource]
Adding a New Database Table
Create schema file:
touch src/lib/db/schema/[tableName].tsDefine table:
import { pgTable, text, timestamp } from "drizzle-orm/pg-core"; export const myTable = pgTable("my_table", { id: text("id").primaryKey(), userId: text("user_id").notNull(), name: text("name").notNull(), createdAt: timestamp("created_at").defaultNow().notNull(), });Generate migration:
npm run db:generate npm run db:migrate
Adding a New Component
Create component file:
touch src/components/features/MyComponent.tsxImplement component:
interface MyComponentProps { title: string; onClick: () => void; } export function MyComponent({ title, onClick }: MyComponentProps) { return ( <div> <h1>{title}</h1> <button me</button> </div> ); }Export from barrel file:
# Add to src/components/features/index.ts export { MyComponent } from './MyComponent';
Calling MCP Server from Frontend
The frontend communicates with the Python MCP server via API routes:
// src/lib/mcp/client.ts
async function callMCP(endpoint: string, params: object) {
const response = await fetch(`/api/mcp/${endpoint}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(params),
});
return response.json();
}
// Usage in components
const signal = await callMCP("analyze", { symbol: "AAPL" });
Navigation Commands
Quick File Finding
Find files by pattern:
# Find all TypeScript files
find src -name "*.tsx" -type f
# Find all API routes
find src/app/api -name "route.ts"
# Find specific component
find src/components -name "*Stock*"
# Search for a function
grep -r "function fetchStocks" src/
# Find imports of a component
grep -r "from.*StockCard" src/
Understanding File Dependencies
To see what a file imports:
head -30 src/components/features/StockCard.tsx
To see what imports a file:
grep -r "from.*StockCard" src/
Architecture Diagrams
Request Flow (Frontend to Backend)
User Interaction (Browser)
↓
React Component (Client/Server)
↓
Next.js API Route (/api/...)
↓
Frontend Service Layer (/lib/api/...)
↓
Python MCP Server (localhost:8000)
↓
Real Market Data APIs
Database Flow
Frontend Form
↓
Next.js API Route (validates input)
↓
Drizzle ORM (src/lib/db/)
↓
PostgreSQL Database
Authentication Flow
User Sign-in
↓
Clerk Authentication Service
↓
Session Cookie Set
↓
Protected Route Access
↓
API Route Checks auth() helper
Environment Variables
Located in .env.local (never commit):
# Next.js / Frontend
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_...
CLERK_SECRET_KEY=sk_...
# Database
DATABASE_URL=postgresql://...
# MCP Server
MCP_SERVER_URL=http://localhost:8000
MCP_API_KEY=sk_...
# Stripe
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_...
STRIPE_SECRET_KEY=sk_...
STRIPE_WEBHOOK_SECRET=whsec_...
Testing Structure
Unit Tests
__tests__/
├── lib/
│ ├── api/
│ └── utils/
└── components/
└── features/
E2E Tests
e2e/
├── auth.spec.ts
├── dashboard.spec.ts
└── stocks.spec.ts
Run tests:
npm run test # Unit tests
npm run test:e2e # E2E tests
npm run test:watch # Watch mode
Performance Optimization Points
Frontend
- Server Components - Use by default for data fetching
- Image Optimization - Use
next/imagefor stock charts - Code Splitting - Route-based automatic with App Router
- CSS - Tailwind CSS with purging
Database
- Indexes - On frequently queried columns (userId, symbol)
- Queries - Use relations to avoid N+1
- Caching - TanStack Query on frontend
MCP Server
- Caching - Cache stock data with TTL
- Rate Limiting - Respect API rate limits
- Connection Pool - Reuse connections to market data APIs
Debugging Tips
Frontend Issues
Check server logs:
cd nextjs-mcp-finance
npm run dev
# Watch for errors in console
Check browser console:
- F12 → Console tab
- Look for JavaScript errors
- Check Network tab for failed requests
Check database:
npm run db:studio # Opens Drizzle Studio on http://localhost:3001
Backend Issues
Check MCP server logs:
# From gcp app w mcp directory
python python_backend/src/mcp_server.py
# Watch console output for errors
Test MCP endpoint directly:
curl http://localhost:8000/api/stocks/AAPL
Database Issues
Check migrations:
npm run db:migrate
npm run db:migrate:rollback
Query directly:
npm run db:studio # GUI interface
# Or use psql if available
psql $DATABASE_URL -c "SELECT * FROM users LIMIT 1;"
Common File Locations
| Task | Location |
|---|---|
| Add UI component | src/components/ui/ |
| Add feature component | src/components/features/ |
| Add API endpoint | src/app/api/[resource]/route.ts |
| Add database table | src/lib/db/schema/ |
| Add API client | src/lib/api/ |
| Add type definitions | src/types/ |
| Add utility functions | src/lib/utils/ |
| Add tests | __tests__/ or e2e/ |
Next Steps
- Explore the codebase: Use Find functionality to locate specific files
- Read the CLAUDE.md file: Understand project guidelines and standards
- Run the application:
npm run devto start frontend +pythonto start MCP server - Use api-test skill: Test APIs as you develop
- Run tests: Ensure everything works before committing
Need help? Use Glob and Grep tools to search the codebase, or ask specific questions about file locations and architecture.