diff --git a/agents/openscader/index.yaml b/agents/openscader/index.yaml
new file mode 100644
index 0000000..46252ea
--- /dev/null
+++ b/agents/openscader/index.yaml
@@ -0,0 +1,14 @@
+name: Openscader
+description: openscader
+version: 0.1.0
+instructions: |
+ You are a professional 3d designer, openscad user. You consult this cheatsheet often - https://openscad.org/cheatsheet/
+
+
+ {{__tools__}}
+
+
+
+ cwd: {{__cwd__}}
+
+
diff --git a/agents/openscader/tools.txt b/agents/openscader/tools.txt
new file mode 100644
index 0000000..01e1717
--- /dev/null
+++ b/agents/openscader/tools.txt
@@ -0,0 +1,5 @@
+web_search_exa.sh
+fetch_url_via_exa.sh
+fs_cat.sh
+fs_write.sh
+execute_openscad.sh
diff --git a/tools/execute_openscad.sh b/tools/execute_openscad.sh
new file mode 100755
index 0000000..e7b4f56
--- /dev/null
+++ b/tools/execute_openscad.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+set -e
+
+# @describe Execute the openscad file.
+# @option --path! Path of the file to execute.
+
+# @meta require-tools openscad
+
+# @env LLM_OUTPUT=/dev/stdout The output path
+
+ROOT_DIR="${LLM_ROOT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
+
+main() {
+ openscad "$argc_path" -o /tmp/aichat_openscad.echo || true
+ cat /tmp/aichat_openscad.echo >> "$LLM_OUTPUT"
+}
+
+eval "$(argc --argc-eval "$0" "$@")"
diff --git a/tools/fetch_url_via_exa.sh b/tools/fetch_url_via_exa.sh
new file mode 100755
index 0000000..839fb60
--- /dev/null
+++ b/tools/fetch_url_via_exa.sh
@@ -0,0 +1,47 @@
+#!/usr/bin/env bash
+set -e
+
+# @describe Fetch contents of a URI using Exa API.
+# Use this when you need to get contents of a link, where you think relevant info is to be found.
+# If you have several sources for a subject to fetch, prioritize personal blogs, PDF files, official documentation, science articles.
+
+# @option --url! The query to search for.
+
+# @env EXA_API_KEY! The api key
+# @env LLM_OUTPUT=/dev/stdout The output path The output path
+
+
+main() {
+ # Make the API request and capture the full response
+ response=$(curl -fsS -X POST 'https://api.exa.ai/contents' \
+ -H "x-api-key: $EXA_API_KEY" \
+ -H 'Content-Type: application/json' \
+ -d '{
+ "urls": ["'"$argc_url"'"],
+ "text": true,
+ "livecrawlTimeout": 10000
+ }')
+
+ # Check if curl command succeeded
+ if [ $? -ne 0 ]; then
+ echo "Error: Failed to make API request" >> "$LLM_OUTPUT"
+ exit 0
+ fi
+
+ # Extract the status information
+ status=$(echo "$response" | jq -r '.statuses[0].status')
+ error_tag=$(echo "$response" | jq -r '.statuses[0].error.tag // "none"')
+ http_status=$(echo "$response" | jq -r '.statuses[0].error.httpStatusCode // 200')
+
+ # Check if the status indicates an error
+ if [ "$status" = "error" ] || [ "$http_status" != "200" ]; then
+ echo "Error: This page is unavailable" >> "$LLM_OUTPUT"
+ exit 0
+ fi
+
+ # If successful, extract and output the text
+ echo "$response" | jq -r '.results[0].text' >> "$LLM_OUTPUT"
+}
+
+eval "$(argc --argc-eval "$0" "$@")"
+
diff --git a/tools/web_search_exa.sh b/tools/web_search_exa.sh
new file mode 100755
index 0000000..aa64b27
--- /dev/null
+++ b/tools/web_search_exa.sh
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+set -e
+
+# @describe Perform a web search using Exa API to get a list of links to fetch.
+# Use this when you need current information or feel a search could provide a better answer.
+# Construct the query out of keywords, not human sentences, sorted by relevance - just like a good Google query.
+# This returns text, then URL for every result found. Judging by the title of the page, fetch relevant info.
+
+# @option --query! The query to search for.
+
+# @env EXA_API_KEY! The api key
+# @env LLM_OUTPUT=/dev/stdout The output path The output path
+
+main() {
+ json_escaped_query=$(jq -R -s . <<< "$argc_query")
+
+ response=$(curl -fsS -X POST 'https://api.exa.ai/search' \
+ -H "x-api-key: $EXA_API_KEY" \
+ -H 'Content-Type: application/json' \
+ -d "{
+ \"query\": $json_escaped_query,
+ \"type\": \"keyword\",
+ \"numResults\": 20
+ }")
+
+ # Check if curl command succeeded
+ if [ $? -ne 0 ]; then
+ echo "Error: Failed to execute search request" >> "$LLM_OUTPUT"
+ return 0
+ fi
+
+ # Check if response contains results
+ results_count=$(echo "$response" | jq -r '.results | length')
+
+ if [ "$results_count" -eq 0 ]; then
+ echo "No results found for query: $argc_query" >> "$LLM_OUTPUT"
+ else
+ # Process results normally
+ echo "$response" | jq -r '.results[] | (.title, .url, "")' >> "$LLM_OUTPUT"
+ fi
+}
+
+
+eval "$(argc --argc-eval "$0" "$@")"