🚀 How to Build Your Own AI Agent Like Cursor with Python and OpenAI

The future of development is here — and it speaks English.
Imagine an AI agent that understands natural language, plans tasks, writes code, executes shell commands, scaffolds projects, and even opens a new terminal to run your app — all autonomously.
In this article, you’ll learn how to build your own local AI agent, similar to Cursor, using:
🧠 OpenAI Function Calling
🐍 Python
🛠️ Shell commands
⚙️ Custom tools (like weather, project creation, code writing)
Let’s dive in!
🌟 What We’re Building
You’re going to build an autonomous AI agent that works like a coding copilot. You type:
“Create a todo app”
And it will:
Plan what steps are needed
Use the correct tools (functions)
Scaffold a working Vite + React + TailwindCSS app
Write the entire code for the app
(Optional) Start it in a new terminal
🧰 Tech Stack
Python 3
dotenv (for secrets)
subprocess / os (for commands and terminal automation)
🛠️ Step-by-Step Guide
1. Setup Project
mkdir ai-agent
cd ai-agent
python -m venv venv
source venv/bin/activate
pip install openai python-dotenv requests
2. Create .env
OPENAI_API_KEY=your_openai_key_here
3. Create Your Agent in main.py
This agent follows a Start ➝ Plan ➝ Action ➝ Observe ➝ Output loop.
It:
Parses user queries
Chooses tools based on intent
Executes tool functions (like create project, run command)
Waits for result and continues
Here’s the core logic:
from dotenv import load_dotenv
from openai import OpenAI
import subprocess, os, json, requests
from datetime import datetime
load_dotenv()
client = OpenAI()
# === Tool Definitions ===
def run_command(cmd): return os.system(cmd)
def run_in_new_terminal(cmd):
if os.name == 'nt':
os.system(f'start cmd /k "{cmd}"')
else:
subprocess.Popen(['gnome-terminal', '--', 'bash', '-c', f'{cmd}; exec bash'])
return f"Started: {cmd}"
def get_weather(city):
url = f"https://wttr.in/{city}?format=%C+%t"
return requests.get(url).text if city else "Try again"
def create_vite_project(project_name):
commands = [
f"npm create vite@latest {project_name} -- --template react-ts",
f"cd {project_name} && npm install",
f"cd {project_name} && npm install -D tailwindcss postcss autoprefixer",
f"cd {project_name} && npx tailwindcss init -p",
]
for cmd in commands: os.system(cmd)
# Inject Todo App Code
app_code = '''import React, { useState } from 'react';
export default function App() {
const [todos, setTodos] = useState<string[]>([]);
const [input, setInput] = useState('');
const addTodo = () => { if (input) setTodos([...todos, input]); setInput(''); };
return (
<div className="p-4">
<h1 className="text-2xl font-bold mb-4">Todo App</h1>
<input value={input} onChange={e => setInput(e.target.value)} className="border p-2 mr-2" />
<button onClick={addTodo} className="bg-blue-500 px-4 text-white">Add</button>
<ul>{todos.map((t, i) => <li key={i}>{t}</li>)}</ul>
</div>
);
}
'''
with open(f"{project_name}/src/App.tsx", "w") as f: f.write(app_code)
return f"Todo app created in {project_name}"
# === Tool Registry ===
available_tools = {
"get_weather": get_weather,
"run_command": run_command,
"run_in_new_terminal": run_in_new_terminal,
"create_vite_project": create_vite_project
}
4. The System Prompt
The agent uses a structured prompt that guides GPT-4 to behave like a planner/executor:
SYSTEM_PROMPT = f"""
You are a helpful AI Agent using Plan ➝ Action ➝ Observe ➝ Output flow.
Available Tools:
- get_weather(city)
- run_command(cmd)
- run_in_new_terminal(cmd)
- create_vite_project(name)
Examples:
User Query: Create a todo app
Plan: User wants to scaffold a todo app
Action: Call create_vite_project with name "todo-app"
Observe: Todo app created in todo-app
Output: Todo app scaffolded successfully.
Today is {datetime.now()}
"""
👨💻 Main Loop
Let the agent talk to you in real time:
messages = [{"role": "system", "content": SYSTEM_PROMPT}]
while True:
query = input("> ")
messages.append({"role": "user", "content": query})
while True:
res = client.chat.completions.create(
model="gpt-4.1",
response_format={"type": "json_object"},
messages=messages
)
parsed = json.loads(res.choices[0].message.content)
messages.append({"role": "assistant", "content": res.choices[0].message.content})
step = parsed.get("step")
print(f"🔹 {step}: {parsed.get('content')}")
if step == "action":
fn = parsed["function"]
input_val = parsed["input"]
result = available_tools[fn](input_val)
messages.append({"role": "user", "content": json.dumps({"step": "observe", "output": result})})
continue
if step == "output":
print(f"✅ {parsed.get('content')}")
break
🧪 Try It Out!
Try some of these:
What’s the weather in Delhi?
Create a todo app
Run todo app in new terminal
Create a file notes.txt
💡 Tips for Extending
You can easily add more tools:
def create_file(filename):
with open(filename, "w") as f: f.write("")
return f"{filename} created"
available_tools["create_file"] = create_file
And describe it in the system prompt like:
create_file(name)
creates a new file with the given name.
🧠 Conclusion
You’ve now built a personal AI assistant that can:
Understand you
Plan steps
Execute shell code
Scaffold projects
Generate files & run apps
This is the foundation of autonomous AI coding agents — and now, you can build on it however you want.
📂 Bonus
👉 Full Source Code GitHub Template
👉 Try turning this into a VS Code extension
👉 Add GitHub Copilot-style chat overlay
Subscribe to my newsletter
Read articles from Robin Roy directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
