MCP Examples
Real-world workflows combining AI steps with MCP tool calls.
CRM Lead Enrichment
Enrich incoming leads with company data and create follow-up tasks:
1import { relay } from '@relayplane/sdk'23relay.configure({4 providers: { openai: { apiKey: process.env.OPENAI_API_KEY! } },5 mcp: {6 servers: {7 crm: { url: 'https://mcp.salesforce.com' },8 clearbit: { url: 'https://mcp.clearbit.com' }9 }10 }11})1213const leadEnrichment = relay14 .workflow('lead-enrichment')15 // Extract company domain from email16 .step('extractDomain')17 .with('openai:gpt-4o')18 .prompt('Extract the company domain from this email address: {{input.email}}. Return just the domain.')19 // Look up company in Clearbit20 .step('enrichCompany')21 .mcp('clearbit:getCompanyByDomain')22 .params({ domain: '{{extractDomain.output}}' })23 .depends('extractDomain')24 // Score the lead based on enriched data25 .step('scoreLead')26 .with('openai:gpt-4o')27 .depends('enrichCompany')28 .prompt(`Based on this company data, score this lead from 1-100:29 Company: {{enrichCompany.name}}30 Industry: {{enrichCompany.industry}}31 Employees: {{enrichCompany.employees}}32 Revenue: {{enrichCompany.estimatedRevenue}}3334 Return a JSON object: { "score": number, "reasoning": string }`)35 // Create or update CRM record36 .step('updateCRM')37 .mcp('crm:upsertLead')38 .params({39 email: '{{input.email}}',40 company: '{{enrichCompany.name}}',41 industry: '{{enrichCompany.industry}}',42 leadScore: '{{scoreLead.score}}'43 })44 .depends('scoreLead')4546const result = await leadEnrichment.run({47 email: 'john.smith@acme.com'48})GitHub Issue Triage
Automatically analyze and triage GitHub issues:
1import { relay } from '@relayplane/sdk'23relay.configure({4 providers: { anthropic: { apiKey: process.env.ANTHROPIC_API_KEY! } },5 mcp: {6 servers: {7 github: {8 url: 'https://mcp.github.com',9 credentials: { token: process.env.GITHUB_TOKEN }10 }11 }12 }13})1415const issueTriage = relay16 .workflow('issue-triage')17 // Get issue details18 .step('getIssue')19 .mcp('github:getIssue')20 .params({21 owner: '{{input.owner}}',22 repo: '{{input.repo}}',23 issueNumber: '{{input.issueNumber}}'24 })25 // Analyze the issue26 .step('analyze')27 .with('anthropic:claude-sonnet-4-20250514')28 .depends('getIssue')29 .prompt(`Analyze this GitHub issue and provide:30 1. Category (bug, feature, question, docs)31 2. Priority (P0, P1, P2, P3)32 3. Suggested labels33 4. Brief summary3435 Issue Title: {{getIssue.title}}36 Issue Body: {{getIssue.body}}3738 Return JSON: { "category": string, "priority": string, "labels": string[], "summary": string }`)39 // Apply labels40 .step('addLabels')41 .mcp('github:addLabels')42 .params({43 owner: '{{input.owner}}',44 repo: '{{input.repo}}',45 issueNumber: '{{input.issueNumber}}',46 labels: '{{analyze.labels}}'47 })48 .depends('analyze')49 // Add comment with analysis50 .step('addComment')51 .mcp('github:createComment')52 .params({53 owner: '{{input.owner}}',54 repo: '{{input.repo}}',55 issueNumber: '{{input.issueNumber}}',56 body: `## Automated Triage5758**Category:** {{analyze.category}}59**Priority:** {{analyze.priority}}60**Summary:** {{analyze.summary}}`61 })62 .depends('analyze')6364const result = await issueTriage.run({65 owner: 'myorg',66 repo: 'myproject',67 issueNumber: 12368})Smart Slack Notifications
Route alerts to the right channel with AI-powered classification:
1import { relay } from '@relayplane/sdk'23relay.configure({4 providers: { openai: { apiKey: process.env.OPENAI_API_KEY! } },5 mcp: {6 servers: {7 slack: {8 url: 'https://mcp.slack.com',9 credentials: { token: process.env.SLACK_BOT_TOKEN }10 }11 }12 }13})1415const alertRouter = relay16 .workflow('alert-router')17 // Classify the alert18 .step('classify')19 .with('openai:gpt-4o')20 .prompt(`Classify this alert and determine the appropriate Slack channel:2122 Alert: {{input.alertMessage}}23 Severity: {{input.severity}}2425 Available channels:26 - #incidents - Critical production issues27 - #security - Security-related alerts28 - #platform - Infrastructure and platform issues29 - #general-alerts - Everything else3031 Return JSON: { "channel": string, "urgency": "high" | "medium" | "low", "summary": string }`)32 // Send to appropriate channel33 .step('notify')34 .mcp('slack:postMessage')35 .params({36 channel: '{{classify.channel}}',37 text: '{{classify.urgency === "high" ? " " : ""}}*{{input.severity}} Alert*\n{{classify.summary}}'38 })39 .depends('classify')4041const result = await alertRouter.run({42 alertMessage: 'Database connection pool exhausted on prod-db-1',43 severity: 'CRITICAL'44})MCP workflows are great for connecting AI reasoning with real-world actions. Use AI steps to analyze and decide, then MCP steps to execute actions.
Next Steps
- MCP Overview - Learn how MCP works
- Configuration - Configure MCP servers
- Invoice Processor - AI-only workflow example