Inspiration
I wanted to understand what actually happens underneath modern AI coding agents — not just use one, but build the agent infrastructure myself.
That led me to NightCode: an AI agent harness designed from scratch to connect LLMs with tools, MCP servers, files, and real coding workflows. The goal was to create a foundation where different AI providers can be plugged in without rebuilding the entire agent system.
What it does
NightCode provides an agent runtime that can:
- Connect to multiple LLM providers
- Stream model responses in real time
- Execute tool calls and return their results back to the model
- Integrate external tools through Model Context Protocol (MCP)
- Manage multi-step agent loops
- Work with files and coding tools
- Display agent activity through a real-time timeline
- Separate the agent harness from provider-specific implementations
Instead of building a single chatbot around one API, NightCode treats the model as one component of a larger agent execution system.
How I built it
I built the project from scratch using a React + TypeScript frontend and a Go backend.
The backend contains the core agent loop and provider abstraction. A provider can stream events back to the harness, while the harness handles the execution flow between the model and tools.
Conceptually, the loop looks like:
User
↓
Agent Harness
↓
LLM Provider
↓
Model Response
↓
Tool Call?
├── No → Final Response
└── Yes
↓
Tool Registry
↓
Tool Execution
↓
Tool Result
↓
LLM Provider
↓
...
I also implemented MCP integration so external MCP servers can expose tools to the agent without those tools having to be hard-coded directly into NightCode.
The frontend receives runtime events such as assistant deltas, tool execution, completion, and errors, allowing the user to see what the agent is doing instead of waiting for a single final response.
What I learned
Building NightCode taught me that an AI agent is much more than an LLM API call.
I learned about:
- Agent execution loops
- Streaming architectures
- Tool calling and tool registries
- MCP and dynamic tool discovery
- Provider abstraction
- Managing conversation and tool history
- Handling asynchronous tool execution
- Designing interfaces around agent state
- Connecting a Go backend with a modern React frontend
One of the biggest lessons was that context management becomes increasingly important as an agent performs more actions. Every tool call produces new information that must be represented correctly and passed back into the model.
Challenges
The hardest part was making the different pieces work together reliably.
Tool calling required careful handling of the model's response, tool execution, tool results, and the next model request. Streaming added another layer because the UI needed to represent an agent that was still actively working.
MCP introduced another challenge: tools are no longer necessarily known when the application is built. NightCode needed a way to discover and register tools dynamically while keeping the agent interface consistent.
I also had to think carefully about provider-specific behavior. Different models and APIs can represent tool calls and streaming events differently, so I designed the provider layer to keep those differences away from the core harness.
What's next
NightCode is still evolving. I want to continue improving its agent runtime, context management, MCP ecosystem, tool execution, and developer experience.
The long-term goal is simple:
Build the infrastructure that makes an AI agent actually useful for building software.
Built With
- api
- eino-ai-sdk
- go
- llm
- mcp
- python
- react
- rest
- shadcn-ui
- typescript
- websockets
Log in or sign up for Devpost to join the conversation.