Skip to main content
Glama
GITHUB_CICD_PLAN.md25.8 kB
# GitHub CI/CD Setup Plan for Tableau MCP Project **Date**: November 19, 2025 **Status**: Ready for Implementation **Repository**: https://github.com/russelenriquez-agile/tableau-mcp-project --- ## Overview This document outlines the plan to implement GitHub-based CI/CD with automatic deployments to Cloud Run staging and production environments using GitHub Actions workflows triggered by branch pushes. ## Deployment Strategy - **Staging Branch** (`staging`) → Automatic deployment to `tableau-mcp-staging` Cloud Run service - **Production Branch** (`main`) → Deployment to `tableau-mcp-production` Cloud Run service (with manual approval gate) ## Architecture ``` Developer pushes to staging branch ↓ GitHub Actions triggered ↓ Build Docker image → Push to GCR ↓ Deploy to tableau-mcp-staging (Cloud Run) ↓ Run smoke tests ↓ ✅ Deployment complete Developer pushes to main branch (or merges PR) ↓ GitHub Actions triggered ↓ ⏸️ Wait for manual approval (production environment) ↓ Build Docker image → Push to GCR ↓ Deploy to tableau-mcp-production (Cloud Run) ↓ Run smoke tests ↓ ✅ Production deployment complete ``` --- ## Implementation Steps ### Step 1: Repository Initialization & Push **Objective**: Initialize git repository and push all project files to GitHub. **Actions**: ```bash # Navigate to project directory cd C:\Users\MomentumMedia\.cursor\agile\projects\tableau-mcp-project # Initialize git repository git init # Add remote git remote add origin https://github.com/russelenriquez-agile/tableau-mcp-project.git # Add all files (respect .gitignore) git add . # Create initial commit git commit -m "Initial commit: Tableau MCP Server with Cloud Run infrastructure" # Push to main branch git branch -M main git push -u origin main # Create staging branch git checkout -b staging git push -u origin staging # Return to main git checkout main ``` **Verification**: - Visit https://github.com/russelenriquez-agile/tableau-mcp-project - Verify all files are present - Verify both `main` and `staging` branches exist --- ### Step 2: Google Cloud Service Account Setup **Objective**: Create a dedicated service account for GitHub Actions with necessary permissions. **Actions**: ```bash # Set your project ID export GCP_PROJECT_ID="your-project-id" # Create service account gcloud iam service-accounts create github-actions-deploy \ --display-name="GitHub Actions Deployment" \ --project=${GCP_PROJECT_ID} # Grant Cloud Run Admin role gcloud projects add-iam-policy-binding ${GCP_PROJECT_ID} \ --member="serviceAccount:github-actions-deploy@${GCP_PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/run.admin" # Grant Service Account User role gcloud projects add-iam-policy-binding ${GCP_PROJECT_ID} \ --member="serviceAccount:github-actions-deploy@${GCP_PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/iam.serviceAccountUser" # Grant Storage Admin role (for Google Container Registry) gcloud projects add-iam-policy-binding ${GCP_PROJECT_ID} \ --member="serviceAccount:github-actions-deploy@${GCP_PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/storage.admin" # Grant Secret Manager Secret Accessor role gcloud projects add-iam-policy-binding ${GCP_PROJECT_ID} \ --member="serviceAccount:github-actions-deploy@${GCP_PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/secretmanager.secretAccessor" # Create and download service account key gcloud iam service-accounts keys create github-actions-key.json \ --iam-account=github-actions-deploy@${GCP_PROJECT_ID}.iam.gserviceaccount.com \ --project=${GCP_PROJECT_ID} # Display the key content (you'll need to copy this to GitHub Secrets) cat github-actions-key.json ``` **Security Note**: Store the `github-actions-key.json` securely and delete it after adding to GitHub Secrets. Never commit this file to the repository. --- ### Step 3: GitHub Repository Configuration #### 3.1 Add GitHub Secrets **Navigate to**: `https://github.com/russelenriquez-agile/tableau-mcp-project/settings/secrets/actions` **Add the following secrets**: | Secret Name | Value | Description | |------------|-------|-------------| | `GCP_PROJECT_ID` | Your GCP project ID | Example: `agile-intelligence-prod` | | `GCP_SA_KEY` | Contents of `github-actions-key.json` | Full JSON key file content | | `GCP_REGION` | `australia-southeast1` | Cloud Run deployment region | **Steps**: 1. Click "New repository secret" 2. Enter name and value 3. Click "Add secret" 4. Repeat for all secrets #### 3.2 Create GitHub Environments **Navigate to**: `https://github.com/russelenriquez-agile/tableau-mcp-project/settings/environments` **Create two environments**: **Environment 1: `staging`** - No protection rules (automatic deployments) - Optional: Add environment-specific variables if needed **Environment 2: `production`** - Enable "Required reviewers" → Add yourself and/or team members - Enable "Wait timer" → 0 minutes (manual approval only) - This creates a manual approval gate before production deployments #### 3.3 Configure Branch Protection Rules **Navigate to**: `https://github.com/russelenriquez-agile/tableau-mcp-project/settings/branches` **Rule 1: Protect `main` branch** - Branch name pattern: `main` - ✅ Require a pull request before merging - ✅ Require approvals: 1 - ✅ Require status checks to pass before merging - Add check: `deploy-staging` (after first run) - ✅ Do not allow bypassing the above settings - ❌ Allow force pushes (keep disabled) - ❌ Allow deletions (keep disabled) **Rule 2: Protect `staging` branch** (Optional but recommended) - Branch name pattern: `staging` - ✅ Require status checks to pass before merging (optional) - ✅ Allow force pushes (for quick iterations) - ❌ Allow deletions --- ### Step 4: Create GitHub Actions Workflows #### 4.1 Staging Deployment Workflow **File**: `.github/workflows/deploy-staging.yml` ```yaml name: Deploy to Staging on: push: branches: - staging env: GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} GCP_REGION: ${{ secrets.GCP_REGION }} SERVICE_NAME: tableau-mcp-staging IMAGE_NAME: tableau-mcp jobs: deploy: name: Deploy to Cloud Run Staging runs-on: ubuntu-latest environment: staging steps: - name: Checkout code uses: actions/checkout@v4 - name: Authenticate to Google Cloud uses: google-github-actions/auth@v2 with: credentials_json: ${{ secrets.GCP_SA_KEY }} - name: Set up Cloud SDK uses: google-github-actions/setup-gcloud@v2 with: project_id: ${{ secrets.GCP_PROJECT_ID }} - name: Configure Docker for GCR run: | gcloud auth configure-docker - name: Build Docker image run: | docker build \ -t gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.IMAGE_NAME }}:staging-${{ github.sha }} \ -t gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.IMAGE_NAME }}:staging-latest \ . - name: Push Docker image to GCR run: | docker push gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.IMAGE_NAME }}:staging-${{ github.sha }} docker push gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.IMAGE_NAME }}:staging-latest - name: Deploy to Cloud Run run: | gcloud run services update ${{ env.SERVICE_NAME }} \ --image gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.IMAGE_NAME }}:staging-${{ github.sha }} \ --region ${{ env.GCP_REGION }} \ --platform managed - name: Get service URL id: get-url run: | SERVICE_URL=$(gcloud run services describe ${{ env.SERVICE_NAME }} \ --region ${{ env.GCP_REGION }} \ --format 'value(status.url)') echo "SERVICE_URL=$SERVICE_URL" >> $GITHUB_OUTPUT echo "Service URL: $SERVICE_URL" - name: Run smoke tests env: SERVICE_URL: ${{ steps.get-url.outputs.SERVICE_URL }} run: | echo "Testing health endpoint..." HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" ${SERVICE_URL}/health) if [ $HTTP_STATUS -eq 200 ]; then echo "✅ Health check passed" else echo "❌ Health check failed with status: $HTTP_STATUS" exit 1 fi echo "Testing alive endpoint..." HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" ${SERVICE_URL}/alive) if [ $HTTP_STATUS -eq 200 ]; then echo "✅ Alive check passed" else echo "❌ Alive check failed with status: $HTTP_STATUS" exit 1 fi - name: Deployment summary run: | echo "## 🚀 Staging Deployment Successful" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "**Service**: ${{ env.SERVICE_NAME }}" >> $GITHUB_STEP_SUMMARY echo "**Image**: gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.IMAGE_NAME }}:staging-${{ github.sha }}" >> $GITHUB_STEP_SUMMARY echo "**URL**: ${{ steps.get-url.outputs.SERVICE_URL }}" >> $GITHUB_STEP_SUMMARY echo "**Commit**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY echo "**Branch**: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY ``` #### 4.2 Production Deployment Workflow **File**: `.github/workflows/deploy-production.yml` ```yaml name: Deploy to Production on: push: branches: - main env: GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} GCP_REGION: ${{ secrets.GCP_REGION }} SERVICE_NAME: tableau-mcp-production IMAGE_NAME: tableau-mcp jobs: deploy: name: Deploy to Cloud Run Production runs-on: ubuntu-latest environment: production steps: - name: Checkout code uses: actions/checkout@v4 - name: Authenticate to Google Cloud uses: google-github-actions/auth@v2 with: credentials_json: ${{ secrets.GCP_SA_KEY }} - name: Set up Cloud SDK uses: google-github-actions/setup-gcloud@v2 with: project_id: ${{ secrets.GCP_PROJECT_ID }} - name: Configure Docker for GCR run: | gcloud auth configure-docker - name: Build Docker image run: | docker build \ -t gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.IMAGE_NAME }}:production-${{ github.sha }} \ -t gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.IMAGE_NAME }}:production-latest \ . - name: Push Docker image to GCR run: | docker push gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.IMAGE_NAME }}:production-${{ github.sha }} docker push gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.IMAGE_NAME }}:production-latest - name: Deploy to Cloud Run run: | gcloud run services update ${{ env.SERVICE_NAME }} \ --image gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.IMAGE_NAME }}:production-${{ github.sha }} \ --region ${{ env.GCP_REGION }} \ --platform managed - name: Get service URL id: get-url run: | SERVICE_URL=$(gcloud run services describe ${{ env.SERVICE_NAME }} \ --region ${{ env.GCP_REGION }} \ --format 'value(status.url)') echo "SERVICE_URL=$SERVICE_URL" >> $GITHUB_OUTPUT echo "Service URL: $SERVICE_URL" - name: Run smoke tests env: SERVICE_URL: ${{ steps.get-url.outputs.SERVICE_URL }} run: | echo "Testing health endpoint..." HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" ${SERVICE_URL}/health) if [ $HTTP_STATUS -eq 200 ]; then echo "✅ Health check passed" else echo "❌ Health check failed with status: $HTTP_STATUS" exit 1 fi echo "Testing alive endpoint..." HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" ${SERVICE_URL}/alive) if [ $HTTP_STATUS -eq 200 ]; then echo "✅ Alive check passed" else echo "❌ Alive check failed with status: $HTTP_STATUS" exit 1 fi echo "Testing ready endpoint..." HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" ${SERVICE_URL}/ready) if [ $HTTP_STATUS -eq 200 ]; then echo "✅ Ready check passed" else echo "❌ Ready check failed with status: $HTTP_STATUS" exit 1 fi - name: Deployment summary run: | echo "## 🎉 Production Deployment Successful" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "**Service**: ${{ env.SERVICE_NAME }}" >> $GITHUB_STEP_SUMMARY echo "**Image**: gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.IMAGE_NAME }}:production-${{ github.sha }}" >> $GITHUB_STEP_SUMMARY echo "**URL**: ${{ steps.get-url.outputs.SERVICE_URL }}" >> $GITHUB_STEP_SUMMARY echo "**Commit**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY echo "**Branch**: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY ``` #### 4.3 Pull Request Testing Workflow (Optional but Recommended) **File**: `.github/workflows/test.yml` ```yaml name: Test on: pull_request: branches: - main - staging jobs: test: name: Run Tests runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '18' cache: 'npm' - name: Install dependencies run: npm ci - name: TypeScript compilation check run: npm run build - name: Run tests run: npm test continue-on-error: true - name: Test summary run: | echo "## 🧪 Test Results" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "**Branch**: ${{ github.head_ref }}" >> $GITHUB_STEP_SUMMARY echo "**Commit**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "✅ TypeScript compilation successful" >> $GITHUB_STEP_SUMMARY ``` --- ### Step 5: Update Cloud Run Configuration Files The existing Cloud Run YAML files need minor updates to work seamlessly with GitHub Actions. #### Update `cloud-run-staging.yaml` **Change line 42** from: ```yaml image: gcr.io/PROJECT_ID/tableau-mcp:staging-latest ``` To (add comment): ```yaml image: gcr.io/PROJECT_ID/tableau-mcp:staging-latest # Updated by GitHub Actions ``` **No other changes needed** - GitHub Actions will use `gcloud run services update` which overrides the image. #### Update `cloud-run-production.yaml` **Change line 42** from: ```yaml image: gcr.io/PROJECT_ID/tableau-mcp:production-latest ``` To (add comment): ```yaml image: gcr.io/PROJECT_ID/tableau-mcp:production-latest # Updated by GitHub Actions ``` --- ### Step 6: Update Documentation #### 6.1 Update `README.md` Add new section after "Quick Start - Cloud Run Deployment": ````markdown ## GitHub-Based Deployment (Automated CI/CD) ### Prerequisites - GitHub account with access to repository - Google Cloud project configured - GitHub secrets configured (see `GITHUB_CICD_PLAN.md`) ### Deployment Workflow #### Deploy to Staging 1. Make your changes in a feature branch 2. Merge or push to `staging` branch: ```bash git checkout staging git merge feature-branch git push origin staging ``` 3. GitHub Actions automatically: - Builds Docker image - Pushes to Google Container Registry - Deploys to `tableau-mcp-staging` Cloud Run service - Runs smoke tests 4. Monitor deployment: https://github.com/russelenriquez-agile/tableau-mcp-project/actions #### Deploy to Production 1. Create pull request from `staging` to `main` 2. Get PR approved by team member 3. Merge PR to `main` 4. GitHub Actions automatically: - Waits for manual approval (production environment protection) - Builds Docker image - Pushes to Google Container Registry - Deploys to `tableau-mcp-production` Cloud Run service - Runs comprehensive smoke tests #### Rollback If you need to rollback to a previous version: ```bash # Find the commit SHA of the working version git log # Checkout that commit git checkout <commit-sha> # Push to staging or create a revert commit for main git revert <bad-commit-sha> git push origin main ``` ### Manual Deployment (Legacy) For emergency situations, manual deployment scripts are available: - `deploy-staging.sh` - Manual staging deployment - `deploy-production.sh` - Manual production deployment See `DEPLOYMENT_GUIDE.md` for manual deployment procedures. ```` #### 6.2 Create `GITHUB_WORKFLOW.md` **File**: `GITHUB_WORKFLOW.md` (separate comprehensive documentation) This file should include: - Detailed workflow architecture - Branch strategy explanation - GitHub Actions troubleshooting - Common deployment scenarios - Security best practices (The content would be similar to this plan document but more operational/user-focused) #### 6.3 Update `PASS_OFF.md` Update Phase 6 section to include GitHub Actions: ```markdown ## Phase 6: Cloud Run Deployment & CI/CD **Status**: ✅ Complete & Automated (November 19, 2025) ### Completed Tasks - ✅ Cloud Run deployment infrastructure - ✅ GitHub Actions CI/CD pipelines - ✅ Automated staging deployments (push to staging branch) - ✅ Automated production deployments (push to main branch with approval) - ✅ Service account configured for GitHub Actions - ✅ Branch protection rules configured ``` --- ### Step 7: Legacy Scripts Updates Update the existing deployment scripts with deprecation notices: #### Update `deploy-staging.sh` Add at the top after the shebang: ```bash #!/bin/bash # ================================================================ # LEGACY SCRIPT - Replaced by GitHub Actions # ================================================================ # This script is kept for emergency manual deployments only. # Normal deployments should use the GitHub Actions workflow: # - Push to 'staging' branch for automatic deployment # - See GITHUB_WORKFLOW.md for details # ================================================================ echo "⚠️ WARNING: This is a legacy manual deployment script." echo " GitHub Actions is now the primary deployment method." echo " Continue with manual deployment? (yes/no)" read -r CONFIRM if [ "$CONFIRM" != "yes" ]; then echo "Deployment cancelled." exit 0 fi # ... rest of existing script ``` #### Update `deploy-production.sh` Same deprecation notice as staging script. --- ### Step 8: Add `.gitignore` Updates Ensure the following are in `.gitignore`: ```gitignore # GitHub Actions artifacts (if any local testing) .github/workflows/*.test # GCP Service Account Keys (NEVER COMMIT) *-key.json github-actions-key.json service-account-*.json ``` --- ## Deployment Testing Checklist After implementing all steps, test the complete workflow: ### Staging Deployment Test - [ ] Create a test branch from `staging` - [ ] Make a minor change (e.g., update a comment in `README.md`) - [ ] Commit and push to `staging` branch - [ ] Verify GitHub Actions workflow triggers - [ ] Check workflow logs for successful deployment - [ ] Test the deployed staging service endpoints - [ ] Verify service URL matches expected staging URL ### Production Deployment Test - [ ] Create a pull request from `staging` to `main` - [ ] Verify PR checks run successfully - [ ] Get PR approval from team member - [ ] Merge PR to `main` - [ ] Verify GitHub Actions workflow triggers - [ ] Approve the production deployment (manual gate) - [ ] Check workflow logs for successful deployment - [ ] Test the deployed production service endpoints - [ ] Verify service URL matches expected production URL ### Rollback Test - [ ] Identify a previous working commit - [ ] Create rollback PR (revert commit) - [ ] Deploy rollback to staging first - [ ] Verify staging works with rollback - [ ] Deploy rollback to production if needed --- ## Benefits of GitHub CI/CD ### 1. **Automation** - No manual `gcloud` commands - No manual Docker builds - Consistent deployment process every time ### 2. **Version Control** - Every deployment tied to a git commit - Easy to see what code is deployed where - Simple rollback by reverting commits ### 3. **Audit Trail** - GitHub logs who deployed what and when - Approval records for production deployments - Complete deployment history ### 4. **Safety** - Branch protection prevents accidental deployments - Required reviews for production changes - Automated tests catch issues before deployment ### 5. **Speed** - Push to deploy in minutes - No context switching to command line - Parallel deployments if needed ### 6. **Collaboration** - Team can see deployment status - Easy to troubleshoot with shared logs - Documented process in repository --- ## Troubleshooting ### Issue: GitHub Actions workflow fails with authentication error **Solution**: 1. Verify `GCP_SA_KEY` secret is correctly formatted (entire JSON content) 2. Check service account has required IAM roles 3. Verify project ID in secret matches actual GCP project ### Issue: Docker build fails in GitHub Actions **Solution**: 1. Check Dockerfile syntax 2. Ensure all dependencies are in `package.json` 3. Test Docker build locally first 4. Check GitHub Actions logs for specific error ### Issue: Cloud Run deployment succeeds but service fails health checks **Solution**: 1. Check Cloud Run logs in GCP Console 2. Verify environment variables are correctly set 3. Ensure secrets exist in Google Secret Manager 4. Test locally with same environment variables ### Issue: Production deployment waiting indefinitely for approval **Solution**: 1. Check GitHub repository → Environments → production 2. Verify you're listed as a required reviewer 3. Go to Actions → Click on running workflow → Click "Review deployments" 4. Approve the deployment ### Issue: Unable to push to protected branch **Solution**: 1. Create a feature branch 2. Make changes in feature branch 3. Create pull request to merge into protected branch 4. Get approval and merge --- ## Security Considerations ### 1. **Service Account Key Management** - ✅ Store in GitHub Secrets (encrypted) - ✅ Use least-privilege IAM roles - ✅ Rotate keys periodically (every 90 days) - ❌ Never commit keys to repository - ❌ Never log or echo key contents ### 2. **Branch Protection** - ✅ Require PR reviews for main branch - ✅ Prevent force pushes to main - ✅ Enable status checks before merge - ✅ Use GitHub environments for production approval ### 3. **Secrets Management** - ✅ Application secrets in Google Secret Manager - ✅ GitHub Secrets for CI/CD credentials only - ✅ Use environment-specific secrets (staging vs production) - ❌ Never expose secrets in logs or outputs ### 4. **Image Tagging** - ✅ Tag images with git commit SHA - ✅ Maintain `latest` tag for convenience - ✅ Never overwrite existing SHA-tagged images - ❌ Don't rely solely on `latest` for production ### 5. **Approval Gates** - ✅ Manual approval required for production - ✅ Documented approval process - ✅ Audit trail of who approved deployments - ✅ Test in staging before production --- ## Cost Optimization ### GitHub Actions - **Free tier**: 2,000 minutes/month for private repositories - Each deployment takes ~5-10 minutes - Estimated: 200-400 deployments/month within free tier ### Google Container Registry - Storage costs: ~$0.026/GB/month - Network egress: First 1GB free, then $0.12/GB - Estimated: <$5/month for image storage ### Cloud Run - Existing costs unchanged (billed per request and compute time) - No additional cost for automated deployments --- ## Migration Timeline | Step | Duration | Dependencies | |------|----------|--------------| | 1. Repository push | 10 minutes | None | | 2. Service account setup | 15 minutes | GCP access | | 3. GitHub configuration | 20 minutes | Repository access | | 4. Create workflows | 30 minutes | None | | 5. Update configs | 10 minutes | None | | 6. Update documentation | 20 minutes | None | | 7. Update legacy scripts | 10 minutes | None | | 8. Testing | 30 minutes | All above complete | | **Total** | **~2.5 hours** | Sequential | --- ## Success Criteria - ✅ Code pushed to GitHub repository (both main and staging branches) - ✅ GitHub Actions workflows created and enabled - ✅ Service account created with correct permissions - ✅ GitHub Secrets configured - ✅ Branch protection rules active - ✅ Successful staging deployment via GitHub Actions - ✅ Successful production deployment via GitHub Actions (with approval) - ✅ Smoke tests pass after deployment - ✅ Documentation updated - ✅ Team trained on new workflow --- ## Next Steps After Implementation 1. **Phase 7: Cursor Integration** - Create `tableau.json` MCP config file - Test tools in Cursor agent mode - Document Cursor integration 2. **Phase 8: Testing & Documentation** - Comprehensive testing suite - End-to-end integration tests - User documentation updates 3. **Future Enhancements** - Add automated testing in CI pipeline - Implement code quality checks (ESLint, Prettier) - Add dependency scanning (Dependabot) - Implement performance monitoring - Add deployment notifications (Slack, email) --- ## Support & Contacts **Repository**: https://github.com/russelenriquez-agile/tableau-mcp-project **Documentation**: See `GITHUB_WORKFLOW.md` (to be created) for operational guide **Issues**: Use GitHub Issues for bug reports and feature requests **Deployments**: Monitor at https://github.com/russelenriquez-agile/tableau-mcp-project/actions --- **Plan Created**: November 19, 2025 **Status**: Ready for Implementation **Estimated Implementation Time**: 2-3 hours

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/russelenriquez-agile/tableau-mcp-project'

If you have feedback or need assistance with the MCP directory API, please join our Discord server