Client-to-Client Protocol (CTCP)
This document intends to be a useful overview and reference of CTCP as it is implemented today. It is a living specification which is updated in response to feedback and implementations as they change. This document describes existing behaviour and what we consider best practices for new software.
If something written in here isn't interoperable with an IRC client you know of, please open an issue.
NOTE: This document is being persued as an Internet-Draft for standardisation with the IETF.
This page is out of date, and you should look here for the document that replaces this:
[Internet-Draft] - [Editor's HTML Draft] - [Editor's TXT Draft] - [Github]
Introduction
The Client-to-Client Protocol (CTCP) has been in use on IRC for a very long time. Essentially, it provides a way for IRC clients to send each other messages that get parsed and displayed/responded to in special ways. Some examples of how CTCP is used today is to request special formatting on certain messages, query other clients for metadata, and initiate file transfers with other clients.
The original CTCP specifications are lengthy and cover quoting mechanisms which are no longer implemented or followed today. In comparison, this document goes over the subset of CTCP which is commonly implemented and lets your software interact nicely with most other IRC software out there.
The IRCv3 Working Group is investigating replacing some functions currently performed by CTCP with alternate methods such as Metadata and client-only message tags, which should also allow these functions to be performed more widely and used to better effect.
Table of Contents
Message Syntax
The PRIVMSG
and NOTICE
messages are used to transmit CTCP frames. To create a CTCP message, you simply replace the body (i.e. the <text to be sent>
) of a PRIVMSG
/ NOTICE
with the following:
delim = %x01
command = 1*( %x02-09 / %x0B-0C / %x0E-1F / %x21-FF )
; any octet except NUL, delim, CR, LF, and " "
params = 1*( %x02-09 / %x0B-0C / %x0E-FF )
; any octet except NUL, delim, CR, and LF
body = delim command [ SPACE params ] [ delim ]
The final <delim>
MUST be sent, but parsers SHOULD accept incoming messages which lack it (particularly for CTCP ACTION
). This is due to how some software incorrectly implements message splitting.
CTCP queries are sent with PRIVMSG
, and replies are sent with NOTICE
. In addition, CTCP queries sent to channels always generate private replies.
Here are two examples of CTCP queries and replies:
:dx PRIVMSG SaberUK :\x01VERSION\x01
:SaberUK NOTICE dx :\x01VERSION Snak for Macintosh 4.13 English\x01
:mt PRIVMSG #ircv3 :\x01PING 1473523796 918320\x01
:Jobe NOTICE mt :\x01PING 1473523796 918320\x01
Changes since 1994 specification
The entire PRIVMSG
/ NOTICE
message body must consist of either a CTCP message or plain text (non-CTCP). The original specification(s) allowed intermixing plain-text chunks and “tagged data” CTCP chunks, which has not been implemented widely enough for regular use.
This document does not include any mechanism for quoting plain text (non-CTCP) messages, as opposed to the original “low-level quoting” specifications (as this has not been widely implemented). Likewise, it does not define any mechanism for quoting CTCP parameters, although individual CTCP message specifications may define their own quoting.
Message Types
CTCP messages generally take on one of these types. These message types are defined here for informational purposes only (to simplify understanding), and aren’t specified or differentiated by the protocol itself.
Generally, channel-directed CTCPs should never cause an error reply.
Extended Formatting
This type of CTCP is used to request special formatting of a user-visible message. That is, to send a user-visible message that should be displayed differently from regular messages - e.g. as an action, a whisper, an announcement.
Extended formatting CTCPs are sent as a PRIVMSG
. There is no automatic response to this message type, as it is not a query nor reply.
Extended formatting CTCPs are expected to be used in channels as well as between clients. However, many servers implement optional filtering to block CTCPs in channels (apart from ACTION
). Because of this, any future extended-formatting CTCPs may be restricted to private messages.
These CTCP messages are sent as a PRIVMSG
and generate no reply.
Example:
:dan- PRIVMSG #ircv3 :\x01ACTION writes the best specifications!\x01
Metadata Query
This type of CTCP is used to provide static information about the target client, user or connection.
This CTCP takes the form of a query and a response (as a PRIVMSG
and NOTICE
, respectively). Due to how bouncers interact with multiple clients, there may sometimes be multiple responses to queries.
Metadata queries MUST NOT require the recipient to implement any side effects (beyond sending the reply itself); if a CTCP message causes side effects by design, it should be categorized as an extended query instead.
Example:
:dx PRIVMSG SaberUK :\x01VERSION\x01
:SaberUK NOTICE dx :\x01VERSION Your Mother 6.9\x01
Extended Query
This type of CTCP is used to provide dynamic information or invoke actions from the client.
This CTCP takes the form of a query and a response (as a PRIVMSG
and NOTICE
, respectively).
Queries sent to a channel always generate private replies.
Example:
:mt PRIVMSG #ircv3 :\x01PING 1473523796 918320\x01
:Jobe NOTICE mt :\x01PING 1473523796 918320\x01
CTCP Message Registry
Extended formatting messages can have parameters, but usually do not generate an automatic reply.
Metadata queries do not have any parameters, but expect a reply with parameters as the response data.
Extended queries and replies may have parameters.
We only cover messages that are widely-used by IRC software today. For more extensive lists, see the external irc-defs
ctcp messages list.
ACTION
Type: Extended Formatting
Params: ACTION <text>
This extended formatting message shows that <text>
should be displayed as a third-person action or emote; in clients, it’s generally activated with the command /me
.
ACTION
is universally implemented and very commonly used. Clients MUST implement this CTCP message.
Example:
Raw: :dan!user@host PRIVMSG #ircv3 :\x01ACTION writes a specification\x01
Formatted: * dan writes a specification
CLIENTINFO
Type: Metadata Query
Reply: CLIENTINFO <token>{ <token>}
This metadata query returns a list of the CTCP messages that this client supports and implements.
CLIENTINFO
is widely implemented. Clients SHOULD implement this CTCP message.
Example:
Query: CLIENTINFO
Response: CLIENTINFO ACTION DCC CLIENTINFO FINGER PING SOURCE TIME USERINFO VERSION
DCC
Type: Extended Query
Params: DCC <type> <argument> <address> <port>
DCC (Direct Client-to-Client) is used to setup and control connections that go directly between clients, bypassing the IRC server. This is typically used for features that require a large amount of traffic between clients or simply wish to bypass the server itself such as file transfer, direct chat, and voice messages.
Properly implementing the various DCC types requires a document all of its own, and are not described here.
DCC
is widely implemented. Clients MAY implement this CTCP message.
FINGER
Type: Metadata Query
Reply: FINGER <info>
This metadata query returns miscellaneous info about the user, typically the same information that’s held in their realname
field.
However, some implementations return the client name and version instead.
FINGER
is widely implemented, but largely obsolete. Clients MAY implement this CTCP message.
Example:
Query: FINGER
Response: FINGER WeeChat 1.5
PING
Type: Extended Query
Params: PING <info>
This extended query is used to confirm reachability with other clients and to check latency. When receiving a CTCP PING, the reply must contain exactly the same parameters as the original query.
PING
is universally implemented. Clients MUST implement this CTCP message.
Example:
Query: PING 1473523721 662865
Response: PING 1473523721 662865
Query: PING foo bar baz
Response: PING foo bar baz
SOURCE
Type: Metadata Query
Reply: SOURCE <info>
This metadata query is used to return the location of the source code for the client.
SOURCE
is rarely implemented. Clients MAY implement this CTCP message.
Example:
Query: SOURCE
Response: SOURCE https://weechat.org/download
TIME
Type: Extended Query
Params: TIME <timestring>
This extended query is used to return the client’s local time in an unspecified human-readable format. We recommend ISO 8601 format, but raw ctime()
output appears to be the most common in practice.
New implementations SHOULD default to UTC time for privacy reasons.
TIME
is almost universally implemented. Clients SHOULD implement this CTCP message.
Example:
Query: TIME
Response: TIME 2016-09-26T00:45:36Z
VERSION
Type: Metadata Query
Reply: VERSION <verstring>
This metadata query is used to return the name and version of the client software in use. There is no specified format for the version string.
VERSION
is universally implemented. Clients MUST implement this CTCP message.
Example:
Query: VERSION
Response: VERSION WeeChat 1.5-rc2 (git: v1.5-rc2-1-gc1441b1) (Apr 25 2016)
USERINFO
Type: Metadata Query
Reply: USERINFO <info>
This metadata query returns miscellaneous info about the user, typically the same information that’s held in their realname
field.
However, some implementations return <nickname> (<realname>)
instead.
USERINFO
is widely implemented, but largely obsolete. Clients MAY implement this CTCP message.
Example:
Query: USERINFO
Response: USERINFO fred (Fred Foobar)