9seconds/mtg: a single-secret MTPROTO proxy for Telegram, installed with Docker
Highly opinionated MTPROTO proxy for Telegram
At a glance
- What is it?
- mtg is a Go MTPROTO proxy for Telegram built around one secret, domain fronting and native blocklists. It is aimed at small, private deployments rather than public proxy pools, and its Docker image is the shortest path to a running instance.
- Who is it for?
- Adopt mtg if you run a private Telegram proxy for a small group and want one secret, a scratch Docker image and proxy protocol support in front of HAProxy or ELB. Do not adopt it if you need adtag, multiple user secrets or a management WebUI, because the README states v2 removed adtag and that a WebUI will not be built; use the mtg-multi fork if you disagree with the single-secret decision.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 112 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem mtg solves, and the operator it assumes
Telegram clients speak MTPROTO, and in a censored network the practical question is not whether a proxy protocol exists but whether the proxy survives inspection. mtg is a Go implementation of that proxy whose README describes it as "minimal unbloated" and sized for roughly 10-20k simultaneous connections. There is no user management layer. The design target is a small group, not a public endpoint.
The README is explicit about that audience. It argues that a proxy acting as a fat connectivity point for hundreds of clients is an illusion, because the first response of an authority in a censored environment is IP blocking. The stated preference is a proxy shared within a family or a group of college friends, with a small number of connections and no public announcement of its presence. That framing explains most of the feature decisions below.
If you want a proxy that supports adtag, the possibility of promoting a channel through a Telegram bot, the README points to the telemt project instead. mtg v1 supported it; v2 does not. The README's own reason is that adtag needs communication through a fragile set of middle proxies, a complex setup that must expose public IPs, and it comes with lower bandwidth and higher latency.
Domain fronting, doppelganger traffic shaping and the rejection path
The mechanism that distinguishes mtg from a plain MTPROTO forwarder is what happens when a request is rejected. According to the README, mtg falls back to accessing the real website it is fronting. A request can fail for several reasons listed there: anti-replay protection, an accidental access to the webserver, or a stale request. When mtg rejects it, the connection is not broken. mtg connects to the website, replicates what the client sent, and proxies the response back as is. The user sees a reply from the real site, which the README describes as byte-to-byte identical to the response of the real netloc.
The second layer is what the README calls doppelganger behaviour. When everything is fine and the connection is genuinely carrying Telegram, mtg still tries to look like the site it fronts. The README's argument is statistical: a large CDN steadily pumps data, while a small website emits short, easily compressible bursts. mtg artificially emulates those delays so that the traffic pattern is statistically indistinguishable from the real site, and it follows two common traffic chunking patterns. The README's stated goal is to make a censor spend more resources to determine that Telegram is present rather than an nginx-served webshop.
Two supporting pieces are visible in the repository rather than the prose. The go.mod file lists github.com/pires/go-proxyproto, which corresponds to the README's claim of proxy protocol v1 and v2 support, the feature that makes HAProxy and ELB integration workable. It also lists github.com/yl2chen/cidranger and github.com/tylertreat/BoomFilters, consistent with the native blocklist support the README describes, where mtg consumes lists of potentially dangerous IPs that were previously delegated to projects such as FireHOL. The antireplay/ and ipblocklist/ directories in the repository layout match those two concerns.
Installing mtg with Docker and running it for the first time
The Dockerfile builds a static binary in a golang:1.26-alpine stage and copies it into a scratch image. The entrypoint is /mtg and the default command is run /config/config.toml. The image also ships example.config.toml as /config.toml, and the build stage creates /config/config.toml as a symlink to /config.toml, so both a file mount and a directory mount are supported.
That default command is the whole invocation: the container runs `/mtg run /config/config.toml`, which means you supply the config file and the port mapping, and nothing else.
ENTRYPOINT ["/mtg"]
CMD ["run", "/config/config.toml"]The README states that only two sections are mandatory in the configuration file: secret and bind-to. Every other section in the example file is filled with default values, so a minimal config carries just those two keys, and the rest can be left as the example ships them.
On startup the process should begin serving on the address given by bind-to. The README does not document a specific startup log line, so check the process output rather than expecting a named banner. The proxy protocol support means that if you put mtg behind HAProxy or an ELB, the load balancer can pass the original client address; the README treats that integration as a first class citizen.
The single-secret decision and what it costs you
mtg accepts one secret. The README's rationale is that multiple secrets solve no problems while adding complexity, and that for throwout proxies the feature is a useless luxury. The author labels this controversial and links to a longer rationale written in Russian, and points readers who disagree to the mtg-multi fork by dolonet.
The practical consequence is that revocation is all or nothing. If one member of your group leaks the link, rotating the secret invalidates it for everyone, and there is no per-user accounting to tell you who was responsible. For a family or a handful of friends that is an acceptable trade. For anything that resembles a subscription service, it is a structural mismatch, and the existence of a dedicated fork is the clearest evidence that the maintainer knows it.
The same philosophy shows up in what the README refuses to build. There is no management WebUI, and the README states plainly that it will not be added. Adtag support was removed in v2 to debloat the project. If your deployment model depends on either, mtg is the wrong tool and you should be looking at the alternatives the README itself lists.
Where mtg is the wrong choice
The clearest failure mode is upgrading from v1. The README opens with a warning for anyone on v1.0 or anyone whose proxy broke after an upgrade, and directs them to the Version 2 chapter. Two breaking changes are named: the configuration file format changed, and adtag support was removed completely. A v1 configuration will not simply carry over, and there is no documented migration path in the README beyond reading the example configuration file, which the README says is heavily commented and mostly optional.
Scale is the second boundary. The README's own figure is roughly 10-20k simultaneous connections. That is a real number, not a suggestion, and it frames mtg as infrastructure for a group rather than a service. Combined with the single secret, it means you cannot grow into a public proxy by adding users; you would need a different design.
The README is silent on several operational questions. It does not document rollback for a bad configuration, it does not describe a health endpoint, and it does not give a recovery procedure for a lost secret beyond regenerating one. Those gaps matter if you are the person on call. The repository does contain a SECURITY.md and a BEST_PRACTICES.md, so the material acknowledges that operational guidance exists, but the README itself does not carry it.
How mtg differs from the official and Python proxies
The README lists the official TelegramMessenger/MTProxy, alexbers/mtprotoproxy in Python, seriyps/mtproto_proxy in Erlang, teleproxy in C, mtproto.zig in Zig and telemt in Rust, and says all of these work well and now have feature parity, including adtag, replay attack protection, domain fronting and faketls. So the honest comparison is not about protocol coverage.
The difference is in the details the README chooses to emphasise. Domain fronting in mtg is not just a fallback path; it is a byte-for-byte replay of the real site's response when a request is rejected, and the doppelganger behaviour extends that disguise to the timing of successful connections. The README also positions deployment style: it invokes ShadowSocks as the model, arguing that a proxy should be restorable anywhere easily, which is why the Docker image is a scratch container with a static binary.
If adtag matters to you, the README's own recommendation is telemt, and the reasoning is candid: adtag needs middle proxies, public IPs, and it costs bandwidth and latency. If you want a Python codebase you can read and modify in an afternoon, mtprotoproxy is the natural counterweight. mtg's answer to that is a different one: the README notes that v2 was redesigned so it can be embedded into other Golang software, with parts replaceable, which is a library story the other implementations do not make.
Maintenance, licensing and upgrade cost
The repository is not archived. The last push was on 2026-06-11, which is roughly three months before the date used for this review, so the project is within a normal release cadence rather than dormant. Recent releases are v2.2.6 on 2026-03-30, v2.2.7 on 2026-04-01 and v2.2.8 on 2026-04-07. The tag naming is consistent, and the repository contains a .goreleaser.yml and a .mise.toml, so the release tooling is checked in rather than improvised.
Upgrade cost is dominated by the v1 to v2 break rather than by routine patch upgrades. The README does not promise configuration stability across major versions, and it explicitly warns v1 users. Within v2, the mandatory surface is small, which limits how much a patch release can break: only secret and bind-to are required, and everything else defaults.
The licence is MIT, which permits commercial use and modification with the usual requirement to keep the copyright and permission notice. That is a permissive licence and it places few constraints on embedding mtg as a library, which the README says is a supported use. Note that the README links to a rationale discussion hosted in the project's issue tracker and to forks maintained by other people; those carry their own licensing and are not covered by the MIT grant on this repository. This is a description of the licence text, not legal advice.
Editorial conclusion
Adopt mtg if you run a private Telegram proxy for a small group and want one secret, a scratch Docker image and proxy protocol support in front of HAProxy or ELB. Do not adopt it if you need adtag, multiple user secrets or a management WebUI, because the README states v2 removed adtag and that a WebUI will not be built; use the mtg-multi fork if you disagree with the single-secret decision. Before deploying, verify the mandatory secret and bind-to sections against example.config.toml, and confirm which config path your container actually mounts, since the Dockerfile keeps /config.toml and /config/config.toml as two views of the same file.
Frequently asked questions
What is the fastest proxy for Telegram?
The README does not rank proxies by speed. It states that mtg and the other listed implementations have feature parity, and that adtag setups have lower bandwidth and higher latency, but it makes no comparative performance claim.
How does MTProto work?
The README does not describe the MTPROTO protocol itself. It covers what mtg does with a connection: domain fronting to the real website when a request is rejected, and emulated timing to resemble the fronted site on successful connections.
Where can I find free proxies for MTProto?
The README does not point to any proxy lists. It argues the opposite direction, that a proxy should be shared within a small group and should never publicly announce its presence.
What protocol does Telegram use?
Telegram uses MTPROTO, and mtg is an MTPROTO proxy for it. The README does not go further into the protocol specification.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/9seconds-mtg)