Generate and edit Draw.io, Mermaid, and Excalidraw diagrams from natural language using a structured JSON spec.
Design & media
artsonia-api
Try itAccess Artsonia (artsonia.com) student-art portfolios, comments, fans, teacher feedback, and downloads from a shell with curl instead of running the artsonia-mcp server — log in with a username/password form POST to get a session cookie, then curl the server-rendered member pages. Use when you want Artsonia data without the MCP, in a script, or on a machine where the MCP isn't installed.
What it does
Artsonia is a classic server-rendered site — no public API, no JSON store, no bot wall. All the data (students, portfolios, comments, fans, feedback, awards, profile) lives in server-rendered HTML, and auth is a real **username + password form POST** that hands back an HttpOnly session cookie. No…
The skill document
Artsonia via curl (no MCP)
Artsonia is a classic server-rendered .asp site — no public API, no JSON
store, no bot wall. All the data (students, portfolios, comments, fans,
feedback, awards, profile) lives in server-rendered HTML, and auth is a real
username + password form POST that hands back an HttpOnly session
cookie. No browser, no Transporter extension, no fpx bridge is needed —
curl with a cookie jar reaches everything a signed-in parent account can.
(The MCP keeps @fetchproxy/server as an optional fallback transport for
some future walled endpoint, but nothing documented here needs it.)
This is the same data the artsonia_* MCP tools return, reached with curl
instead of a running server.
One-time setup
export ARTSONIA_USERNAME=you@example.com
export ARTSONIA_PASSWORD='your-password' # or: op read "op://Private/Artsonia/password"
JAR=~/.cache/artsonia-cookies.txt
mkdir -p ~/.cache # ensure the jar's directory exists on a fresh box
: > "$JAR" # fresh jar
Log in (get the session cookie)
Read the password from stdin (Password@-) instead of putting it on the
command line — --data-urlencode name=value puts value in curl's argv,
which any local user can read via ps//proc while the process runs. This
mirrors how the MCP itself sends the password: only in the POST body, never
on a command line.
printf '%s' "$ARTSONIA_PASSWORD" | curl -s -c "$JAR" -b "$JAR" -L \
--data-urlencode "Username=$ARTSONIA_USERNAME" \
--data-urlencode "Password@-" \
--data-urlencode "TargetUrl=/members/" \
--data-urlencode "Action=login" \
-o /tmp/artsonia-login.html -w '%{http_code} %{url_effective}\n' \
https://www.artsonia.com/members/login.asp
A successful login redirects away from login.asp (final URL ends in
.../members/) and leaves cookies in $JAR. If url_effective still ends
in login.asp, or /tmp/artsonia-login.html matches You need to log in|Parent \(or Fan\) Login, the credentials are wrong — Artsonia has no
CSRF/__VIEWSTATE token, so a bad login is the only reason this fails.
Magic-link-only accounts can't use this (there's no password to POST).
Re-run this exact command any time a later request looks logged-out (see
"Session expiry" below) — curl -c overwrites the jar with a fresh session.
Core call pattern
Every read is a GET through the jar; every write is a form-urlencoded
POST through the jar. Fetch to a file, then extract:
curl -s -b "$JAR" -c "$JAR" 'https://www.artsonia.com/members/' -o /tmp/dash.html
For the numeric ids every other endpoint needs (artist_id, artwork_id),
a plain regex on the href is enough and needs no extra tooling:
grep -oP '(?<=portfolio\.asp\?id=)\d+' /tmp/dash.html | sort -u
For the full structured fields (name, school, stats, notifications, awards,
…) don't re-derive selectors by hand — this repo already ships a
live-verified node-html-parser scraper (src/parse.ts → built
dist/parse.js) with one function per page. Build it once, then import it
in a one-liner and pipe the JSON to jq:
cd ~/git/artsonia-mcp && npm install && npm run build # once, if dist/ is missing
node --input-type=module -e "
import { readFileSync } from 'node:fs';
import { parseStudents } from '$(pwd)/dist/parse.js';
console.log(JSON.stringify(parseStudents(readFileSync('/tmp/dash.html', 'utf8'))));
" | jq '.'
references/endpoints.md has the ready-to-run curl command, dist/parse.js
import, and jq projection for every read and write tool, keyed to the same
paths and selectors the MCP uses.
The one rule: resolve artist_id (and artwork_id) first
Every per-student/per-artwork endpoint needs a numeric id you can only get from a parent call — never guess one:
GET /members/→.artist-card→artist_id(from each card'sportfolio.asp?id=link).GET /artists/portfolio.asp?id=→.grid-itemthat contains anart.asplink →artwork_id.
Session expiry
Artsonia expires a session by redirecting/rendering back to the login page, not a 401. After any GET/POST, check the response body:
grep -qE 'login\.asp|You need to log in|Parent \(or Fan\) Login' /tmp/out.html \
&& echo "EXPIRED — re-run the login step"
Writes — real caveats from the MCP build
- A 3xx is not proof a write persisted. Artsonia's form handlers 302
even on payloads they silently drop. Re-
GETthe page you just changed and confirm the field actually flipped before trusting a write. - Checkboxes submit
value=Y, neveron. SendingField=onis silently ignored by the server (still 302s, saves nothing). - The profile form is read-modify-write.
/members/profile/(#TheForm) bundles name/email/password/opt-ins in one form — re-POST every current field verbatim (blank the password fields, keepDidChangePassword=N), flipping only the one you're changing. - Never POST a password. Leave
OldPassword/NewPassword/NewPassword2blank/omitted.
See references/endpoints.md for the exact body of every write, and how to
re-read and verify each one.
Artwork images (no auth needed)
Full-resolution images live on a public CDN — no cookie required, even for private pieces:
curl -s -o "$artwork_id.jpg" "https://images.artsonia.com/art/full/$artwork_id.jpg"
curl -sI "https://images.artsonia.com/art/full/$artwork_id.jpg" | grep -i last-modified # per-artwork upload date
Resolutions (small→large): small medium large xlarge full.
Notes
- Reads/writes both go through the member site (
www.artsonia.com); nothing here needs thefetchproxy/browser-bridge path the MCP keeps as an optional fallback. - Comment-item markup on
/museum/art.aspis unverified upstream (both captured accounts had 0 comments) —references/endpoints.mdflags it. - This project is developed and maintained by AI (Claude).
Related skills
Fetch raw ad creative, app, ranking, and revenue data from AdMapix as structured JSON.
Join a video meeting as an AI bot with voice, avatar, and screenshare across four operating modes.
Stores durable facts in a categorized, plain-markdown vault on disk, alongside your agent's built-in memory.
Read and write Excel workbooks, worksheets, ranges, tables, and charts in OneDrive through Microsoft Graph with managed OAuth.
Find why your productivity system keeps failing, then apply the smallest fix — capacity math, bottleneck routing, durable local notes.
More from chrischall
Browse all skillsRead and write OurFamilyWizard messages, calendar events, expenses, and journal entries from your agent.
Find, inspect, compare, and resolve Compass listings, photos, prices, addresses, and property records.
Pull Credit Karma transactions into a local SQLite database and query them by category, merchant, or account.
Search, book, and cancel Resy reservations, plus favorites and Priority Notify alerts.
Manage iOffice buildings, rooms, visitors, maintenance, moves, and mail through natural-language commands.
Look up concert setlists, tour histories, and live-show data on setlist.fm through natural-language MCP tools.