I love to write code. I’m not a professional software engineer, but I appreciate the craft. Software is a rich domain for exploring ideas and the feedback loops are fast.

I decided to build an SDK. My inexperience makes me paranoid, so I lean on Claude for implementation while driving the project direction. I’m going to make mistakes, but if I set the right example, I’ll get better help from AI and other humans. Here’s what I’m trying to keep in mind:

Common sense and empathy

A lot of good engineering is common sense and being considerate of others.

  • I’m constantly asking “does this feel right?” for users and developers. If it doesn’t, I fix the issue.

  • I don’t know a bunch of software jargon. That helps me. I do the simplest thing I can think of and then find a more general solution when I’m starting to feel limited. Claude is great at helping me learn new ideas.

Here’s how this played out recently:

MCP servers have several capabilities—tools, prompts, resources, etc. I started with the simplest thing—put all registration methods directly on the ServerSession. So you’d register a new tool with ServerSession.register(tool). The problem I discovered is that, repeated across all capabilities, this practice creates a huge number of properties on the ServerSession. The code was painful to sift through. This friction led me to learn about manager classes. I wrote a ToolManager class which handles tool related tasks for the server. Now, registration is more like session.tools.register(tool). We repeated this across capabilities and it feels great.

Testing

I’m trying to test all the promises I make to users. Tests catch bugs, but more importantly they catch design issues early.

A few practices that help:

  • Name tests well. test_returns_empty_result_for_ping is better than test_handles_ping.
  • Include explicit Arrange, Act, Assert comments. It makes tests easier to follow. For example:
1
2
3
4
5
6
7
8
9
def test_filter_truthy_values():
    # Arrange
    messy_data = {"name": "Alice", "age": 0, "email": "", "active": True}
    
    # Act
    clean_data = filter_truthy_values(messy_data)
    
    # Assert
    assert clean_data == {"name": "Alice", "active": True}

Making the right thing easy

Structured templates are easy to follow and share as context.

For example, my commit messages used to be like:

1
Add tests for request handling.

for a commit where I changed three files, updated handler docs, and fixed a bug in my test fixtures.

I created a commit message template and now my commit messages indicate the work that happened. Here’s a new message:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
feat: organize client session tests by domain

What changed and why:

Split monolithic test_request_handling.py into domain-specific test
files:
- test_request_routing.py (ping + routing logic)
- test_roots_handling.py (filesystem roots functionality)
...

Impact:

- Improved test discoverability and maintainability
- Consistent organization pattern between client and server tests
...

I’ve done the same with issue and PR templates. None of this is perfect, but it’s a lot easier to write legible commit messages now. Plus, I can ask Claude “Can you draft a commit message using our template?”

Results so far

I’m doing the best work of my life. Cursor’s Apply and Tab features handle 95% of the code while I focus on design and direction. The structure and patterns I’ve established create meaningful context for AI collaboration—I don’t waste time re-explaining basic standards.

Room for improvement

I still need to oversee everything—even simple refactors. I’d like to multiply my efforts with more autonomous agents, but I don’t trust them yet. The goal is establishing such a strong track record that doing the right thing becomes natural for any agent in my codebase.

Consistency is the other challenge. I improve daily, but it’s tough to reflect my latest understanding across the entire repo.

The takeaway

LLMs and tools like Cursor are amazing levers for ambitious projects, but someone still needs to set the tone. My approach is to stick to fundamentals and let good examples compound over time. The early results are promising.