advancedWorkflow playbookPrimary10 min read

Using MCP to Code Faster: My Actual Workflow

Overview

I’ve spent the last three years trying every AI coding tool under the sun: GitHub Copilot, Cursor, CodeLlama running locally, even GPT-4 copy-paste workflows. All of them had the same core problem: they only knew what I bothered to tell them. If I forgot to co

Key Concepts

  • **IDE**: VS Code (I’ve tried Cursor with MCP and it works, but I prefer Claude’s native MCP integration in the official Claude VS Code extension)
  • **AI Model**: Claude 3.5 Sonnet (I pay for Claude Pro, which supports MCP natively in the extension for no extra cost)
  • **MCP Servers (per project, not global)**: Official filesystem, GitHub, Postgres, and npm servers. I’ve tried others like Brave Search and Playwright, but I only add them when I need them for a specific task to avoid slowing down responses.
  • **Core architecture for new projects**: I don’t let MCP design the overall folder structure, database schema, or core dependency choices for a new project. It will give you a generic architecture that works fine for a demo, but it doesn’t know my long-term requirements for the project. I’ve tried letting it do the heavy lifting here, and ended up with a mess that took me days to refactor 3 months later. I do the big architecture decisions myself, then use MCP to implement the individual features.
  • **Any connection to production**: As I learned the hard way, the risk is way too high. Even if you think you have permissions locked down, I never take the chance. If I need to debug production, I pull a copy of the relevant data down to local and debug it there with MCP.
  • **Large-batch refactoring**: I’ve let MCP refactor 10 files at once to update a shared type, and it introduced subtle breaking changes in 2 of the files I missed when reviewing the whole batch. Now I do one file at a time, review each change, and only move to the next. It’s a little slower, but avoids nasty regressions.

I’ve spent the last three years trying every AI coding tool under the sun: GitHub Copilot, Cursor, CodeLlama running locally, even GPT-4 copy-paste workflows. All of them had the same core problem: they only knew what I bothered to tell them. If I forgot to copy-paste my database schema, they’d hallucinate column names. If I didn’t show them the existing pattern for API routes in my codebase, they’d invent a new one that didn’t fit. That changed when I started using the Model Context Protocol (MCP) six months ago. MCP lets your AI coding assistant access real, live data from your local environment, external APIs, and services directly, without you manually copying everything over. It’s not a new AI model, it’s a protocol that lets the AI pull context on its own, and it’s cut my development overhead by more than half. This is my actual, tested workflow, warts and all.

My Setup

I’ve landed on a simple setup that works for full-stack development, and I’ve intentionally kept it minimal to avoid bloat and security risks:

  • **IDE**: VS Code (I’ve tried Cursor with MCP and it works, but I prefer Claude’s native MCP integration in the official Claude VS Code extension)
  • **AI Model**: Claude 3.5 Sonnet (I pay for Claude Pro, which supports MCP natively in the extension for no extra cost)
  • **MCP Servers (per project, not global)**: Official filesystem, GitHub, Postgres, and npm servers. I’ve tried others like Brave Search and Playwright, but I only add them when I need them for a specific task to avoid slowing down responses.

The biggest tradeoff I made early on was deciding to configure MCP per-project instead of globally. Giving an AI unrestricted access to your entire computer’s filesystem is a huge security risk, so I only grant access to the current workspace I’m working in. For example, here’s my actual `.vscode/mcp.json` config that works out of the box if you have the Claude extension installed:

```json

// .vscode/mcp.json (add to your project root, no extra installation needed beyond npx)

{

"servers": {

"filesystem": {

"command": "npx",

"args": ["-y", "@modelcontextprotocol/server-filesystem", "${workspaceFolder}"]

},

"github": {

"command": "npx",

"args": ["-y", "@modelcontextprotocol/server-github"],

"env": {

"GITHUB_PERSONAL_ACCESS_TOKEN": "${env:GITHUB_MCP_TOKEN}"

}

},

"postgres": {

"command": "npx",

"args": ["-y", "@modelcontextprotocol/server-postgres", "${env:LOCAL_DB_URL}"]

},

"npm": {

"command": "npx",

"args": ["-y", "@modelcontextprotocol/server-npm"]

}

}

}

```

Another key tradeoff: I use a dedicated read-only Postgres user for MCP, even on my local database. I’ll get into why later, but it’s a 2-minute setup that saved me from a hours-long disaster a few weeks back.

Workflow 1: Starting a New Feature

Before MCP, the first 10 minutes of any new feature was just me hunting down relevant files, copying types, and explaining existing code patterns to the AI. Now, I let MCP do all that context gathering in seconds. I’m currently building a personal finance tracking app, so let’s use my recent work adding a CSV export for recurring transactions as an example. My verbatim prompt to Claude is always the same structure, just swap out the details:

> "Using the filesystem MCP server, list all files in the `src/features/transactions` and `src/types` directories, read the existing transaction type definitions, and check how all existing transaction API routes are structured in `app/api/transactions`. I want to add a CSV export feature that lets users download all their recurring transactions from the last 90 days. Use the existing coding patterns you see for auth and API routes, and only add a new dependency if there isn’t already something in the codebase that works. If you need a new dependency, use the npm MCP server to find a well-maintained option."

That’s it. The AI automatically reads all the relevant files, checks what patterns you’re already using, and even picks a current, well-maintained package instead of pulling a deprecated one from its 2-year-old training data. In this case, it picked papaparse, which is exactly what I would have chosen, and generated the API route matching my existing Next.js App Router patterns:

```typescript

// app/api/transactions/export-csv/route.ts (generated end-to-end by AI via MCP)

import { NextResponse } from 'next/server';

import Papa from 'papaparse';

import { auth } from '@/lib/auth';

import { getRecurringTransactions } from '@/features/transactions/getRecurringTransactions';

export async function GET(request: Request) {

const session = await auth();

if (!session?.user?.id) {

return new NextResponse('Unauthorized', { status: 401 });

}

const { searchParams } = new URL(request.url);

const days = searchParams.get('days') ? parseInt(searchParams.get('days') as string, 10) : 90;

const transactions = await getRecurringTransactions({

userId: session.user.id,

startDate: new Date(Date.now() - days * 24 * 60 * 60 * 1000)

});

const csv = Papa.unparse(transactions.map(t => ({

id: t.id,

name: t.name,

amount: t.amount,

frequency: t.frequency,

nextChargeDate: t.nextChargeDate,

category: t.category || 'Uncategorized'

})));

return new NextResponse(csv, {

headers: {

'Content-Type': 'text/csv',

'Content-Disposition': `attachment; filename="recurring-transactions-${new Date().toISOString().slice(0, 10)}.csv"`

}

});

}

```

The practical tradeoff here: if you’re not specific about which directories to check, the AI will read dozens of irrelevant files, which bogs down the response and eats into your context window. I used to just say “read my codebase” and wait 30 seconds for a response; now I specify exact directories and get a response in 7-10 seconds. It’s a tiny change that makes a huge difference in daily use.

Workflow 2: Debugging

This is where MCP saves me more time than any other use case. I can’t count how many hours I spent before MCP switching between my IDE, database client, and AI chat, copying query results back and forth to debug a weird data issue. Now, the AI can access the database directly, check the schema, run test queries, and cross-reference the results with your actual code.

Last month, I had a bug where the dashboard transaction total was still showing the old amount after a user updated a recurring transaction. My verbatim prompt was:

> "The dashboard total is wrong after updating a recurring transaction: it still shows the old amount. The main function is `getDashboardTotals` in `src/features/dashboard/getDashboardTotals.ts`. Connect to the local Postgres database, check the transactions table schema, run a query for my test user ID `123e4567-e89b-12d3-a456-426614174000`, and compare what the database returns to what the function is returning. Find why the total is wrong."

Within 2 minutes, MCP had found the bug: when you update a recurring transaction, my code soft-deletes the old entry and creates a new one, but the `getDashboardTotals` function was filtering for `deleted IS NULL` instead of `deleted = false`. The old deleted entry had `deleted = true`, so it wasn’t being filtered out, and it was still being added to the total. Fixed in 2 minutes, where it would have taken me 15 minutes of jumping between tools before.

But this is where I hit my worst MCP gotcha, the one I still think about. I was in a hurry to fix a password reset bug on our staging environment before a client demo the next day. Staging had a copy of production user data, and I’d added the MCP Postgres server to the project, using my default admin database role that had write access. My prompt was asking it to debug why test user tokens were expiring early. I wasn’t paying close attention, went to grab a coffee, and came back to find it had run this query:

```sql

-- Accidentally run by MCP on my staging database

UPDATE password_reset_tokens SET expires_at = NOW() + INTERVAL '1 day' WHERE user_id IS NOT NULL;

```

It was supposed to update just my test user’s token, but it interpreted “test user” as any user with “test” in their email, which was 500 out of 600 staging users. I had a backup, but restoring it took an hour, and I missed the concert I was supposed to go to with my partner that night. That’s why I’m now militant about two rules: never connect MCP to any environment with real production data, even staging, and always use a read-only database role for MCP. The convenience of the AI being able to run queries isn’t worth the risk of accidental data loss. I’d rather apply the fix myself than deal with that again.

Workflow 3: Pre-PR Code Review

Most people don’t talk about using MCP for code review, but it’s become a non-negotiable step for me before I ask a teammate to review my code. MCP can pull your PR changes directly from GitHub via the GitHub MCP server, cross-reference them against your existing codebase, and catch all the obvious mistakes you missed after hours of coding. My standard verbatim prompt is:

> "Use the GitHub MCP server to pull all changes from PR #42. Check the changes against existing codebase patterns and look for: 1) missing error handling, 2) unvalidated user input, 3) violations of our typing rules, 4) deviations from existing patterns for this feature. Don’t flag minor style issues like variable naming, just actual bugs or pattern violations. Summarize what you find and suggest fixes."

Last week, this caught that I’d forgotten to validate the `days` parameter in the CSV export route I built. If someone passed `?days=-10000`, the API would pull every transaction a user ever created, which could easily cause a timeout or OOM error. I completely missed that, and MCP caught it in 10 seconds before I sent the PR for review. Before MCP, I’d spend 10-15 minutes manually going through every changed line to catch these kinds of issues, and I’d still miss half of them.

The tradeoff here: MCP doesn’t replace human code review. It just catches the obvious, low-level mistakes so your reviewer can focus on architecture and business logic, not typos or missing validation. I’ve had it miss subtle logic issues that a human caught immediately, so I still require a human review for every PR, but MCP cuts down on review time for everyone involved.

Workflow 4: Documentation

I hate writing documentation. Always have. MCP has turned a 20-minute chore into a 2-minute check. It can read your new code, check how you’ve written documentation for other features, and update your README or add docstrings matching your existing tone and structure. My standard prompt is:

> "I added the new CSV export feature for recurring transactions, all code is in `app/api/transactions/export-csv` and `src/features/transactions/components/ExportCSVButton`. Read the existing `README.md` and check how other features are documented in the repo. Update the README to add a section for this new feature matching the existing tone and structure, and add JSDoc docstrings to all new public functions and components."

It does 90% of the work correctly out of the box, and I just spend a minute trimming any redundant fluff it adds. The tradeoff: I never let it write public-facing customer-facing documentation without a full review. It can still hallucinate what the feature does even with access to the code, so I always read it over carefully. But for internal READMEs and inline docstrings, it’s a massive time saver.

What I Don’t Use MCP For

MCP isn’t a silver bullet. There are a lot of things I still do manually, because the tradeoffs aren’t worth it:

  1. **Core architecture for new projects**: I don’t let MCP design the overall folder structure, database schema, or core dependency choices for a new project. It will give you a generic architecture that works fine for a demo, but it doesn’t know my long-term requirements for the project. I’ve tried letting it do the heavy lifting here, and ended up with a mess that took me days to refactor 3 months later. I do the big architecture decisions myself, then use MCP to implement the individual features.
  2. **Any connection to production**: As I learned the hard way, the risk is way too high. Even if you think you have permissions locked down, I never take the chance. If I need to debug production, I pull a copy of the relevant data down to local and debug it there with MCP.
  3. **Large-batch refactoring**: I’ve let MCP refactor 10 files at once to update a shared type, and it introduced subtle breaking changes in 2 of the files I missed when reviewing the whole batch. Now I do one file at a time, review each change, and only move to the next. It’s a little slower, but avoids nasty regressions.
  4. **Compliance-critical code**: If I’m working on code that handles HIPAA or PCI data, I write the core logic myself and only use MCP for boilerplate. I’m responsible for that code, and I don’t want to rely on an AI to get compliance right.

Time Saved Estimate

I work full-time as a full-stack developer, coding roughly 30 hours a week. Before MCP, I spent about 8-10 hours a week on overhead: context gathering, manual debugging steps, pre-PR self-review, writing documentation. That’s almost a full day a week of work that isn’t actually building anything. After MCP, that overhead is down to 2-3 hours a week. I save roughly 6-7 hours a week on average, which is almost a full extra work day every week. To break it down more concretely:

  • 9 minutes saved per new feature (cut from 10 minutes of context gathering to 1 minute), 5 features a week: 45 minutes saved
  • 13 minutes saved per bug (cut from 15 minutes of manual tool switching to 2 minutes), 10 bugs a week: 130 minutes saved
  • 9 minutes saved per pre-PR check (cut from 10 minutes to 1 minute), 4 PRs a week: 36 minutes saved
  • 13 minutes saved per feature for documentation (cut from 15 minutes to 2 minutes), 5 features a week: 65 minutes saved

That adds up to 276 minutes, or 4.6 hours a week, even in a slow week. In weeks with more debugging or new features, it’s closer to 7 hours. That’s time I can spend building more impactful features, or leaving work on time to spend with my family, which is priceless.

Actionable Next Steps

If you want to try this workflow yourself, start with these concrete steps to avoid the mistakes I made:

  1. **Start small**: Add MCP to just one side project first, with only the filesystem MCP server. Don’t add 5 servers at once. Use the config I shared earlier to get set up in 2 minutes.
  2. **Lock down permissions first**: Create a read-only Postgres user specifically for MCP, never use your admin role. Only give MCP access to your current workspace, not your entire home directory.
  3. **Use the prompt templates I shared**: Copy the verbatim prompts from this post into a note, and adjust them for your project. You don’t need to reinvent the prompt wheel to get good results.
  4. **Never connect MCP to production or staging with real user data**: Write this rule down somewhere you’ll see it. No exceptions.
  5. **Audit after a month**: After a month of use, remove any MCP servers you don’t actually use. I had 6 servers added at one point, realized I only used 4 regularly, and removing the extra two cut my response time by a third.

MCP doesn’t replace you as a developer, but it eliminates almost all of the boring overhead that slows you down. After six months of using it daily, I can’t imagine going back to the old copy-paste workflow.

What To Do Next

Move from this guide to a concrete workflow and a matching tool page to apply the concepts.

References

Last updated: April 5, 2026

Sponsored