As an AppSec engineer at Vim, I’ve spent a lot of time helping developers adopt secure coding practices – through onboarding, education, and collaborative reviews.
But with over 50 developers and just one of me, that approach didn’t scale.
Then came Cursor.
In just a few months, it changed how code was written — not line by line, but prompt by prompt. Cursor’s AI became a second pair of hands, rapidly generating handlers, logic, and full services.
It was fast. It worked. But it didn’t always produce secure code.
Without context or constraints, the AI might skip validation, hardcode secrets, mishandle tokens, or introduce risky defaults — and developers might not even realize it.
Security wasn’t just overlooked — it was being automated out.
That raised a real question:
Would our standards hold if the AI was writing most of the code?
It made me wonder — is this a gift… or a Cursor?
The Idea: Embedding Security into Code Generation
After spending time hands-on with Cursor, I started thinking:
If every developer uses the same AI agent to generate code, maybe I don’t need to step in every time personally. Developers still need to understand secure coding, but what if I could reinforce those principles automatically when the code is written?
That’s where Cursor’s Model Context Protocol (MCP) came in — a lightweight interface that lets you run your background process. Cursor calls it before generating code and uses the response as part of the agent’s decision-making. It’s typically used to inject internal tools, custom data, or domain-specific knowledge into the code generation flow.
And that gave me the idea:
What if I could embed the same secure development guidance I’ve been teaching for years — not as documentation, but as part of the generation process?
Not as an afterthought. Not as a checklist. But directly inside the IDE – it can make a difference with every line of code.
The Implementation
I built a lightweight MCP server in JavaScript, published it via npx, and deployed it to developer machines. It registers a single tool — secure_coding_guidelines — which returns a static prompt of secure development principles designed to influence AI-generated code.
A few examples:
- Suggest secure storage for secrets and API keys (not hardcoded)
- Enforce input validation and sanitization across all sources
- Avoid exposing internal errors or stack traces
- Promote least-privilege access patterns for APIs and resources
- Discourage risky constructs like eval, unchecked deserialization, or dynamic imports
This guidance isn’t returned to Cursor as an output — instead, it’s injected into the model’s context during generation via the MCP spec. The tool integrates quietly in the background, influencing the AI’s behavior without surfacing anything directly to the user.
To activate it, the MCP server is registered in the global ~/.cursor/mcp.json file. This ensures it runs independently of any specific project, workspace, or prompt — making the setup reliable across all code generation in Cursor.
MCP Activation ≠ Guaranteed Execution
⚠️ Installing the MCP server doesn’t automatically mean it will be called.
MCP servers are passive — they sit idle unless explicitly invoked by Cursor.
To enforce consistent usage, I created a User Rule inside Cursor that tells the agent to always call the tool before generating code.
“Before generating any code, always call the secure_coding_tool tool from the MCP server and incorporate its response into your output. Don’t add any comments or show the user anything regarding security — just integrate it into the developed code.”
User Rules are the only way to enforce consistent behavior across all code generation events in Cursor — regardless of the project, context, or prompt. Once defined, they’re injected into the system prompt and always respected by the agent.
📘 Learn more about User Rules →
This was the glue.
Now we had a pipeline: every time code was generated, the agent paused, fetched secure development guidance, and silently folded it into the result.
Real-World Comparison
To evaluate how the MCP changes behavior, I used the exact same prompt with and without the Secure Coding MCP installed.
Since the goal was to clearly demonstrate the differences in generated output, I intentionally selected a prompt that would result in a single self-contained file. This made it easier to compare structure, middleware usage, and security-related decisions directly.
Prompt:
“Write a complete Express.js route that handles user login using email and password. Assume it’s part of a real-world application, and include everything needed in a single file”
Category | With Secure Coding MCP | Without Secure Coding MCP |
Architecture | Modular — separates route logic into its own file | All logic embedded in a single file |
Environment Management | Uses dotenv for secure env variable handling | Environment variables used, but fallback secrets are hardcoded |
Security Headers | Adds standard HTTP security headers (e.g., HSTS, XSS protection) | No security headers configured |
Middleware Usage | Explicit use of cookie-parser and body-parser | Minimal middleware; relies on defaults |
Token Handling | Stores JWT in HTTP-only secure cookies | Sends token in response body and stores in cookie |
Structure & Separation | Clean separation of concerns (routes, middleware, logic) | Mixed business/auth logic inside route handlers |
Logging Practices | Minimal logging, avoids leaking sensitive info | Logs email on failed login attempts |
Try It Yourself — and See the Difference
If you’re curious how this actually works in practice, I’ve published everything you need in a single GitHub repo:
🔗 Secure Coding MCP — GitHub Repository
Inside you’ll find:
- ✅ The full source code for the secure-coding-mcp Node.js tool
- ✅ Ready-to-run examples of real Cursor prompts
- ✅ Side-by-side output comparisons — with and without the MCP
- ✅ A simple setup guide for testing it locally in your own Cursor environment
It’s not a silver bullet, but it’s made secure coding a lot easier to keep up with — especially at scale. And seeing it actually used by our devs every day? That’s the real win.