#Dancer2
LOGOS/DANCER2.GIF
June 12, 2025 at 5:20 PM
LOGOS/DANCER2.GIF
June 18, 2025 at 5:20 PM
enjoying my day off by writing another worthless Dancer2 webapp for my own utilization
September 7, 2026 at 4:03 PM
LOGOS/DANCER2.GIF
December 28, 2024 at 6:20 PM
thanks for the reminder that I need to add live output routing to github.com/m0rb/midamp
GitHub - m0rb/midamp: MIDamp - A Perl/Dancer2 barebones webapp for playing back MIDI files on a MIDI synth
MIDamp - A Perl/Dancer2 barebones webapp for playing back MIDI files on a MIDI synth - m0rb/midamp
github.com
April 29, 2025 at 8:21 PM
I'm writing the jankiest Web 1.0 MIDI Jukebox in Dancer2

dubbing it MIDamp
September 6, 2023 at 1:02 PM
Playing around with #starman and #dancer2, since apparently no one uses #perlcgi any more.

If anyone can recommend some beginner resources, I'd appreciate it, specifically around form processing and DB interactions.

#perl #selfhosting #selfhosted #webcrafting #webserver
April 2, 2026 at 12:14 PM
I’ve been learning #CSharp and #DotNet as part of a migration project at work, and got my boss’s blessing to share some of the insights and concept-mapping I’ve done so far: itsdaves.site/2025/11/28/p...

#Dancer2 #PerlDancer #DBIxClass #EntityFrameworkCore #PostgreSQL #SQLServer
Perl vs C# (vs JavaScript)
Lately at my day job, I have been tasked with spearheading a migration of some software from Linux-based Modern Perl apps using Dancer2 and DBIx:Class to Windows-based C# apps using .NET and Entity…
itsdaves.site
November 28, 2025 at 5:01 PM
Also, a blog post on the web design process, as well as bugs and lessons learned.
https://blog.k3can.us/posts/2026/apr/everham-test/

#webcrafting #everyham #perl #dancer2 #smallweb #selfhosted
The EveryHam Amateur Radio Contest Website is Online! - k3can blog
blog.k3can.us
April 23, 2026 at 12:22 PM
Security updates for Tuesday
Security updates have been issued by **Debian** (network-manager-l2tp and urwid), **Fedora** (perl-Dancer2, perl-Data-Entropy, perl-DBI, perl-Protocol-HTTP2, podman-tui, rust-lru, and rust-lru0.16), **Mageia** (bzip2, cups-filters, libcupsfilters, libssh2, perl-Authen-SASL, perl-HTML-FormFu, tar, unzip, and zip), **Red Hat** (grafana and image-builder), **SUSE** (389-ds, acl, attr, apache2-mod_auth_openidc, apr-util, aws-nitro-enclaves-cli, bzip2, c-ares, clamav, cpio, curl, dhcpcd, dovecot23, dovecot24, dracut, emacs, fuse-overlayfs, go1.25-openssl, go1.26-openssl, google-cloud-sap-agent, google-osconfig-agent, govulncheck-vulndb, gstreamer-devtools, gzip, helm, java-17-openjdk, java-21-openjdk, java-25-openjdk, jq, libBasicUsageEnvironment2, libgpg-error, libidn, librest, libusb-1_0, libvirt, LibVNCServer, libzypp, zypper, lkl, mcphost, MozillaFirefox, mozilla-nspr, mozilla-nss, rust-cbindgen, MozillaFirefox, mozilla-nss, mozilla-nspr, rust-cbindgen, MozillaFirefox, MozillaFirefox-branding-SLE, mozilla-nspr, mozilla-nss, rust-cbindgen, msgpack-c, multipath-tools, NetworkManager, openexr, openssl-3, perl-Protocol-HTTP2, perl-URI, php-composer2, postgresql14, postgresql15, postgresql16, postgresql17, postgresql18, python-aiohttp, python-cryptography, python-h2, python-ruff, python-sqlparse, python311, python312, python39.SUSE_SLE-15-SP3_Update, rav1e, rpcbind, sssd, systemd, tomcat, tomcat11, ucode-intel, udisks2, vim, and wicked2nm), and **Ubuntu** (cgit, dracut, freeciv, konsole, libinput, linux-azure, linux-nvidia-7.0, nginx, vips, and yelp).
lwn.net
September 15, 2026 at 1:25 PM
Teaching AI About the British Monarchy with MCP One of the more interesting additions I’ve made recently to the Line of Succession website is support for the Model Context Protocol (MCP). If you...

#Programming #ai #dancer2 #line #of #succession #mcp #perl

Origin | Interest | Match
Teaching AI About the British Monarchy with MCP
One of the more interesting additions I’ve made recently to the Line of Succession website is support for the Model Context Protocol (MCP). If you’ve spent any time around AI tooling recently, you’ve probably seen people talking about MCP. It’s often described as “USB for AI”, which is perhaps a little overblown, but the basic idea is sound. MCP provides a standard way for AI assistants to discover and use external tools and data sources. In practical terms, it means that instead of building bespoke integrations for ChatGPT, Claude, Gemini and whatever comes next, you expose a standard MCP endpoint and let the AI clients do the rest. For a data-driven site like Line of Succession, that seemed like an obvious experiment. ## What is MCP? The Model Context Protocol was originally developed by Anthropic and has rapidly become one of the emerging standards in the AI ecosystem. An MCP server exposes: * Information about itself * A list of available tools * Schemas describing how those tools should be called * The results returned by those tools An AI client can connect to the server, discover the available tools and invoke them when needed. Instead of scraping web pages or attempting to infer information from HTML, the AI gets access to structured data. That’s exactly the kind of thing Line of Succession is good at. ## Why Add MCP? The site already exposes information through a traditional web interface and a JSON API. But those interfaces were designed for humans and developers respectively. MCP gives AI systems a much cleaner integration point. For example, an AI assistant can now answer questions like: * Who was the British sovereign on 14 November 1948? * What did the line of succession look like in 1980? * Who was next in line when Queen Victoria died? without having to scrape pages or understand the site’s internal URLs. More importantly, it ensures that the information comes directly from the same database that powers the website. The AI isn’t guessing. It’s querying the source of truth. As someone who runs a reference website, that’s a pretty attractive proposition. ## The Initial Design My first goal was to keep things simple. Rather than exposing dozens of narrowly-focused tools, I started with just two: * `sovereign_on_date` * `line_of_succession` Those two tools cover a surprisingly large proportion of the questions people are likely to ask. The first returns the sovereign reigning on a given date. The second returns the line of succession for a specified date, with a configurable limit on the number of entries returned. The implementation currently caps the list at thirty people. That’s enough for most use cases while preventing someone from accidentally asking for all six thousand people currently in the line of succession. One thing I learned quite quickly is that MCP isn’t really about exposing huge amounts of data. It’s about exposing useful questions that can be answered from your data. ## MCP Is Mostly JSON-RPC One thing that surprised me when I first started reading the specification was how little protocol code is actually required. At its core, MCP uses JSON-RPC. A client sends requests like: JavaScript { "jsonrpc": "2.0", "id": 1, "method": "tools/list" } 12345 | { "jsonrpc": "2.0", "id": 1, "method": "tools/list"} ---|--- and the server responds with: JavaScript { "jsonrpc": "2.0", "id": 1, "result": { ... } } 1234567 | { "jsonrpc": "2.0", "id": 1, "result": { ... }} ---|--- Once I’d written helper methods for creating standard JSON-RPC responses, most of the complexity disappeared. The MCP module contains methods like: Perl sub rpc_result ($self, $id, $result) 1 | sub rpc_result ($self, $id, $result) ---|--- and: Perl sub rpc_error ($self, $id, $code, $message) 1 | sub rpc_error ($self, $id, $code, $message) ---|--- which means the Dancer route handlers remain pleasantly small. The protocol logic lives in one place and the web application simply delegates to it. ## Separating the MCP Logic I didn’t want protocol-specific code scattered throughout the web application. Instead, I created a dedicated module: Perl package Succession::MCP; 1 | package Succession::MCP; ---|--- This module is responsible for: * Initialisation * Tool discovery * Tool execution * JSON-RPC response generation * Error handling That keeps the Dancer routes thin and makes the MCP implementation easier to test independently. It also means that if I ever decide to expose the same MCP server through a different transport mechanism, most of the work is already done. ## Tool Calls Are Mostly Adapters One pleasant surprise was how little new application logic I actually had to write. The MCP server needs to expose tools, but those tools ultimately just answer questions about the succession database. The code to answer those questions already existed. For example, the application’s model layer already contained methods such as: * `sovereign_on_date()` * `line_of_succession()` These methods power parts of the website itself, so they already encapsulate all of the business rules and database queries. The MCP implementation simply acts as an adapter. When a tool call arrives, the server extracts the arguments, validates them and passes them to the existing model methods: Perl sub _call_tool ($self, $tool_name, $args) { my $tool = $self->_tool_dispatch->{$tool_name}; return $tool->($args); } 12345 | sub _call_tool ($self, $tool_name, $args) { my $tool = $self->_tool_dispatch->{$tool_name}; return $tool->($args);} ---|--- The tool implementations themselves are deliberately thin: Perl sub sovereign_on_date ($self, $args) { my $date = $args->{date}; my $sovereign = $self->model->sovereign_on_date($date); ... } 12345678 | sub sovereign_on_date ($self, $args) { my $date = $args->{date}; my $sovereign = $self->model->sovereign_on_date($date); ... } ---|--- That’s exactly how I wanted it to work. The MCP layer doesn’t know how to calculate a line of succession or determine who was sovereign on a particular date. It simply knows how to expose those capabilities through the protocol. This is one of the advantages of adding MCP to an existing application. If your business logic is already cleanly separated from your web interface, an MCP server often becomes surprisingly straightforward to implement. In many ways, adding MCP feels less like building a new application and more like adding another interface alongside the website and API. ## The YAML Epiphany The most interesting design decision came a little later. Initially, the tool definitions lived in Perl data structures. That worked, but it quickly became obvious that I was duplicating information. The MCP server needed tool descriptions. The documentation page needed tool descriptions. The schemas needed to be defined somewhere. And every change required updating multiple places. The obvious answer was to move all of the tool definitions into a YAML file. The MCP module now loads its tool definitions at startup: Perl sub _build__tools ($self) { return LoadFile($self->tools_file); } 1 | sub _build__tools ($self) { return LoadFile($self->tools_file); } ---|--- The result is a single source of truth. The same YAML file drives: * The `tools/list` response * Tool metadata * JSON schemas * Human-readable documentation Adding a new tool now involves updating one file and writing the code that implements it. Everything else follows automatically. Here’s the current YAML file: JavaScript # data/mcp-tools.yml - name: sovereign_on_date description: Return the British sovereign on a given date. documentation: | Looks up the reigning British sovereign for the supplied date. Use this when answering questions such as “Who was sovereign on 6 February 1952?” inputSchema: type: object properties: date: type: string description: Date in YYYY-MM-DD format. required: - date - name: line_of_succession description: Return the line of succession on a given date. documentation: | Returns people in the line of succession. If no date is supplied, the current line of succession is returned. inputSchema: type: object properties: date: type: string description: Optional date in YYYY-MM-DD format. Omit for the current line of succession. limit: type: integer description: Maximum number of successors to return. minimum: 1 maximum: 100 required: [] 123456789101112131415161718192021222324252627282930313233343536 | # data/mcp-tools.yml - name: sovereign_on_date description: Return the British sovereign on a given date. documentation: | Looks up the reigning British sovereign for the supplied date. Use this when answering questions such as “Who was sovereign on 6 February 1952?” inputSchema: type: object properties: date: type: string description: Date in YYYY-MM-DD format. required: - date - name: line_of_succession description: Return the line of succession on a given date. documentation: | Returns people in the line of succession. If no date is supplied, the current line of succession is returned. inputSchema: type: object properties: date: type: string description: Optional date in YYYY-MM-DD format. Omit for the current line of succession. limit: type: integer description: Maximum number of successors to return. minimum: 1 maximum: 100 required: [] ---|--- Looking back, this is probably the part of the design I’m happiest with. It feels very Perl-ish: keep configuration as data and avoid duplicating information wherever possible. ## Human Documentation Matters One thing I noticed while exploring other MCP servers is that many of them are effectively invisible to humans. You know an endpoint exists. You know it speaks MCP. But unless you inspect the protocol responses manually, you don’t really know what it does. I decided to add a conventional web page at `/mcp`. The page lists all available tools, their descriptions and their schemas. The nice part is that there is no duplicated documentation. The page is generated from the same YAML definitions used by the MCP server itself. If I add a new tool tomorrow, both the machine-readable and human-readable views update automatically. ## Structured Data and Text Responses Another nice feature of MCP is that tool results can include both structured data and human-readable text. For example, a tool response might contain: JavaScript { "content": [ { "type": "text", "text": "The sovereign on 14 November 1948 was George VI." } ], "structuredContent": { ... } } 123456789 | { "content": [ { "type": "text", "text": "The sovereign on 14 November 1948 was George VI." } ], "structuredContent": { ... }} ---|--- The structured content is useful for software. The text is useful for humans and language models. Both are generated from the same underlying data. That gives AI clients flexibility while ensuring consistency. ## Getting Listed Once everything was working, I submitted the server to the MCP directory at mcpservers.org. That might seem like a small step, but discoverability is important. An MCP server hidden on a random website isn’t much use if nobody knows it exists. Directories like that are rapidly becoming the equivalent of API catalogues for the AI era. Being listed means developers and AI enthusiasts can find the service without first discovering the website. ## Was It Worth It? Absolutely. The amount of code required was surprisingly small. Most of the work wasn’t implementing the protocol; it was deciding how best to expose the data. More importantly, it opens the site up to an entirely new audience: AI agents. Historically, websites were built for humans and APIs were built for developers. MCP introduces a third category: services designed specifically for AI systems. For a structured-data site like Line of Succession, that’s a natural fit. Will MCP still be the dominant standard in five years’ time? I have no idea. The AI industry changes too quickly to make confident predictions. But right now it has significant momentum, broad industry support and a growing ecosystem of tools. And if nothing else, it’s rather satisfying to ask an AI who was on the throne on a particular date and know that the answer came directly from my database rather than from whatever the model happened to remember. ### Share this: * Tweet * * Share on Reddit (Opens in new window) Reddit * More * * Email a link to a friend (Opens in new window) Email * Print (Opens in new window) Print * * Share on Tumblr * * ### _Related_
perlhacks.com
May 30, 2026 at 1:34 PM
Security updates have been issued by Debian (network-manager-l2tp and urwid), Fedora (perl-Dancer2, perl-Data-Entropy, perl-DBI, perl-Protocol-HTTP2, podman-tui, rust-lru, and rust-lru0.1...

🔗 https://lwn.net/Articles/1094469
September 15, 2026 at 3:45 PM
"dancer2"

Line 9246 out of 14344391 lines
(0.06446% out of 100% done)
September 11, 2026 at 7:57 AM
CVE-2026-15689 - dancer2::plugin::auth::extensible
Dancer2::Plugin::Auth::Extensible versions for Perl, through 0.713, contain a security risk where attackers can manipulate password reset links by exploiting the…

Too many irrelevant or confusing CVEs? Use stackflag.com

#abeverley #CVE #infosec
CVE-2026-15689: Dancer2::Plugin::Auth::Extensible password reset link manipulation via Host header
Dancer2::Plugin::Auth::Extensible versions for Perl, through 0.713, contain a security risk where attackers can manipulate password reset links by.
stackflag.com
August 17, 2026 at 10:00 PM
CVE-2026-15689: Dancer2::Plugin::Auth::Extensible versions through 0.713 for Perl allow password reset link poisoning via the request Host header in _default_email_password_reset and _default_welcome_send
oss-sec: CVE-2026-15689: Dancer2::Plugin::Auth::Extensible versions through 0.713 for Perl allow password reset link poisoning via the request Host header in _default_email_password_reset and _default_welcome_send
Posted by Timothy Legge on Aug 15 ======================================================================== CVE-2026-15689 CPAN Security Group ======================================================================== CVE ID: CVE-2026-15689 Distribution: Dancer2-Plugin-Auth-Extensible Versions: through 0.713 MetaCPAN: https://metacpan.org/dist/Dancer2-Plugin-Auth-Extensible VCS Repo:...
seclists.org
August 15, 2026 at 5:07 PM
Dancer2 ≤2.1.0 (CROMEDOME) HIGH severity flaw: Predictable session IDs if secure random modules missing. Install Math::Random::ISAAC::XS or Crypt::URandom to mitigate. https://radar.offseq.com/threat/cve-2026-13577-cwe-340-generation-of-predictable-numbers-or-identifiers-in-cromedome-dancer2-858d...
CVE-2026-13577: CWE-340 Generation of Predictable Numbers or Identifiers in CROM
Dancer2 versions <=2.1.0 generate session IDs using secure CSPRNG modules Math::Random::ISAAC::XS or Crypt::URandom when available. However, if these modules are missing, the generate_id function silently falls back to a weak method that de
radar.offseq.com
July 20, 2026 at 12:00 PM
🚨 EUVD-2026-45896
📊 n/a
🏢 CROMEDOME

📝 Dancer2 versions through 2.1.0 for Perl generate insecure session ids when CSPRNG modules are unavailable.

Dancer2::Core::Role::SessionFactory::generate_i...

🔗 https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-45896

#cybersecurity #infosec #cve #euvd
July 20, 2026 at 10:00 AM
CVE-2026-12746 - Dancer2::Plugin::Auth::OAuth::Provider versions before 0.23 for Perl do not support the OAuth 2.0 state parameter
CVE ID : CVE-2026-12746

Published : 4 juillet 2026 17:52 | 4 heures, 23 minutes ago

Description : Dancer2::Plugin::Auth::OAuth::Provider ver...
CVE-2026-12746 - Dancer2::Plugin::Auth::OAuth::Provider versions before 0.23 for Perl do not support the OAuth 2.0 state parameter
Dancer2::Plugin::Auth::OAuth::Provider versions before 0.23 for Perl do not support the OAuth 2.0 state parameter. The authentication_url method builds the provider authorization redirect without issuing a state value, and the callback method exchanges the callback code and registers the resulting token into the session without verifying that the callback corresponds to …
cvefeed.io
July 5, 2026 at 12:00 AM
🚨 EUVD-2026-41686
📊 n/a
🏢 BIAFRA

📝 Dancer2::Plugin::Auth::OAuth::Provider versions before 0.23 for Perl do not support the OAuth 2.0 state parameter.

The authentication_url method builds the p...

🔗 https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-41686

#cybersecurity #infosec #cve #euvd
July 4, 2026 at 7:00 PM