Microsoft Fara Tutorial: Run a Browser-Use Agent in Google Colab with a Mock OpenAI-Compatible Endpoint
In this tutorial, we set up Microsoft Fara in Google Colab and run a browser-use workflow from start to finish. We begin by cloning the repository, installing the package, preparing Playwright, and verifying that the installed Fara files work even when the package layout changes. Instead of immediately relying on a heavy Fara-7B deployment, we create a small mock OpenAI-compatible endpoint that returns valid browser actions. This lets us test the same agent loop that Fara uses for real tasks, including sending a task, receiving model-style action responses, and executing those actions through the browser. We also keep the endpoint configuration flexible, so the same notebook can later connect to Azure Foundry, vLLM, LM Studio, or Ollama when we want to use the real Fara-7B model.
import os
import sys
import json
import time
import socket
import subprocess
import importlib
from pathlib import Path
USE_REAL_FARA_ENDPOINT = False
REAL_FARA_BASE_URL = "http://localhost:5000/v1"
REAL_FARA_API_KEY = "not-needed"
REAL_FARA_MODEL = "microsoft/Fara-7B"
TASK = "Open example.com and tell me what the page is."
WORKDIR = Path("/content/fara_tutorial")
REPO_DIR = Path("/content/fara")
REPO_SRC = REPO_DIR / "src"
OUTPUT_DIR = WORKDIR / "outputs"
ENDPOINT_CONFIG_PATH = WORKDIR / "endpoint_config.json"
MOCK_SERVER_FILE = WORKDIR / "mock_fara_endpoint.py"
WORKDIR.mkdir(parents=True, exist_ok=True)
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
We import the required Python libraries and define the main configuration values for the tutorial. We decide whether to use the mock endpoint or connect to a real Fara endpoint, and we set the browser task that the agent needs to perform. We also create the working folders and file paths for the repository, endpoint configuration, mock server, and output files.
def run_cmd(cmd, cwd=None, check=True, env=None):
print(f"n$ {cmd}")
result = subprocess.run(
cmd,
shell=True,
cwd=str(cwd) if cwd else None,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
env=env,
)
print(result.stdout)
if check and result.returncode != 0:
raise RuntimeError(f"Command failed with exit code {result.returncode}: {cmd}")
return result
def wait_for_port(host, port, timeout=60):
start = time.time()
while time.time() - start < timeout:
try:
with socket.create_connection((host, port), timeout=2):
return True
except OSError:
time.sleep(1)
return False
print("Python:", sys.version)
print("Working directory:", WORKDIR)
We define a command runner that lets us execute shell commands in the notebook and view the output clearly. We also create a helper function that checks whether a server is active on a given port before the next step runs. We then print the Python version and working directory to confirm that the Colab environment is set up correctly.
os.chdir("/content")
if REPO_DIR.exists():
print("Fara repo already exists. Pulling latest changes...")
run_cmd("git pull", cwd=REPO_DIR, check=False)
else:
run_cmd("git clone https://github.com/microsoft/fara.git /content/fara")
print("nInstalling Fara and tutorial dependencies...")
run_cmd(
f'{sys.executable} -m pip install -q "setuptools<82" wheel pip',
check=True,
)
run_cmd(
f'{sys.executable} -m pip install -q -e /content/fara fastapi uvicorn requests pillow',
check=True,
)
if str(REPO_SRC) not in sys.path:
sys.path.insert(0, str(REPO_SRC))
print("nInstalling Playwright Firefox browser and system dependencies...")
run_cmd(
f"{sys.executable} -m playwright install --with-deps firefox",
check=True,
)
We clone the Microsoft Fara repository into Colab, or pull the latest version if the repository already exists. We install Fara along with the supporting packages needed for the mock endpoint and browser workflow. We also install Playwright Firefox support so the agent can control a browser during execution.
print("nInspecting Fara package files...")
try:
import fara
print("Imported fara from:", getattr(fara, "__file__", "unknown"))
except Exception as e:
print("Could not import fara:", repr(e))
print("nAvailable files inside /content/fara/src/fara:")
if (REPO_SRC / "fara").exists():
for p in sorted((REPO_SRC / "fara").glob("*.py")):
print("-", p.name)
else:
print("Could not find /content/fara/src/fara")
print("nTrying to inspect Fara action definitions...")
try:
fara_agent = importlib.import_module("fara.fara_agent")
action_defs = getattr(fara_agent, "FARA_ACTION_DEFINITIONS", None)
if action_defs:
print("nFara action space:")
for action_name, arg_names in action_defs.items():
args = ", ".join(sorted(arg_names)) if arg_names else "no arguments"
print(f"- {action_name}: {args}")
else:
print("FARA_ACTION_DEFINITIONS was not found. Continuing because this step is optional.")
except Exception as e:
print("Could not import fara.fara_agent directly:", repr(e))
print("Continuing because this inspection step is optional.")
We inspect the installed Fara package and check where it is being imported from in the notebook. We list the Python files in the Fara source folder to understand the current package structure. We then try to load the Fara action definitions safely, while keeping the tutorial running even if the import path changes.
mock_server_code = r'''
from fastapi import FastAPI, Request
import time
app = FastAPI()
STATE = {"calls": 0}
@app.post("/v1/chat/completions")
async def chat_completions(request: Request):
payload = await request.json()
STATE["calls"] += 1
model_name = payload.get("model", "mock-fara-7b")
if STATE["calls"] == 1:
content = (
"I will open a stable public test page so the browser-control loop can be demonstrated.n"
"{"name":"computer","arguments":{"action":"visit_url","url":"https://example.com"}}"
)
else:
content = (
"The browser has opened Example Domain, a stable demonstration page used for documentation and examples.n"
"{"name":"computer","arguments":{"action":"terminate","status":"success"}}"
)
return {
"id": f"chatcmpl-mock-{STATE['calls']}",
"object": "chat.completion",
"created": int(time.time()),
"model": model_name,
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": content
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 100,
"completion_tokens": 50,
"total_tokens": 150
}
}
'''
MOCK_SERVER_FILE.write_text(mock_server_code)
print(f"nMock endpoint written to: {MOCK_SERVER_FILE}")
if USE_REAL_FARA_ENDPOINT:
endpoint_config = {
"model": REAL_FARA_MODEL,
"base_url": REAL_FARA_BASE_URL,
"api_key": REAL_FARA_API_KEY,
}
else:
endpoint_config = {
"model": "mock-fara-7b",
"base_url": "http://127.0.0.1:8001/v1",
"api_key": "not-needed",
}
ENDPOINT_CONFIG_PATH.write_text(json.dumps(endpoint_config, indent=2))
print("nEndpoint config:")
print(ENDPOINT_CONFIG_PATH.read_text())
mock_process = None
if not USE_REAL_FARA_ENDPOINT:
print("nStarting mock OpenAI-compatible endpoint...")
mock_process = subprocess.Popen(
[
sys.executable,
"-m",
"uvicorn",
"mock_fara_endpoint:app",
"--host",
"127.0.0.1",
"--port",
"8001",
],
cwd=str(WORKDIR),
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
)
if not wait_for_port("127.0.0.1", 8001, timeout=60):
if mock_process and mock_process.stdout:
print(mock_process.stdout.read())
raise RuntimeError("Mock endpoint did not start on port 8001.")
print("Mock endpoint is running at http://127.0.0.1:8001/v1")
else:
print("nUsing real Fara endpoint. Make sure it is reachable.")
We create a mock OpenAI-compatible endpoint that returns valid Fara-style browser actions. We write the endpoint configuration file so Fara knows whether to call the mock server or a real Fara-7B endpoint. We then start the mock server in the background and wait until it is ready to receive requests.
print("nRunning Fara browser agent...")
fara_command = (
f'fara-cli '
f'--task "{TASK}" '
f'--endpoint_config "{ENDPOINT_CONFIG_PATH}"'
)
agent_result = run_cmd(fara_command, cwd=REPO_DIR, check=False)
if agent_result.returncode != 0:
print("nfara-cli failed, trying module form...")
fara_command = (
f'{sys.executable} -m fara.run_fara '
f'--task "{TASK}" '
f'--endpoint_config "{ENDPOINT_CONFIG_PATH}"'
)
agent_result = run_cmd(fara_command, cwd=REPO_DIR, check=False)
print("nFara command exit code:", agent_result.returncode)
print("nSaved tutorial outputs:")
if OUTPUT_DIR.exists():
files = sorted(OUTPUT_DIR.glob("*"))
if files:
for path in files:
print("-", path)
else:
print("No files saved in output directory.")
else:
print("Output directory does not exist.")
real_usage_notes = """
============================================================================
How to switch this notebook from mock mode to real Fara-7B
============================================================================
Option A: Azure Foundry endpoint
Set:
USE_REAL_FARA_ENDPOINT = True
REAL_FARA_BASE_URL = "https://your-endpoint.inference.ml.azure.com/"
REAL_FARA_API_KEY = "YOUR_AZURE_FOUNDRY_KEY"
REAL_FARA_MODEL = "Fara-7B"
Option B: self-host with vLLM on a GPU machine
Run this separately on the GPU machine:
vllm serve "microsoft/Fara-7B" --port 5000 --dtype auto
Then set:
USE_REAL_FARA_ENDPOINT = True
REAL_FARA_BASE_URL = "http://localhost:5000/v1"
REAL_FARA_API_KEY = "not-needed"
REAL_FARA_MODEL = "microsoft/Fara-7B"
Option C: LM Studio or Ollama
Load a compatible Fara-7B model and enable an OpenAI-compatible local server.
Example base URLs:
LM Studio: http://localhost:1234/v1
Ollama-style OpenAI server: http://localhost:11434/v1
Important:
Browser agents should be tested in sandboxed environments only.
Avoid private accounts, payments, credentials, and high-risk websites.
============================================================================
"""
print(real_usage_notes)
if mock_process is not None:
print("nStopping mock endpoint...")
mock_process.terminate()
try:
mock_process.wait(timeout=10)
except subprocess.TimeoutExpired:
mock_process.kill()
print("Mock endpoint stopped.")
print("nTutorial complete.")
We run the Fara browser agent using fara-cli and use the module command as a fallback if the CLI call fails. We print the result, check any generated output files, and include the settings needed to switch from mock mode to a real Fara-7B deployment. We finally stop the mock endpoint and close the tutorial cleanly.
In conclusion, we have a Colab-ready Fara setup that demonstrates the main browser-control pipeline without requiring GPU resources or a live model server. We installed the framework, prepared the browser runtime, safely inspected the action setup, started a local mock endpoint, and ran the Fara CLI on a simple web task. The mock endpoint helps us verify that the agent loop, endpoint format, and browser execution flow are working before moving to a real model deployment. We also left the code structured so switching from mock mode to Fara-7B only requires changing the endpoint settings.
Check out the Full Codes here. Also, feel free to follow us on Twitter and don’t forget to join our 150k+ ML SubReddit and Subscribe to our Newsletter. Wait! are you on telegram? now you can join us on telegram as well.
Need to partner with us for promoting your GitHub Repo OR Hugging Face Page OR Product Release OR Webinar etc.? Connect with us
The post Microsoft Fara Tutorial: Run a Browser-Use Agent in Google Colab with a Mock OpenAI-Compatible Endpoint appeared first on MarkTechPost.
MarkTechPost
