Pipe Manual

Profile manual

Importing profiles

On this page
  1. Adding a profile
  2. Add links
  3. What does not come across
  4. Kept current
  5. Surge
  6. Clash and mihomo
  7. sing-box
  8. Categories

A profile from another app becomes a Pipe profile when you add it: Pipe converts it. Surge profiles, Clash and mihomo configurations, and sing-box configurations all go through the converter, each as far as Pipe's format can say what it says — proxies, groups, rules and rule sets, DNS and hosts. What you then have is a Pipe profile: the format this manual describes, and the one to write a profile of your own in. A Surge profile converts best, line for line, because Pipe's format began from Surge's; it is still converted, not taken as it is (Surge).

What does not come across is never dropped in silence. It stays in the profile as a comment, and the app lists it before the profile is added — each item saying whether it changes where traffic goes, only how Pipe is set up, or nothing but appearance. A conversion with nothing listed that changes routing is added at once; one with a routing change is shown for review, and so is a profile fetched again whose conversion changes routing in a way the review did not show.

Once converted, the profile says nothing more of the app it came from: what checking it reports (diagnostics) is about the Pipe profile, as of one you wrote.

Adding a profile#

In the app: Profile, the profile's name at the top, then +:

  • Paste or Download… takes the text of a profile, or a link to one.
  • Open a File takes a file.

Pipe tells the format by the content. When something does not come across, the app shows what was converted — how many proxies, groups and rules — and the list of what was left out or changed, each with why, before the profile is added. A profile with nothing to list is added at once.

A link is fetched as Surge asks for a profile (its User-Agent): providers choose the format they send by it, and a Surge profile is the one that converts most completely. A provider that sends a Clash or sing-box configuration instead is converted all the same, and so is a profile a provider wraps in base64, as it wraps a list of links.

Share links, a subscription of share links (base64), and a WireGuard file are lists of proxies, not profiles: they have no groups or rules to convert. Import those under Profile › All Proxies, into the pool, where every profile can take them in.

A link can offer a module, a profile or a subscription to anyone with Pipe, from a web page, a message or another app:

https://getpipe.today/add?module=<url>
https://getpipe.today/add?profile=<url>
https://getpipe.today/add?subscription=<url>

pipe://add?module=<url>, and the same for the other two, says the same thing where a web link would not open the app. Without Pipe, the web link opens a page that says what the link asks for.

Opening a link adds nothing. It opens the sheet you would have typed the address into, with the address filled in and its host named. Pipe fetches nothing until you tap Review, and keeps nothing until you accept the review, as with an address you pasted yourself.

A link holds one address, percent-encoded, and nothing else:

  • The address begins with https://, has a host and has no user or password in it.
  • It is plain printable text, at most 2,048 bytes, with no spaces.
  • Anything else in the link, such as a second address, refuses it. An address left unencoded usually does this: its own & starts another part of the link.

Pipe says it can't use a link it refuses, and does nothing else. A link shows its address to whoever can read the link, and the page for people without Pipe asks getpipe.today for it: keep a subscription's private address out of a link you post where others can see it.

What does not come across#

Each part that Pipe's format has no way to say becomes a comment where it would have been, and a line in the list the app shows:

[Proxy]
Server 1 = trojan, server1.example.com, 443, password=pw
# not converted: proxy 'JP 02' — tls: REALITY public_key must be 43 unpadded URL-safe base64 bytes

[Rule]
# not converted: IP-SUFFIX,1.1.1.1/24,DIRECT — Pipe has no IP-SUFFIX rule
GEOIP,JP,DIRECT

What a conversion writes is checked by Pipe's own compiler before it is given to the app: a profile that does not compile is an error, not a profile. Conversion can change routing where the formats differ; review the reported changes before using it. Unavailable policies are handled as follows:

  • A rule whose policy could not be converted — a proxy Pipe cannot run, a group it has no counterpart for — rejects what it matches, with a comment that says why. So does a rule naming a policy the original does not define.
  • A group none of whose members could be converted rejects everything: its only member is REJECT.
  • A group keeps the members that could be converted, and the list says which it left out. A reference to anything that could not be written — a group, a provider's group, a proxy — is resolved against what was: what dropped it re-renders without it and says so, so nothing dangles.

A rule whose matcher has no counterpart in Pipe is left out, as Pipe leaves out a rule it cannot evaluate: what it would have matched goes on to the rules after it, and the note says so — a routing change, shown for review. A proxy Pipe cannot run yet (Not supported yet) is left out with the reason.

A proxy whose TLS handshake is to look like a browser's — Clash's client-fingerprint, sing-box's utls, a link's fp — gets Chrome's, the one browser handshake Pipe has (client-fingerprint): firefox, safari, ios, edge, random and the rest ask for the same thing, a handshake that passes for a browser's, and Chrome's does. One note, as a setting, names the proxies it changed. none asks for no browser's, and gets none.

Names stay as they were. Two of one name become Server and Server 2. A proxy or group named like a built-in policy (DIRECT, REJECT-DROP, …) can never be reached — everything naming the name reaches the policy, as in mihomo and Surge — so it is skipped with a note, and the rules and members that named it use the policy. A name a profile line cannot say — one that would read as a comment or a section's header — is written quoted, and what cannot be quoted is skipped with the reason.

Kept current#

A profile added from a link is kept current from it when its format says so — and a Clash or sing-box one always, as those apps keep every profile from a link current. The converted profile then begins with a #!MANAGED-CONFIG line naming the link:

#!MANAGED-CONFIG https://provider.example/subscribe?token=… interval=43200 strict=false

The interval is the one the server gives (profile-update-interval, in hours, as Clash subscriptions send it), else a day. A Surge profile is kept current by its own #!MANAGED-CONFIG line, as it says; one without the line is a copy.

Each time the profile is fetched again, what comes back is converted again, the same way. As with every managed profile, what you change in it is replaced at its next update: change it with a module.

Surge#

Nearly every line of a Surge profile is a line of Pipe's format already, and means the same: it is kept as written, with its comments, order and line requirements. What is Surge's alone does not come across:

Surge Pipe
A [General] key Pipe's format has no setting for (hijack-dns, compatibility-mode, tls-provider, …), or one Pipe does not do yet (auto-suspend) Left out, as a setting, with why.
A setting of one platform's — a Mac's skip-proxy, a computer's http-listen, an iPhone's allow-wifi-access Kept: one profile serves a phone and a computer alike, and each reads its own.
http-api or external-controller-access, in a profile kept current from a link Left out: its key is the provider's, who would hold the key to Pipe. In a profile of your own it stays.
[Replica], [Ponte], [Testing], a section Pipe's format does not have Left out, the section's lines with it.
A Tailscale proxy A tailnet policy of the same name; its [Tailscale <name>] section goes, and the tailnet is offered for sign-in with the section's auth key and control server, which never go into the profile.

Each line left out becomes a # not converted: comment where it was, naming it and why — never its value, which may hold a password:

[General]
loglevel = notify
# not converted: hijack-dns — every DNS query sent to port 53 through Pipe's tunnel is answered by Pipe already
skip-proxy = 127.0.0.1, 192.168.0.0/16

Older spellings#

Pipe's format reads one spelling of each thing. Where Surge has another, older one, the conversion writes Pipe's in its place, on the same line, with its comment and line requirement:

Surge writes Pipe's profile has
doh-server, doh-follow-outbound-mode, doh-skip-cert-verification encrypted-dns-server, encrypted-dns-follow-outbound-mode, encrypted-dns-skip-cert-verification
use-default-policy-if-wifi-not-primary = false subnet-exp-wifi-always-match = true, and the other way round; where the profile has subnet-exp-wifi-always-match already, which Surge goes by, the older line goes
ipv6-vif = off ipv6-vif = disabled
server:syslib in [Host] server:system
VMess's encrypt-method=chacha20-ietf-poly1305 encrypt-method=chacha20-poly1305
The rule types DST-PORT, SRC-IP-CIDR, IP6-CIDR, NETWORK, MATCH, in logical rules too DEST-PORT, SRC-IP, IP-CIDR6, PROTOCOL, FINAL; a rule list at a URL reads either name
A Mac's interface and port http-listen = address:port: the address 127.0.0.1 where only the port is given, the port 6152 where only the address is
A Mac's socks-interface and socks-port socks5-listen = address:port, the same way, the port 6153
Name = custom, server, port, cipher, password, module Name = ss, server, port, encrypt-method=cipher, password=password; the module, which Surge ran to speak Shadowsocks, is left out, with a note
A group of type ssid subnet
A subnet group's cellular = Policy TYPE:CELLULAR = Policy, before its other conditions, as Surge tried it
A subnet group's condition without a prefix With the prefix of what it is: SSID:Office* for a pattern, ROUTER:192.168.1.1 for an address, BSSID:aa:bb:cc:dd:ee:ff for an access point's, SSID:Home for any other
A SUBNET rule's value without a prefix, in a logical rule too, and an [SSID Setting] line's With its prefix the same way, cellular becoming TYPE:CELLULAR; the rest of the line as it was. A rule list at a URL is not converted: its lines without a prefix are passed over.
external-policy-modifier = "underlying-proxy=Relay" The group's underlying-proxy=Relay where all its proxies come from its policy-path. Where the group lists proxies too, the modifier stays, and sets each proxy the list brings to go through Relay, as any modifier sets a key. Where the group has an underlying-proxy of its own, which Surge went by, the modifier's is left out, with a note.
[Script]: cron "0 8 * * *" script-path=a.js, … (type value parameters) a.js = type=cron, cronexp=0 8 * * *, script-path=a.js, …, named as Surge names it: a rule, dns or generic script by its value, any other by its file, and by its file and line where another script has that name
[Header Rewrite]: a line without http-request or http-response The same line with http-request in front: Surge rewrote requests with it

A Surge module, when it is added, has its older spellings written the same way (Modules).

What stays and Pipe does not do yet — a proxy it cannot run, a rule option it reads past — is the compiler's to report, as of any profile (diagnostics). A module (#!name=…) is not a profile but a plugin: it is added to a profile the app already has (Modules), not converted as one.

Clash and mihomo#

Proxies#

proxies (and the old Proxy) become [Proxy] lines, field by field, with mihomo's leniency: keys in any case, _ read as -. A proxy's dialer-proxy becomes underlying-proxy. As in mihomo, a Shadowsocks, VMess, VLESS, Trojan, AnyTLS, SOCKS5, Snell or MASQUE proxy carries UDP only with udp: true; without it, its line says udp-relay=false. mihomo's masque is Cloudflare WARP's: it becomes a masque line with mode=cloudflare, its private-key, public-key, ip, ipv6, mtu, uri and sni kept, and its dns with remote-dns-resolve: true; with network: h3-l4proxy, WARP's TCP proxy, a plain line that carries TCP alone. network: h2 is left out. An ssh proxy's key, written in the config (private-key: | and the key's text), becomes a [Keystore] item the line names, and private-key-passphrase comes across as it is; a key named by its file's path is left out, with a note: the file is on the machine the config was written for, which Pipe cannot read.

Groups#

Clash Pipe
select select
url-test url-test
fallback fallback
load-balance load-balance
smart smart
relay A chain of proxies: each hop after the first is a copy of that proxy going through the one before it, and the last takes the relay's name. A hop that is not a proxy of the configuration, or that goes through a proxy of its own already, cannot be chained.
Option Pipe
proxies The members, in order.
use The members of the providers named (below), with include-other-group.
include-all The config's own proxies, listed by name, and every provider — mihomo's own scope for them, which a listed name keeps.
include-all-proxies The config's own proxies, listed by name.
include-all-providers Every provider.
filter policy-regex-filter for providers, and filtering of automatically included local proxies. Explicitly listed members are preserved. mihomo splits a filter on ` and keeps a proxy matching any part, so the parts become alternatives of one pattern. A pattern with look-around is left out: Pipe's patterns have none, so the group takes every proxy it is given.
interval interval.
tolerance tolerance.
timeout timeout, in seconds.
strategy round-robin runs round-robin across healthy members. Hashing strategies become persistent=true, with a note: Pipe uses full-host rendezvous hashing and does not preserve mihomo's registrable-domain or source-address sticky-session behavior.
url The automatic group's own test URL. The most common URL also supplies the profile default.
default-selected default on a selector, without changing member order; an available saved selection wins.
expected-status The automatic group's accepted HTTP status codes/ranges. Tests and cached results stay separate for different accepted statuses.
exclude-filter, exclude-type policy-regex-exclude-filter, policy-type-exclude-filter, applied to all member sources and retained on provider refresh.
hidden hidden=true.
icon icon-url.
lazy, max-failed-times, disable-udp, interface-name, routing-mark, empty-fallback Left out, with a note: Pipe tests a group when it is used, and refuses an empty group.

Proxy providers#

Each provider a group uses becomes a hidden select group of its own, named like the provider, at the end of [Proxy Group]. The groups that use it take its members in with include-other-group.

Provider Pipe
type: http policy-path with its URL — a policy-path list may be in Clash's format — and update-interval for its interval (a day unless it says).
type: inline Its proxies, in [Proxy], listed by its group.
type: file Left out: the file was on the device Clash ran on.
Option Pipe
filter external-policy-regex-filter for remote providers, before any name prefix; applied directly to inline members.
override.additional-prefix external-policy-name-prefix for a remote provider.
override.skip-cert-verify For remote providers, external-policy-modifier preserves explicit skip-cert-verify=true or false.
override.dialer-proxy For remote providers, external-policy-dialer-proxy, including DIRECT. The overridden definitions reach every group using that provider; shared URLs with different overrides remain distinct.
health-check.url Counts toward the profile's proxy-test-url.
exclude-filter, exclude-type External name exclusion before prefixes, and native type exclusion; retained when the list refreshes.
header, other override keys, inline provider overrides Left out, with a note.

Rules#

Clash Pipe
DOMAIN, DOMAIN-SUFFIX, DOMAIN-KEYWORD, DOMAIN-WILDCARD, DOMAIN-REGEX The same.
GEOSITE, GEOIP See Categories.
IP-CIDR, IP-CIDR6 The same, no-resolve kept. With src: SRC-IP.
SRC-IP-CIDR SRC-IP.
IP-ASN IP-ASN, with an ASN database.
DST-PORT, SRC-PORT, IN-PORT DEST-PORT, SRC-PORT, IN-PORT. A list of ports (80/443) becomes an OR of one each.
NETWORK PROTOCOL,TCP or PROTOCOL,UDP.
PROCESS-NAME The same.
PROCESS-PATH PROCESS-NAME with the path, which it matches written out.
PROCESS-PATH-REGEX The same.
RULE-SET The rule provider's list (below).
AND, OR, NOT The same, each sub-rule converted. One that cannot be leaves the whole rule out, as does nesting more than ten deep.
MATCH FINAL, with dns-failed: a name that cannot be looked up goes on to it, as in Clash. Without a MATCH, FINAL,DIRECT,dns-failed — what Clash does with what no rule matches. Rules after MATCH are left out.
SUB-RULE, SCRIPT, PROCESS-NAME-REGEX, PROCESS-NAME-WILDCARD, PROCESS-PATH-WILDCARD, IP-SUFFIX, SRC-GEOIP, SRC-IP-ASN, SRC-IP-SUFFIX, IN-TYPE, IN-USER, IN-NAME, UID, DSCP, REMATCH-NAME Left out.

DIRECT, REJECT and REJECT-DROP are Pipe's built-in policies of those names, and COMPATIBLE is DIRECT. GLOBAL is the config's own group of that name when it has one; otherwise it is mihomo's own group of every proxy, which Pipe does not have, and is DIRECT — what that group has picked until someone picks another. A rule whose policy is PASS does nothing in Clash, and is left out.

Rule providers#

Provider Pipe
type: http RULE-SET with its URL, in the format its behavior says — format=clash-domain, clash-ipcidr or clash-classical (List formats) — and update-interval for its interval.
format: mrs The original URL, read as a mihomo binary list. A country's addresses (geoip/jp.mrs) become GEOIP,JP, and the local network's RULE-SET,LAN.
type: inline A [Ruleset <name>] section of its payload. A payload that names the provider itself, directly or through others, or names providers more than eight deep, has those lines left out, with a note; a provider none of whose payload can be converted is no set, and a rule naming it is left out.
type: file Left out.

DNS and hosts#

Clash Pipe
no dns, or enable: false dns-server = system.
default-nameserver dns-bootstrap-server: resolves server names without racing ordinary destination queries.
nameserver Plain servers go to dns-server, encrypted ones (tls://, https://, quic://; https://…#h3=true as h3://) to encrypted-dns-server. system and dhcp:// are system.
nameserver-policy [Host] entries sending names to those servers, in the order the config writes them, after the entries hosts makes, which mihomo answers from first: name = server:…. +.example.com is the name and every name under it; geosite: and rule-set: names are lists (RULE-SET:<url> keys); V2Ray's domain:, full: and keyword: are read too. regexp: is left out. A prefix goes for every name after it: geosite:google,apple.
fake-ip-filter always-real-ip. Its geosite: and rule-set: entries are left out, and so is the whole filter in the whitelist and rule modes.
respect-rules, a server's #<policy> fragment UDP, TCP, TLS, HTTPS, QUIC and HTTP/3 keep the live rules or named policy through native DNS route fragments. A direct resolver bootstraps proxy names. QUIC and HTTP/3 require a policy with UDP support.
fallback, fallback-filter, proxy-server-nameserver, proxy-server-nameserver-policy, direct-nameserver, direct-nameserver-follow-policy Left out, as settings: Pipe races its servers and takes the first good answer, and looks every name up with them. In the tunnel a connection goes by its name — through a proxy, the name itself — so what the servers answer decides address rules alone.
fake-ip-range, fake-ip-range6, fake-ip-ttl, cache-algorithm, prefer-h3, use-system-hosts Left out, as settings: Pipe hands out fake IPs from its own range, and reads a hosts file only on a Mac, with read-etc-hosts.
use-hosts true, as mihomo has it unless told otherwise, is what Pipe does: [Host] answers first. false is left out, with a note.
enhanced-mode: redir-host Noted: in the tunnel, Pipe answers names with fake IPs, so that rules can go by name.
hosts [Host] entries.

Everything else#

Clash Pipe
log-level loglevel: debug is verbose, info is notify, the rest warning.
ipv6: true ipv6 = true.
mode The app's Rule, Global and Direct modes; noted when it is not rule.
tun.dns-hijack Port 53 is what Pipe's tunnel answers already: nothing is written. Another port is left out, with a note.
tun.route-exclude-address tun-excluded-routes.
tun.route-address Left out: a tunnel takes all traffic and excludes; it cannot add addresses to take. What should go past it belongs in tun-excluded-routes.
url-rewrite, Stash's http.url-rewrite [URL Rewrite] lines, each of the entry's three words quoted where it would read as something else: an entry can say nothing but a rewrite. Types other than header, 302, 307 and reject are left out.
port, mixed-port, allow-lan, external-controller, secret, sniffer, … Settings for Clash itself — how it listens, is controlled and runs — left out, named in one note.

sing-box#

Outbounds#

sing-box Pipe
Proxies, and endpoints [Proxy] lines. A proxy's detour becomes underlying-proxy, and network: tcp udp-relay=false; a proxy for UDP alone (network: udp) is left out. A tailscale endpoint is a tailnet policy, its tailnet offered for sign-in. An ssh outbound's private_key becomes a [Keystore] item the line names, with private_key_passphrase as private-key-passphrase; one with private_key_path is left out, the file being another machine's, and so is one with no host_key.
selector select, its default first; interrupt_exist_connections becomes interrupt-existing-connections.
urltest url-test, with its own url, interval (3m is interval=180), tolerance, and interrupt-existing-connections.
direct DIRECT. Its options are left out.
block REJECT.
dns A rule sending to it asks what Pipe's tunnel does already: nothing is written.

Rules#

A sing-box rule matches when one of its destinations does — domain, domain_suffix, domain_keyword, domain_regex, ip_cidr, ip_is_private, rule_set — and every other condition holds too: a port, a source, the network, and the rest. Pipe writes it so:

  • A rule of destinations alone becomes one line per destination, each with the rule's policy.
  • Any other becomes one logical rule: AND,((OR,((DOMAIN,a.example),(DOMAIN,b.example))),(DEST-PORT,443)),Proxy.
  • invert is NOT; a logical rule (type: logical, mode: and or or) is AND or OR of its rules, nested ten deep at most. Each value is written as a rule's is, quoted where it holds a comma or a parenthesis: a pattern's {1,3} or an SSID's comma stays in it.
  • A rule set a rule names that cannot be read narrows the rule when some of the others survive (with the note where the set is); when none do — or under invert, where dropping one would widen what the rule matches — the whole rule is left out rather than broadened to its other conditions. The note says so.
Condition Pipe
domain DOMAIN
domain_suffix DOMAIN-SUFFIX; with a dot in front, which is only what is under the name, DOMAIN-REGEX,^.+\.example\.com$
domain_keyword DOMAIN-KEYWORD
domain_regex DOMAIN-REGEX
ip_cidr IP-CIDR, IP-CIDR6
ip_is_private RULE-SET,LAN
rule_set The set's list (below)
port, port_range DEST-PORT (1000:2000 is 1000-2000)
source_ip_cidr, source_ip_is_private SRC-IP
source_port, source_port_range SRC-PORT
network PROTOCOL,TCP, PROTOCOL,UDP
protocol PROTOCOL: http is HTTP, tls is HTTPS, quic is QUIC, stun is STUN. Others leave the rule out.
process_name, process_path PROCESS-NAME: a name, or a path written out
wifi_ssid, wifi_bssid SUBNET,SSID:…, SUBNET,BSSID:…
network_type SUBNET,TYPE:WIFI, TYPE:CELLULAR, TYPE:WIRED
clash_mode A rule of nothing else is left out silently: Pipe's modes are the app's. One with other conditions applies in that mode only, which no Pipe rule can say — it is left out with a note, not made always-on.
geosite, geoip (before 1.12) See Categories.
Any other (package_name, user, inbound, ip_version, …) The rule is left out.
Action Pipe
route, or an outbound alone The outbound's policy. override_address and override_port become native override-address and override-port options, applied to TCP and UDP after the rule matches.
reject REJECT; with method: drop, REJECT-DROP.
hijack-dns Nothing: Pipe answers the DNS sent to port 53 through its tunnel already.
sniff Nothing: Pipe reads what a connection says where rules need it (Sniffing).
resolve Nothing of its own. sing-box looks no name up for an address rule until a resolve has come, so address rules before one are written no-resolve, and those after it are not.
route-options Destination overrides, UDP timeout, TLS fragmentation and network strategy controls become one native ROUTE-OPTIONS action. They accumulate; later matchers see the effective destination. Unsupported controls leave the whole action out with a note.
bypass, … Left out.

Terminal route actions can override the connection's destination while keeping the selected proxy or group and the original match metadata (Destination overrides). Nonterminal address/port options continue through later matching rules and apply to the selected terminal policy or FINAL. UDP timeouts, TLS fragmentation and network strategies follow native route controls, including their duration, stream and host-interface limits. Imported network_type remains a matcher, including on route-options, as in sing-box's rule schema. Native network-type is a separate explicit dial filter. Route fallback_delay accepts both documented duration strings and the reference implementation's uint32 nanoseconds. udp_connect, udp_disable_domain_unmapping and TLS spoofing remain unsupported and leave the whole action out. sing-box gives a sniffed domain precedence over the replaced destination; Pipe retains sniffed names for explicit extended-matching, while ordinary domain rules use the effective host. A conversion using both sniffing and nonterminal options reports this remaining distinction.

route.final becomes FINAL, with dns-failed. Without it, FINAL names the first outbound, as sing-box sends what no rule matches there.

Rule sets#

Rule set Pipe
remote, format: source RULE-SET with its URL: Pipe reads sing-box's source lists (List formats). update_interval becomes update-interval. no-resolve sits on the rule naming the set, not on lines inside an inline one.
remote, format: binary (.srs) The original URL, read as binary by Pipe. A country's addresses (geoip-jp.srs) become GEOIP,JP, and the local network's RULE-SET,LAN.
inline A [Ruleset <tag>] section of its rules.
local Left out: the file was on the device sing-box ran on.

DNS and the rest#

sing-box Pipe
The final server (else the first) Simple name routing uses dns-server and encrypted-dns-server; its bootstrap resolver becomes dns-bootstrap-server, excluded from ordinary queries. An advanced DNS program keeps named [DNS Server] definitions and selects its fallback with dns-final.
route.default_domain_resolver, and a DNS rule of nothing but outbound: any The server that looks up proxies' own names: dns-bootstrap-server, as Pipe's bootstrap servers are.
Servers address as Clash writes it (tls://, https://, quic://, h3://, udp://, tcp://, an address; local and dhcp:// are system), or 1.12's type with server, server_port and path (local, dhcp, resolved and mdns are system; a tailscale server is left out, with a note: a tailnet signed in to in Pipe answers its own names). A server's detour becomes the same named policy for UDP, TCP, TLS, HTTPS, QUIC and HTTP/3; the engine applies group selection before reusing a DNS connection. Unsupported detours are reported.
A fakeip server, and rules sending to it Nothing: in the tunnel, Pipe answers with fake IPs itself.
A hosts server Reported and left out. A named resolver's records cannot become global [Host] entries without changing which queries it answers.
dns.rules sending names to a server [Host] entries in source order: domain, domain_suffix (*.example.com and example.com; with a dot in front, *.example.com alone), domain_keyword, geosite, and rule_set lists of names. Explicit rules naming the final server are retained, so an earlier exclusion still wins over a later broad match. An unconditional rule becomes *; a local resolver becomes server:system.
Query-type filters, domain regex, logical rules and inversion An ordered [DNS Rule] program. Domain alternatives remain alternatives, additional conditions remain requirements, and the configured literals keep their case and dotted-suffix behavior. All rules in that program use the DNS interpreter; they are never mixed with generated Host rules that would change their order.
DNS actions and exchange controls route, route-options, evaluate, respond, reject/drop and predefined response codes and records are preserved, including named evaluated responses, response code/record/address filters, racing response rules and speculative fallback. Cache bypass, optimistic-cache control, TTL rewriting, query timeouts and client-subnet changes become native rule options.
Other DNS rule fields Unsupported conditions and actions are diagnosed as whole-rule omissions. outbound (but for any alone, above), clash_mode, per-rule strategy, process/network metadata and mixed address/metadata/logical DNS rule sets remain unsupported. Advanced programs preserve domain-only rule_set conditions through the shared list loader; simple name-only programs retain the Host conversion above.
dns.strategy Advanced programs use dns-strategy directly, with as_is when absent so AAAA queries still reach their rules. Simple name routing retains the previous mapping: prefer_ipv4 enables IPv6; prefer_ipv6 and ipv6_only enable IPv6 with a note that Pipe prefers IPv4.
The tun inbound route_exclude_address becomes tun-excluded-routes.
Other inbounds Where sing-box listened: left out.
log.level loglevel.
experimental, ntp, … Settings for sing-box itself, left out.

Advanced DNS imports allow at most 256 resolvers, 1,024 rules, 256 KiB of DNS text and 16,384 values. Concurrent conversions share a temporary memory allowance. Exceeding these bounds or the allowance aborts conversion.

Categories#

Clash, mihomo and sing-box name their geodata by category: GEOSITE,google, GEOIP,JP, geosite-cn.srs. A country's addresses are Pipe's own GEOIP, which its built-in table answers for every country. Every other category — every domain category, whatever country it is about — becomes the list of the same category from MetaCubeX's meta-rules-dat, the data mihomo's own geodata is built from, and the list a Pipe profile's GEOSITE names too: fetched and kept current like any rule set. Where the source says where its geodata lives (geox-url, a mirror of the same repository), the lists come from there — a mirror is the point of naming one. Every substitution is noted with the list's URL, for when it does not load.

Category Pipe
GEOIP,<country> (GEOIP,JP) GEOIP,JP, the built-in table's.
GEOIP,private (or lan) RULE-SET,LAN.
Any other GEOIP (telegram, …) RULE-SET,https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geoip/<name>.yaml
GEOSITE,<name> RULE-SET,https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/<name>.yaml; a category's entries of one attribute (google@cn) are the list of that name too.

In a [Host] key, which takes lists only, a GEOSITE category is its list too.

IP-ASN rules need an ASN database: the converted profile's ip-asn-maxmind-url is the one the configuration names (mihomo's geox-url.asn), else meta-rules-dat's GeoLite2-ASN.

[General]
ip-asn-maxmind-url = https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/GeoLite2-ASN.mmdb

[Rule]
RULE-SET,https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/category-ads-all.yaml,REJECT
RULE-SET,https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/google.yaml,Proxy
RULE-SET,https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geoip/telegram.yaml,Proxy,no-resolve
IP-ASN,13335,Proxy,no-resolve
GEOIP,JP,DIRECT
FINAL,Proxy,dns-failed

A converted group whose name filters change meaning after proxy-name collision renaming is rejected with a routing note. The same applies when differently modified copies of a shared subscription make name filters or the selected default ambiguous. Review that group before using the converted profile; static provider filters and known inline defaults use the original source names.