Gemini Protocol & Markup

The Gemini project defines a protocol and markup for serving documents. The server runs on port 1965 by default, it responds to gemini:// URLs, it uses TLS with client certificates, and it has a simple markdown that fixes the shortcomings of Gopher pages without adding much extra. There are GUI, terminal, and command line clients already available.

The protocol has been designed with just enough features to allow publishing of simple documents, small files, and it also allows for rudimentary input handling. The bare simplicity of Gemini is a deliberate design choice. Client and server software is easy to write, as are Gemini documents. There are no features that could meaningfully aid tracking and advertising, so it’s unlikely to ever gain commercial interest. This is itself a key feature.

My own Gemini server is at gemini:// In order to read any content there, it’s first necessary to install Gemini client (just as you need a Web browser to read content on the World Wide Web). There are a number of web-based proxies that have been made available by members of the community, and while these can be used to access Gemini ‘capsules’ (the Gemini equivalent of a web-site), I’d recommend using a proper client instead.

Gemini is overwhelmingly text-based. Not even inline images are supported, and although some clients do offer inline image loading, you generally have to choose to download an image, e.g. by clicking a link just like any other link. Again, this is a matter of principle in the protocol design; that is, it’s you who’s in charge of what you view, not the page author or site owner, nor any advertiser.

So, if you want to publish stuff somewhere that’s separate from the world wide web, then this seems like a good alternative. The markdown is simple, yet gives headings, paragraphs, pre-formatted blocks, lists, and links. You can simply type some words in a text file, and that’s your document ready to serve to the world. The immediacy and accessibility is refreshing (more so as I type this in WordPress, which is lagging in a browser on a fast 8-core Intel i7 laptop with 16GB of RAM).

There are barriers to entry – the most direct access for editing is via a shell, using a command line editor (I use Vim). I think this is well within the abilities of most people, but it will likely be daunting. The tilde communities seem to do a good job of making these things accessible, perhaps some of this could be applied to the fledgling Gemini community.

Below is a summary, but the full specification is at (it’s brief; it can be read in the time it takes to drink a coffee!)

# This would be an H1
## This would be an H2
### This would be an H3

=> Click me, I always exist on my own line.

> This line will show as a block-quote

* This is the first list item.
* This is another list item.

Pre-formatted blocks start and end with lines containing three back-ticks (```)

Anything else is just normal paragraph text, blank lines are always preserved.

The simplest Gemini client is Bash

Using ncat, it’s possible to make a request to a Gemini server with the following: –

echo -ne 'gemini://\r\n'|ncat --ssl 1965

This results in the following on stdout. The first line is the server’s response code, the rest is my index.gmi content: –

20 text/gemini
Hello from Gemini dot Susa dot Net

=> lua_api.txt The Official Minetest Lua API for modding.
=> lua_api.gmi The Official Minetest Lua API in Gemini markup.
=> xtract_lua_api.awk My awk script to extract sections of the API.

=> petz_functions.gmi a list of member functions in the Petz mod.
=> minetest_pointed_thing.gmi my explanation of above and under nodes.

=> hexchat_no_such_device_or_address.gmi Fix HexChat Disconnected (No such device or address)

My web site is at: -


I can be reached via SMTP at

So simple, this is a great initiative; decisions seem to have been well considered. I’m grateful! For more, see

A more featureful client: GemiNaut

A gemini (.gmi) page viewed in the GemiNaut browser.

For a server, I use agate gemserv:

I have tried agate, which serves static files (and is still being actively developed). I then spent ages getting GLV-1.12556 running, which has lots of well considered features, but it required a lot of fiddling and hacking to get it to compile and run, so it might be too much of an admin hassle.

I have currently switched to gemserv, which seems to have similarly useful features (virtual hosts, CGI, home directories), but runs as a single binary like agate, and the Rust project builds easily with cargo. There are a couple of links to CGI examples at gemini:// if you want to see the server in action.

My server needs a private key and certificate (just issued locally using openssl).

# This command created a key and certificate that's valid for any host on
openssl req -x509 -newkey rsa:4096 -keyout key.rsa -out cert.pem -days 3650 -nodes -subj "/CN=*"

# This command lets you view your server's certificate as human-readable text for troubleshooting.
openssl x509 -in cert.pem -text

The following is some server output, including the command line that launched the server (in this case agate).

kevin@kakapo:~/gemini$ ./agate.x86_64-unknown-linux-gnu ./content/ cert.pem key.rsa
Got request for "gemini://"
Got request for "gemini://"
Got request for "gemini://"
Got request for "gemini://"
Got request for "gemini://"
Error: Os { code: 2, kind: NotFound, message: "No such file or directory" }
Got request for "gemini://"
Got request for "gemini://"
Error: Os { code: 2, kind: NotFound, message: "No such file or directory" }
Got request for "gemini://"

My index.gmi file to show a little markdown.

Hello from Gemini

=> petz_functions.gmi a list of member functions in the Petz mod.

You may check out my website at: -

-- Lua code to log my name minetest.log("Kevin")
Kevin said:
> This is quite a useable format to document Minetest mods. I think I'll use this in future.

### I'm signing off now
Good day to you sir. I bid you farewell.

If you have a Gemini client, you can view this at gemini://

6 Replies to “Gemini Protocol & Markup”

  1. Amfora says:

    Failed to connect to the server: hostname does not verify: x509: certificate is not valid for any names, but wanted to match

    GemiNaut agrees!

    1. Yes, you’re right. Thanks! My link text was ‘’, but the actual URL I was linking to was ‘’. Fixed.

      Have you got your server running and said hello on IRC yet? port 6697

  2. I don’t get it. If you don’t like the bloat of the modern web, just hand jam your own minimal html and css. That’s basically what you’re doing with Gemini, but no one is around to see it.

    1. I don’t really write for other people, I just write stuff and share for anyone who happens to find it.

      Gemini uses plain-text for everything, I can write using whatever I want, and there’s no tag bloat, so I can read easily from anywhere. That’s about it.

      One incidental benefit of using a different protocol is that it inherently separates content from the ocean of crap that the web has become. How else can you differentiate in advance between commercial click-bait and genuine content? I’ve tried to figure this out, and can’t think of any workable solution.

  3. I would like to add that agate does have multi-host support. I have a number of capsules running on the same machine using agate.

Leave a Reply

Your email address will not be published. Required fields are marked *