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

Robin RoyRobin Roy
4 min read

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:

  1. Plan what steps are needed

  2. Use the correct tools (functions)

  3. Scaffold a working Vite + React + TailwindCSS app

  4. Write the entire code for the app

  5. (Optional) Start it in a new terminal


🧰 Tech Stack

  • Python 3

  • OpenAI SDK

  • 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

0
Subscribe to my newsletter

Read articles from Robin Roy directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Robin Roy
Robin Roy