Skip to main content

Command Palette

Search for a command to run...

Journal: From Copilot Prompts to a Full Link Shortener App

A day of agentic coding, Drizzle ORM, Neon MCP, and learning when context runs out

Published
8 min read
R

Full-stack Engineer specializing in Node.js, Nest.js, MERN. Expert in building scalable APIs & real-time apps. Focus on clean code, Security, and performance.

Setting Up Copilot Agents with Custom Instructions

I started GitHub Copilot Beginner to Pro - AI for Coding & Development Udemy course and wanted to learn agentic coding. By following the course, I added custom agents and prompts to the GitHub Copilot setup inside the profiler. Basically treating Copilot like a proper agentic coding partner for the first time.

The first prompt was simple:

create a /dashboard page, no real content yet, just a placeholder.

Then I layered in the standards — a follow-up prompt told it to make sure the dashboard page follows the authentication coding standard. What surprised me was that the agent actually went and read the authentication.md file inside the /docs folder on its own. No hand-holding needed.

I did the same for the home page, and again it read the relevant instruction doc. Then I asked it to make sure the sign-up and sign-in buttons follow the UI component coding standard — and it pulled up ui-component.md, read it, and updated the header accordingly using the shadcn component. That felt like a proper workflow clicking into place.


Tightening the Agent Instructions

After watching the agent work, I realized the instruction chain needed to be more explicit. I gave it a prompt to update AGENTS.md to make it crystal clear that reading the relevant individual instruction files inside /docs before generating any code is non-negotiable.

The agent rewrote the AGENTS.md file — added a new critical section, listed all the directive documents, and restructured things so the priority order was obvious. Small prompt, meaningful change.


Signing Up for the Anthropic API

Since I'm actively learning agentic coding, I went ahead and signed up for the Anthropic API. Bought $5 of credit to start experimenting with the models directly — coding, audio processing, that sort of thing.


Understanding Agent Types

Took a moment to properly understand the different types of agents available:

  • Local agent — you give it a prompt and it runs directly on your device.

  • Background agent — starts working in the background after receiving a prompt.

  • Cloud agent — similar to GitHub Copilot's cloud-based execution model.

Each has its own trade-offs depending on the task. Good to have the mental model straight before diving deeper.


Moved on to actual feature work. I needed a database table to store shortened links. Gave the agent a prompt to design a simple table schema and it created a schema file inside the /db folder using the Drizzle ORM.

The schema had the right fields: id, shortcode, url, userId, createdAt, and updatedAt. Table name: links. Clean and straightforward.

import { pgTable, text, varchar, timestamp } from 'drizzle-orm/pg-core';

export const links = pgTable('links', {
  id: text('id').primaryKey(),
  shortCode: varchar('short_code', { length: 20 }).notNull().unique(),
  originalUrl: text('original_url').notNull(),
  userId: text('user_id').notNull(),
  createdAt: timestamp('created_at').defaultNow().notNull(),
  updatedAt: timestamp('updated_at').defaultNow().notNull(),
});

I started with the ask agent type to let it design the schema first before committing to implementation. Once I was happy with it, I told the agent to start the implementation. I also asked it to properly declare and type the id fields.

Then came the sync step — I asked how to push the schema to the Neon platform. It walked me through:

  1. npx drizzle-kit generate — generates the SQL migration file inside the /drizzle folder.

  2. npx drizzle-kit push — syncs the schema to the Neon database.

Worked first try.


Using MCP Inside VS Code with Neon

This was a new one for me. Learned how to connect an MCP (Model Context Protocol) extension in VS Code to an external service — in this case, Neon.

The flow is roughly:

  1. Install the Neon MCP extension in VS Code.

  2. Connect your Neon account to the extension.

  3. Configure which tools you want to expose to the Copilot chat.

  4. Enable those tools and start prompting.

Once connected, I could just type list my Neon projects and it would return actual project data from my Neon account. I also ran list out tools you have with the Neon MCP and got back the full list of available operations.

The most satisfying part: I asked it to generate 10 example link records following my schema, and it produced a JSON file with 10 properly structured entries. Then I told it to insert that data into my links table using my user ID — it generated a small script and ran it, populating the Neon database directly.


Switching to Native GitHub Copilot Instructions

Found out that GitHub Copilot has a native instruction system built around the .github/instructions/ folder. You put instruction files there, give each one a description in the front matter, and Copilot agents automatically pick up the right ones based on the description.

This is basically the same pattern I was already using with the /docs folder — but now it's native. A few things to note:

  • All instruction files use the .instructions.md extension.

  • You write a description in the front matter — that's what the agent reads to decide if a file is relevant.

  • You no longer need to manually reference these files in AGENTS.md.

I migrated my existing instruction files into .github/instructions/ and that cleaned things up nicely.


With the instructions in place, I gave the agent a real feature prompt: build out the dashboard page, query for the currently logged-in user's links, and display them as a list. I referenced the dashboard file directly using # in the prompt.

It updated the dashboard page, wired up the query, and the list rendered correctly — showing links tied to the logged-in user. There were a couple of UI issues after the first pass, but one follow-up prompt fixed them. Dashboard was functional.


Server Actions — Writing the Instruction File

Before building out more features, I created a new instruction file specifically for server actions. The rules I put in:

  • All data mutations go through server actions only.

  • Server actions must be called from the component that needs them.

  • Files must be named action.ts and live in the same directory as the calling component.

  • All incoming data must have proper TypeScript types — no any.

  • All data must be validated via Zod.

  • Always check for a logged-in user before touching the database.

  • Database operations go through helper functions (located in the /db directory) — server actions don't write raw queries.

  • Server actions must never throw. They return either { error: "..." } or { success: "..." }.


Create, Edit, Delete, and Redirect

With the standards locked in, I moved fast on features:

Create: Prompted the agent to implement the link creation flow from the dashboard. It added a create button and the supporting logic.

Refresh bug: After creating a link, the dashboard wasn't updating. Gave a prompt describing the bug and it traced it back to the codebase and fixed it.

Edit & Delete: One prompt — implement edit via a modal, delete via a confirmation dialog, referenced the dashboard file. It implemented both. There was a small typing bug in the edit modal's input field; another short prompt fixed it.

Redirect: Asked it to implement the redirect functionality via an API route handler. Whenever someone hits /l/[shortcode], they get redirected to the full URL. It created the route handler and it works.


Learning About Subagents

Took a detour to understand subagents. The idea is:

When a task is large, the main agent's context window can fill up fast. Subagents are isolated agent instances spun up by the main agent to handle specific chunks of the work. Each subagent gets its own full context, so you're not cramming everything into one window.

They're especially useful for parallel tasks — things that don't depend on each other can run at the same time across separate subagents.


Skills and Context Management

Related to the context problem — learned about "skills". The issue is that loading all instruction files and MCP tool definitions on every prompt burns through context quickly.

With skills, the agent only loads the description of each skill upfront. Based on the prompt, it decides which skills are actually needed, then loads only those specific instruction sets. It's lazy-loading for agent knowledge.

For a project with lots of directive files, this makes a real difference in how far you can go before the context fills up.


Wrapping Up — Course Done, Model Costs

Finished the GitHub Copilot Beginner to Pro course today. The project — a working link shortener — turned out well. Honestly impressed with how capable agentic coding was throughout.

Here is the final project.

One thing I noticed along the way: the Claude Code model is noticeably more expensive than alternatives. Worth looking into Minimax M2.5 AI as cheaper options that apparently perform close to Claude. Planning to watch a few comparison videos on YouTube and also explore running the Qwen 3.5 AI model locally to see if I can get similar results without the cost.


Total features shipped: dashboard, create/edit/delete links, redirect handler, server action standards, MCP-driven seed data. Next up: model cost comparison, local model experiments.

16 views