MCP Usage Examples
MCP Usage Examples
Section titled “MCP Usage Examples”This guide provides real-world scenarios and practical examples of using MCP servers together to accomplish common development tasks in the astro-basics project.
Complete Development Workflows
Section titled “Complete Development Workflows”1. Feature Development Workflow
Section titled “1. Feature Development Workflow”Build a new authentication feature from research to deployment:
// 1. Research authentication patterns in Astroconst authDocs = await searchAstroDocs({query: "middleware authentication protected routes"})
// 2. Check current Clerk setup and usersconst userCount = await getUserCount()const currentUser = await getUserId()
console.log(`Current setup: ${userCount} users, current user: ${currentUser}`)
// 3. Create Supabase table for user profilesawait applyMigration({project_id: "your-project-id",name: "add_user_profiles_table",query: ` CREATE TABLE user_profiles ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id TEXT NOT NULL UNIQUE, display_name TEXT, bio TEXT, avatar_url TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() );
-- Enable RLS ALTER TABLE user_profiles ENABLE ROW LEVEL SECURITY;
-- Users can read all profiles CREATE POLICY "Public profiles are viewable by everyone" ON user_profiles FOR SELECT USING (true);
-- Users can update their own profile CREATE POLICY "Users can update own profile" ON user_profiles FOR ALL USING (auth.jwt() ->> 'sub' = user_id);`})
// 4. Generate updated TypeScript typesconst updatedTypes = await generateTypescriptTypes({project_id: "your-project-id"})
console.log("Updated database types generated")
// 5. Test the implementation with Playwrightawait browserNavigate({ url: "http://localhost:4321/profile" })
// Should redirect to sign-in for unauthenticated usersawait browserWaitFor({ text: "Sign In", time: 5 })
// Take screenshot of sign-in pageawait browserTakeScreenshot({filename: "profile-redirect-signin.png",fullPage: true})
// 6. Deploy to Netlify with updated environment variablesawait deployToNetlify({siteId: "your-site-id",envVars: { SUPABASE_URL: "https://your-project.supabase.co", SUPABASE_ANON_KEY: "your-anon-key", CLERK_SECRET_KEY: "your-clerk-secret"}})
console.log("Feature deployed successfully!")2. Content Management Workflow
Section titled “2. Content Management Workflow”Create and manage blog content with full workflow:
// 1. Research content patterns in Astro docsconst contentDocs = await searchAstroDocs({query: "content collections MDX frontmatter"})
// 2. Create content database tableawait applyMigration({project_id: "your-project-id",name: "create_posts_metadata",query: ` CREATE TABLE posts_metadata ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), slug TEXT NOT NULL UNIQUE, title TEXT NOT NULL, author_id TEXT NOT NULL, published BOOLEAN DEFAULT false, featured BOOLEAN DEFAULT false, view_count INTEGER DEFAULT 0, like_count INTEGER DEFAULT 0, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), published_at TIMESTAMP WITH TIME ZONE,
CONSTRAINT posts_metadata_author_fkey FOREIGN KEY (author_id) REFERENCES auth.users(id) );
-- Enable RLS ALTER TABLE posts_metadata ENABLE ROW LEVEL SECURITY;
-- Public can read published posts CREATE POLICY "Published posts are public" ON posts_metadata FOR SELECT USING (published = true);
-- Authors can manage their posts CREATE POLICY "Authors can manage own posts" ON posts_metadata FOR ALL USING (auth.uid()::text = author_id);`})
// 3. Get current user for authoringconst currentUserId = await getUserId()const author = await getUser({ userId: currentUserId })
// 4. Insert post metadataawait executeSql({project_id: "your-project-id",query: ` INSERT INTO posts_metadata (slug, title, author_id, published) VALUES ('new-astro-features', 'New Astro Features Guide', '${currentUserId}', true) RETURNING *;`})
console.log(`Post created by ${author.firstName} ${author.lastName}`)// 5. Generate social media assets with Figmaconst figmaAssets = await getFigmaAssets({nodeId: "blog-post-template",format: "png",scale: 2})
// 6. Test content renderingawait browserNavigate({ url: "http://localhost:4321/posts/new-astro-features" })
// Check for proper meta tagsconst pageSnapshot = await browserSnapshot()const hasMetaTags = pageSnapshot.includes('og:title') && pageSnapshot.includes('og:description')
if (!hasMetaTags) {console.log("Warning: Missing social media meta tags")}
// Take screenshot for social sharingawait browserTakeScreenshot({filename: "post-social-preview.png",element: "Main content",ref: "main"})
// 7. Verify search functionalityawait browserClick({element: "Search input",ref: "input[type='search']"})
await browserType({element: "Search input",ref: "input[type='search']",text: "astro features"})
await browserWaitFor({ text: "New Astro Features", time: 5 })
console.log("Search functionality verified")// 8. Update post analyticsawait executeSql({project_id: "your-project-id",query: ` UPDATE posts_metadata SET published_at = NOW(), view_count = 0, like_count = 0 WHERE slug = 'new-astro-features' RETURNING *;`})
// 9. Create organization announcementawait createOrganizationInvitation({organizationId: "content-team-org-id",role: "member",publicMetadata: { type: "content-notification", postTitle: "New Astro Features Guide", postUrl: "/posts/new-astro-features"}})
// 10. Deploy with cache invalidationawait deployToNetlify({siteId: "your-site-id",invalidateCache: true,environment: "production"})
// 11. Verify deploymentawait browserNavigate({url: "https://your-site.netlify.app/posts/new-astro-features"})
await browserTakeScreenshot({filename: "post-live-production.png",fullPage: true})
console.log("Content published and live on production!")3. Database Migration & Testing Workflow
Section titled “3. Database Migration & Testing Workflow”// Complete database migration with testing// 1. Create development branch for testingconst branch = await createBranch({project_id: "your-project-id",name: "comments-migration",confirm_cost_id: "cost-confirmation-123"})
console.log(`Created branch: ${branch.id}`)
// 2. Apply migration on branchawait applyMigration({project_id: branch.project_ref, // Use branch project IDname: "add_comments_system",query: ` CREATE TABLE comments ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), content_type TEXT NOT NULL CHECK (content_type IN ('post', 'doc')), content_id TEXT NOT NULL, parent_comment_id UUID REFERENCES comments(id), author_id TEXT NOT NULL, content TEXT NOT NULL, status TEXT DEFAULT 'active' CHECK (status IN ('active', 'archived', 'flagged')), created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() );
-- Indexes for performance CREATE INDEX idx_comments_content ON comments(content_type, content_id); CREATE INDEX idx_comments_parent ON comments(parent_comment_id); CREATE INDEX idx_comments_author ON comments(author_id);
-- Enable RLS ALTER TABLE comments ENABLE ROW LEVEL SECURITY;
-- RLS Policies CREATE POLICY "Comments are viewable by everyone" ON comments FOR SELECT USING (status = 'active');
CREATE POLICY "Authenticated users can create comments" ON comments FOR INSERT WITH CHECK (auth.uid() IS NOT NULL);
CREATE POLICY "Users can update own comments" ON comments FOR UPDATE USING (auth.uid()::text = author_id);`})
// 3. Test migration with sample dataawait executeSql({project_id: branch.project_ref,query: ` INSERT INTO comments (content_type, content_id, author_id, content) VALUES ('post', 'test-post-1', 'user_123', 'Great article!'), ('post', 'test-post-1', 'user_456', 'Thanks for sharing this.'), ('doc', 'api-reference', 'user_789', 'Very helpful documentation.');`})
// 4. Generate types for branchconst branchTypes = await generateTypescriptTypes({project_id: branch.project_ref})
// 5. Test comment functionality with Playwrightawait browserNavigate({ url: "http://localhost:4321/posts/test-post" })
// Test comment form (assuming authentication is set up)await browserClick({element: "Comment textarea",ref: "textarea[name='comment-content']"})
await browserType({element: "Comment textarea",ref: "textarea[name='comment-content']",text: "This is a test comment from automation"})
await browserClick({element: "Submit comment",ref: "button[type='submit']"})
// Wait for comment to appearawait browserWaitFor({ text: "test comment from automation", time: 10 })
// 6. Verify data in databaseconst comments = await executeSql({project_id: branch.project_ref,query: "SELECT * FROM comments ORDER BY created_at DESC LIMIT 5;"})
console.log(`Found ${comments.length} comments in test database`)
// 7. If tests pass, merge to productionif (comments.length > 0) {await mergeBranch({ branch_id: branch.id })console.log("Migration merged to production successfully")
// 8. Deploy updated applicationawait deployToNetlify({ siteId: "your-site-id", environment: "production"})} else {console.log("Tests failed - migration not merged")}Debugging & Troubleshooting Scenarios
Section titled “Debugging & Troubleshooting Scenarios”Debug Production Issues
Section titled “Debug Production Issues”// Comprehensive production debugging workflow// 1. Check application logsconst logs = await getNetlifyLogs({siteId: "your-site-id",level: "error",limit: 50})
console.log(`Found ${logs.length} error entries`)
// 2. Check database connectivitytry {await executeSql({ project_id: "your-project-id", query: "SELECT 1 as health_check;"})console.log("✅ Database connection healthy")} catch (error) {console.log("❌ Database connection failed:", error.message)}
// 3. Verify authentication servicetry {const userCount = await getUserCount()console.log(`✅ Clerk service healthy - ${userCount} total users`)} catch (error) {console.log("❌ Clerk service error:", error.message)}
// 4. Test critical user flowsconst testResults = []
// Test homepagetry {await browserNavigate({ url: "https://your-site.netlify.app" })await browserWaitFor({ text: "Welcome", time: 5 })testResults.push({ test: "Homepage", status: "✅ Pass" })} catch (error) {testResults.push({ test: "Homepage", status: "❌ Fail", error: error.message })}
// Test authentication flowtry {await browserNavigate({ url: "https://your-site.netlify.app/dashboard" })await browserWaitFor({ text: "Sign In", time: 5 })testResults.push({ test: "Auth Redirect", status: "✅ Pass" })} catch (error) {testResults.push({ test: "Auth Redirect", status: "❌ Fail", error: error.message })}
// Test database-driven contenttry {await browserNavigate({ url: "https://your-site.netlify.app/posts" })await browserWaitFor({ text: "Recent Posts", time: 10 })testResults.push({ test: "Database Content", status: "✅ Pass" })} catch (error) {testResults.push({ test: "Database Content", status: "❌ Fail", error: error.message })}
console.log("Production Health Check Results:")testResults.forEach(result => {console.log(`${result.test}: ${result.status}`)if (result.error) console.log(` Error: ${result.error}`)})
// 5. Take screenshots of failing pages for investigationif (testResults.some(r => r.status.includes("❌"))) {await browserTakeScreenshot({ filename: "production-error-state.png", fullPage: true})}Performance Optimization Workflow
Section titled “Performance Optimization Workflow”// Comprehensive performance analysis and optimization// 1. Research performance best practicesconst perfDocs = await searchAstroDocs({query: "performance optimization build static"})
// 2. Analyze current database performanceconst slowQueries = await executeSql({project_id: "your-project-id",query: ` SELECT query, calls, mean_exec_time, total_exec_time FROM pg_stat_statements WHERE mean_exec_time > 100 ORDER BY mean_exec_time DESC LIMIT 10;`})
console.log(`Found ${slowQueries.length} slow queries`)
// 3. Check for missing database indexesconst missingIndexes = await executeSql({project_id: "your-project-id",query: ` SELECT schemaname, tablename, attname, n_distinct, correlation FROM pg_stats WHERE schemaname = 'public' AND n_distinct > 100 AND correlation < 0.1;`})
// 4. Optimize database with new indexes if neededif (missingIndexes.length > 0) {await applyMigration({ project_id: "your-project-id", name: "add_performance_indexes", query: ` -- Add indexes for frequently queried columns CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_published_date ON posts (published_at DESC) WHERE published = true;
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_comments_content_created ON comments (content_type, content_id, created_at DESC);
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_user_profiles_updated ON user_profiles (updated_at DESC); `})
console.log("Performance indexes added")}
// 5. Test page load performance with Playwrightconst performanceTests = ["https://your-site.netlify.app","https://your-site.netlify.app/posts","https://your-site.netlify.app/docs"]
for (const url of performanceTests) {await browserNavigate({ url })
// Measure performance metricsconst metrics = await browserEvaluate({ function: `() => { const navigation = performance.getEntriesByType('navigation')[0]; return { domContentLoaded: navigation.domContentLoadedEventEnd - navigation.domContentLoadedEventStart, loadComplete: navigation.loadEventEnd - navigation.loadEventStart, firstPaint: performance.getEntriesByType('paint')[0]?.startTime || 0, largestContentfulPaint: performance.getEntriesByType('largest-contentful-paint')[0]?.startTime || 0 }; }`})
console.log(`Performance for ${url}:`, metrics)
// Take screenshot if performance is poorif (metrics.domContentLoaded > 2000) { await browserTakeScreenshot({ filename: `slow-page-${url.split('/').pop() || 'home'}.png`, fullPage: true })}}
// 6. Check Netlify deployment performanceconst deploymentInfo = await getNetlifyDeployment({siteId: "your-site-id"})
console.log(`Build time: ${deploymentInfo.buildTime}ms`)console.log(`Bundle size: ${deploymentInfo.bundleSize}MB`)
// 7. Generate optimization recommendationsconst recommendations = []
if (slowQueries.length > 0) {recommendations.push("Consider optimizing database queries or adding indexes")}
if (deploymentInfo.buildTime > 120000) { // 2 minutesrecommendations.push("Build time is high - consider code splitting or build optimization")}
if (deploymentInfo.bundleSize > 5) { // 5MBrecommendations.push("Bundle size is large - consider lazy loading or image optimization")}
console.log("Optimization Recommendations:")recommendations.forEach(rec => console.log(`- ${rec}`))Multi-Server Integration Patterns
Section titled “Multi-Server Integration Patterns”Convert Figma designs to working components:
// 1. Get design specifications from Figmaconst designSpecs = await getFigmaVariables({nodeId: "component-design-node"})
// 2. Generate component codeconst componentCode = await getFigmaCode({nodeId: "component-design-node",framework: "react"})
// 3. Research similar components in Astro docsconst componentDocs = await searchAstroDocs({query: "component props TypeScript interface"})
// 4. Create component in development// (This would typically involve file creation, but shown conceptually)const componentPath = "/src/components/react/NewComponent.tsx"
// 5. Test component with Playwrightawait browserNavigate({ url: "http://localhost:4321/component-preview" })
// Check if component renders correctlyconst snapshot = await browserSnapshot()if (snapshot.includes("NewComponent")) {console.log("✅ Component renders successfully")
// Take screenshot for design comparisonawait browserTakeScreenshot({ element: "Component preview", ref: "[data-component='NewComponent']", filename: "component-implementation.png"})} else {console.log("❌ Component rendering failed")}
// 6. Deploy to preview environmentawait deployToNetlify({siteId: "preview-site-id",branch: "feature-new-component"})Automated content creation and management:
// 1. Get content ideas from web researchconst contentIdeas = await webSearch({query: "astro framework tutorial ideas 2024"})
// 2. Research existing content gapsconst existingContent = await executeSql({project_id: "your-project-id",query: "SELECT title, slug FROM posts_metadata WHERE published = true"})
// 3. Create content outline using AI assistanceconst outline = await webFetch({url: "https://api.openai.com/v1/chat/completions",method: "POST",headers: { "Authorization": "Bearer your-openai-key", "Content-Type": "application/json"},body: JSON.stringify({ model: "gpt-4", messages: [{ role: "user", content: "Create a detailed outline for an Astro tutorial about SSR and API routes" }]})})
// 4. Set up content in databaseawait executeSql({project_id: "your-project-id",query: ` INSERT INTO posts_metadata ( slug, title, author_id, published, outline ) VALUES ( 'astro-ssr-api-routes', 'Building SSR Apps with Astro API Routes', '${await getUserId()}', false, '${JSON.stringify(outline)}' )`})
// 5. Create content branch for developmentconst contentBranch = await createBranch({project_id: "your-project-id",name: "content-ssr-tutorial"})
// 6. Track progress in organizationawait updateOrganizationMetadata({organizationId: "content-team-id",publicMetadata: { activeProjects: { "astro-ssr-tutorial": { status: "in-progress", author: await getUserId(), deadline: "2024-02-15", outline: outline } }}})Best Practices Summary
Section titled “Best Practices Summary”Error Handling Pattern
Section titled “Error Handling Pattern”// Robust error handling across multiple servicesasync function robustWorkflow() {const results = { astroSearch: null, clerkAuth: null, supabaseQuery: null, playwrightTest: null, netlifyDeploy: null}
const errors = []
// Astro docs searchtry { results.astroSearch = await searchAstroDocs({ query: "authentication" })} catch (error) { errors.push({ service: "Astro Docs", error: error.message })}
// Clerk authentication checktry { results.clerkAuth = await getUserId()} catch (error) { errors.push({ service: "Clerk", error: error.message })}
// Supabase query (only if auth successful)if (results.clerkAuth) { try { results.supabaseQuery = await executeSql({ project_id: "your-project-id", query: "SELECT COUNT(*) FROM users" }) } catch (error) { errors.push({ service: "Supabase", error: error.message }) }}
// Playwright test (only if other services working)if (results.clerkAuth && results.supabaseQuery) { try { await browserNavigate({ url: "http://localhost:4321" }) results.playwrightTest = "success" } catch (error) { errors.push({ service: "Playwright", error: error.message }) }}
// Netlify deployment (only if tests pass)if (results.playwrightTest === "success") { try { results.netlifyDeploy = await deployToNetlify({ siteId: "your-site-id" }) } catch (error) { errors.push({ service: "Netlify", error: error.message }) }}
return { results, errors }}These examples demonstrate how to effectively combine multiple MCP servers to create powerful, automated workflows that span the entire development lifecycle from research and design to testing and deployment.