The best way to create Claude skills in .NET
The best way to write a Claude skill is not to write it yourself. Give Claude Code a prompt and it builds the skill for you.
I created two skills this way for an ASP.NET Core Web API. One adds a new Entity Framework Core entity, and the other adds a new Minimal API endpoint.
Create a skill for adding an EF Core entity
The first skill adds a new entity to Entity Framework Core.
Before pasting in the prompt, I put Claude Code into plan mode. In plan mode, Claude Code reads the project and plans the changes, but it doesn't make any of them until you're happy with the plan.
The prompt
This is the prompt I gave to Claude Code:
/planCreate a new skill for adding a new entity into Entity Framework Core.The user must give an entity name and configuration values. These must be provided otherwise the entity cannot be created.
Table name
Primary key
Properties and their column types. If it's a string, max length must be specified.
The configuration will be stored in its own class which implements
IEntityTypeConfiguration.It will also add it as a
DbSettoEcommerceDbContext. There will also be a new repository class called{EntityName}Repositorywhich will be added to the Repositories folder. This will inject theDbContextinto the class through the constructor and store it as a private readonly field. It will not contain any methods.The interface will be set up in the Application project. The class will implement the interface and it will be added to dependency injection.
A new test class will be set up for the repository in InfrastructureTests. This will create the repository and create an in-memory instance of the
DbContext. An instance to the repository will be created as a private readonly field. No test methods will be added.
The prompt covers two things. It lists the values that the skill must be given before it can create an entity, and it describes each file that the skill needs to create or change.
Claude's question about soft deletes
The project already has a Product entity, and it has a Deleted property to allow for soft deletes.
Claude Code spotted this and asked how the new skill should handle soft deletes for new entities. It offered three options:
Ask for each entity whether it can be soft deleted, which was the option it recommended
Always add a
Deletedcolumn and a query filter to every new entityNever add it, leaving soft deletes to be added by hand later
I chose to be asked for each entity. When the answer is yes, the skill adds a nullable Deleted property and a query filter that matches the one used for Product.
The plan
Claude Code then came up with a plan. It starts with some context around the skill, and states that it will create the skill in .claude/skills/add-entity/SKILL.md and add it to the list of skills in CLAUDE.md. No C# code is changed at this point. The skill only generates code when it's run.
The plan then sets out the three steps that the skill will follow:
Collect and validate inputs: The entity name, the table name, the primary key and each property with its C# type and column type are all required. Every
stringmust have a max length. If anything is missing, the skill lists what is missing, asks for it and creates nothingGenerate the files: Each file is based on the existing
Productfiles in the project. The plan also includes mapping rules, such as usingHasMaxLengthfor strings andHasColumnTypefor every other columnVerify and report: The skill builds the solution, runs the tests and summarises the files that it created and modified. It doesn't generate a migration, but it tells you that one is needed
I was happy with the plan, so I got Claude Code to implement it.
Get notified of new content
Join other .NET developers improving their skills and knowledge.
The skill that Claude Code created
The skill follows the plan closely. It begins with a name, a description that tells Claude Code when to use it and a hint for the arguments that it accepts.
After that, it goes through each of the three steps. The first step lists the required values and tells Claude Code never to guess, invent or default any of them. It also lists the reasons to stop and create nothing, such as a string property with no max length.
The second step has a code example for each file, showing how the code should be structured. There is one for the entity, the configuration class, the DbSet, the repository interface, the repository, the dependency injection registration and the test class. Claude Code follows these examples whenever it uses the skill.
The skill is stored in the .claude folder. Inside the skills folder, Claude Code created a new add-entity folder and saved the skill as SKILL.md.
Why use plan mode
I like to put Claude Code into plan mode when creating a skill. It plans out the skill and asks questions about things I haven't even thought of that need to go into it.
The soft delete question is a good example. It wasn't in the prompt, but the answer is now part of the skill.
What the skill stops you forgetting
When you add a string property to an entity, Entity Framework Core sets the column type to nvarchar(max) unless you specify a max length.
It also chooses the table name unless you override it. EF Core uses the name of the DbSet property when the entity has one, and the name of the entity class when it doesn't.
These are things I've forgotten many times in the past. That is the whole point of adding a skill: to make sure they aren't forgotten.
It's why the prompt states that the table name must be given, and that every string property must have a max length.
Testing the entity skill
To test the skill, I left that information out of the prompt to see what would happen:
Add a new
Categoryentity withId,NameandDeleted
Missing data
Claude Code didn't create anything. It explained that the skill won't guess or fill in defaults for missing details, and that the request left several of them out.
It listed what was missing:
The table name
The primary key
The C# type and the column type for
IdThe C# type, the column type and the max length for
NameWhich properties, if any, can be null
It also pointed out that the skill doesn't treat Deleted as a normal property. It's added when the entity is marked as one that can be soft deleted, so Claude Code asked me to confirm that this is what I wanted.
Finally, it gave a short format that I could use to reply with all the values on one line. I used that format:
Category table=Categories key=Id Id:int:int Name:string:nvarchar:100 soft-delete=yes
This sets the table name to Categories with a key of Id. The Id property is an int, and Name is a string stored as nvarchar with a max length of 100. The entity can also be soft deleted.
The generated code
With all the values supplied, Claude Code created the files. Looking at them in Visual Studio:
Categorieshas been added as aDbSettoEcommerceDbContextThe
Categoryentity has been created with all of its propertiesThe entity is configured in its own
CategoryConfigurationclass, which sets the table name, the primary key, the max length forNameand the query filter for soft deletesThe repository, its interface and its test class have been created, and the repository has been added to dependency injection
It's no coincidence that Claude Code structured the code in that way. All of those rules are in the skill.
Why skills stop AI making assumptions
This is where you can get frustrated with AI. If you don't give it enough information, it makes assumptions, which it loves to do.
A skill gives Claude Code that information every time, and tells it to stop and ask when something is missing.
Another benefit is that skills should cost you fewer tokens. Claude Code only loads the name and description of each skill to begin with. It reads the full skill when it uses it, so it has less information to read before making a decision.
Create a skill for adding a Minimal API endpoint
The second skill adds a new Minimal API endpoint. Once again, I put Claude Code into plan mode first.
The prompt
This is the prompt I gave to Claude Code:
/planCreate a new skill for adding a Minimal API endpoint:Specify a name for the Minimal API endpoint. It will create a new
{Name}Endpoints.cs file in the Api project, structured like this:public static class {Name}Endpoints { extension (WebApplication app) { public WebApplication Map{Name}Endpoints() { var group = app.MapGroup("/api/{GroupEndpoint}"); return app; } } }The group endpoint must be specified otherwise the endpoint can't be created.
It will be referenced in Program.cs by calling
app.Map{Name}Endpoints().The skill must also create a new test method to check it works. Create a test method in the Endpoints file:
public static string Test() => "Works";And then referencing it the
Map...Endpointsmethod.group.MapGet("/test", Test);Run the application. Check it appears in the Swagger Document and run the endpoint to check the output gets the correct response.
The plan
The plan is for a skill called add-endpoint. It's created in .claude/skills/add-endpoint/SKILL.md, uses the same layout as the entity skill and is added to the list of skills in CLAUDE.md.
It has the same three steps as the last skill:
Collect and validate inputs: The name and the group endpoint are both required, and the group endpoint is never worked out from the name. The skill stops and creates nothing if either one is missing, or if the endpoints class already exists
Generate the code: The skill creates the endpoints class, based on the existing
ProductsEndpointsclass, and adds the call to it in Program.cs. It also creates a test class for the endpoint. That wasn't in the prompt, but CLAUDE.md states that every endpoint handler must have testsVerify and report: The skill builds the solution, runs the tests and then runs the API. It checks that the OpenAPI document and Swagger both load and that the test endpoint returns
Works, before stopping the API and listing the files that it created and modified
I was happy with the plan, so I got Claude Code to implement it.
This skill is a good fit for the task. Whenever you create a controller or a Minimal API endpoint, there is a lot of boilerplate code. It's easy to miss something out, and it can take ages to debug.
The skill
Like the entity skill, this one goes through each of the steps and gives a code example for each of them. There is one for the endpoints class, one for the line that is added to Program.cs and one for the test class.
Testing the endpoint skill
I tested the skill with this prompt:
Create a category endpoint using Minimal APIs
Missing data
Like last time, I didn't give it enough information, and Claude Code flagged it without creating anything.
The skill needs two values, and only one of them was clear from the prompt:
Name: The prompt said "category", which would create a
CategoryEndpointsclass. As the existingProductsEndpointsclass is plural, Claude Code asked whether the name should beCategoryorCategoriesGroup endpoint: This was missing. It's the route that goes after
/api/, and the skill doesn't allow Claude Code to work it out from the name
I gave it a name of Categories and a group endpoint of categories, using the format that it suggested:
Categories group=categories
Verify and report
Once the code has been created, Claude Code moves on to the last step in the skill. This is where it proves that the code works.
It builds the solution to make sure that the code it added hasn't broken anything. After that, it runs the unit tests to make sure that they all pass.
It then runs the API. The skill created a test endpoint in the group, so Claude Code calls it to make sure that it works.
Finally, it reports on what it did. It created CategoriesEndpoints.cs with a test route in the /api/categories group, created CategoriesEndpointsTests.cs to test it, and added a call to app.MapCategoriesEndpoints() in Program.cs.
It also reported that the solution built with no warnings or errors and that all the tests passed. With the API running, the OpenAPI document and Swagger both returned a 200 response, and the test endpoint returned Works. It stopped the API afterwards.
Checking the result
Claude Code reported that everything was successful, but I was sceptical and wanted to check it for myself.
I ran all the tests and they passed, which also means that the solution built successfully.
I then ran the API and tried out the test endpoint in Swagger. It returned a 200 response with a response body. The endpoint is there because the skill states that a test endpoint must be created.
Give the skill enough information
Skills make this kind of task much quicker and easier, and you're less likely to make mistakes, as long as there is enough information in the skill.
Getting Claude Code to write the skill in plan mode helps with that. Your prompt covers what you know the skill needs, and its questions cover what you missed.
Watch the video
Watch the video where I show you how to get Claude Code to create both skills, and test them by adding a category entity and a category endpoint.
Download the resources
The prompts, plans, skills and code that are featured in this tutorial are all available to view when you download the code example below.
Related tutorials
Learn when to use TypedResults vs Results in minimal APIs and explore the different response types available for returning API responses.
Learn how to use the new LeftJoin and RightJoin LINQ methods introduced in EF Core for .NET 10, replacing the verbose GroupJoin and SelectMany pattern.