Skip to main content
Glama
Kamu1403

3GPP FTP Remote MCP Server

by Kamu1403

3GPP FTP Remote MCP Server

A remote MCP server for browsing public files from the 3GPP FTP service. It runs on Cloudflare Workers using TypeScript, Wrangler, and Streamable HTTP transport.

The MCP endpoint is /mcp. The server is stateless and does not require 3GPP credentials. All 3GPP source access is read-only; one separate, explicitly invoked tool can save a selected public file to the user's ChatGPT Library.

Tools

search(query: string)

Uses the official 3GPP filename conventions to locate public files before falling back to a bounded directory crawl. Supported query forms include:

  • TS/TR references such as TS 23.501 or TR 21.900 v15.1.1

  • Versioned spec archives such as 23501-k20.zip

  • Multipart specs such as 29.198-08 or 29198-08-651.zip

  • TDoc identifiers such as S2-2601720, SP-200062, and modern RAN/SA/CT WG identifiers

  • Conventional CR member filenames such as 23501_CR1668r4_(Rel-16)_S2-2001278_....docx

  • Exact paths or URLs under the configured public 3GPP FTP origin

Each result contains:

  • id: canonical 3GPP FTP path used by fetch

  • title: filename

  • url: public 3GPP URL

  • metadata: path, strategy, parsed identifiers, modified date, size, and extension when available

Exact files and direct paths are validated with a one-byte ranged GET. The 3GPP server rejects many HEAD requests even when the same public file is downloadable.

The response can also contain warnings. A CR number alone does not determine a public FTP path; CR lookup without a WG/TSG TDoc requires a future portal adapter or CR database index, so the server reports that limitation instead of guessing a link.

fetch(id: string)

Fetches one result by its canonical path. Text and HTML content is returned as text, up to the configured character limit. Binary formats such as ZIP, RAR, DOCX, XLSX, and PDF return metadata, a Worker relay URL, and an MCP resource_link. The file is streamed only when a client follows that link.

download_file(id: string)

Returns a read-only MCP resource_link for an ID returned by search. The resource points to /download?id=<artifact-id> on the same Worker. This explicit tool is useful for clients that do not automatically act on the resource link included by fetch.

import_to_chatgpt(id: string)

Renders a versioned MCP Apps widget that streams one result through /download, constructs a browser File, and calls ChatGPT's optional window.openai.uploadFile(file, { library: true }) API. This is the only write-capable tool because it creates a ChatGPT-hosted file. Its MCP annotations mark it non-read-only and non-idempotent, and its description requires an explicit user request before invocation.

The widget:

  • auto-starts only after the explicit import_to_chatgpt tool call

  • saves to ChatGPT Library when that feature is available to the user

  • persists a private import key to avoid duplicate uploads when the widget rerenders

  • enforces THREEGPP_IMPORT_MAX_BYTES before upload, including for responses without a declared size

  • falls back to opening the streamed file when the ChatGPT upload API is unavailable

  • does not automatically attach the saved file to the current chat or a project

Streaming Relay

The /download HTTP route:

  • accepts GET, HEAD, OPTIONS, and one HTTP byte range

  • permits only the configured 3GPP origin and /ftp root

  • streams the upstream response body without reading it into Worker memory

  • adds download, MIME, CORS, and nosniff headers

  • implements HEAD with a one-byte upstream GET, because the 3GPP service commonly rejects direct HEAD requests

  • does not persist files in Worker storage

Related MCP server: File Search Tool

Project Layout

src/index.ts       Remote MCP server, resource, and tool registration
src/conventions.ts Official TS/TR, TDoc, CR parsing and group routing
src/import-to-chatgpt.ts ChatGPT Library import preparation and widget
src/relay.ts       Restricted, zero-storage streaming download relay
src/threegpp.ts    Public 3GPP listing, search, and fetch logic
src/types.ts       Worker environment and result types
tests/             Deterministic convention, resolver, and relay tests
wrangler.jsonc     Cloudflare Worker configuration
chatgpt-plugin/    ChatGPT registration metadata and setup guide
legacy-python/     Original Python MCP prototype

Prerequisites

  • Node.js and npm

  • A Cloudflare account for deployment

Verify the local tools:

node --version
npm --version

Install

cd 3gpp-ftp-connector
npm install
npm test
npm run typecheck

Run Locally

Start the Worker development server:

npm run dev

Wrangler normally serves it at http://localhost:8787. Confirm the Worker is running:

curl http://localhost:8787/

The response should advertise /mcp, Streamable HTTP, and the search, fetch, download_file, and import_to_chatgpt tools.

Test the relay metadata and a small byte range without downloading the whole archive:

curl --head "http://localhost:8787/download?id=%2Fftp%2FSpecs%2Farchive%2F23_series%2F23.501%2F23501-k20.zip"
curl --range 0-31 "http://localhost:8787/download?id=%2Fftp%2FSpecs%2Farchive%2F23_series%2F23.501%2F23501-k20.zip" --output relay-sample.bin

Test with MCP Inspector

Keep npm run dev running and open a second terminal:

npx @modelcontextprotocol/inspector@latest

In Inspector:

  1. Select Streamable HTTP.

  2. Enter http://localhost:8787/mcp.

  3. Connect and list the available tools.

  4. Call search with a TS/TR reference, filename, TDoc, CR filename, path, or URL.

  5. Pass a returned id to fetch.

  6. Call download_file with the same id and inspect its resource_link.

  7. Call import_to_chatgpt and inspect its structured result and ui://threegpp/import-to-chatgpt-v1.html resource.

MCP Inspector can verify tool discovery, annotations, structured output, resource MIME type, and widget HTML. It does not provide ChatGPT's optional window.openai.uploadFile host API, so the actual Library write must be tested in ChatGPT after deployment. The automated test suite uses a mocked bridge to verify the complete widget upload and deduplication flow.

Example search input:

{
  "query": "S2-2601720"
}

Example fetch input:

{
  "id": "/ftp/tsg_sa/WG2_Arch/TSGS2_174_Malta_2026-04/Docs/S2-2601720.zip"
}

Deploy

Authenticate Wrangler and deploy:

npx wrangler login
npm run deploy

With the default Worker name, the deployed endpoint is:

https://threegpp-ftp-mcp.<cloudflare-subdomain>.workers.dev/mcp

Streamed files use the same origin:

https://threegpp-ftp-mcp.<cloudflare-subdomain>.workers.dev/download?id=<artifact-id>

Wrangler prints the exact URL after a successful deployment.

Connect to ChatGPT

The maintained ChatGPT app/plugin name, description, registration values, and test prompts are in chatgpt-plugin/. Update that metadata when the public endpoint or tool behavior changes.

Configuration

Public configuration is stored in wrangler.jsonc:

  • THREEGPP_BASE_URL: 3GPP website origin

  • THREEGPP_FTP_ROOT: allowed FTP path root

  • THREEGPP_SEARCH_ROOTS: comma-separated directories searched by default

  • THREEGPP_SEARCH_MAX_DIRECTORIES: maximum directories visited only by the generic fallback

  • THREEGPP_SEARCH_MAX_RESULTS: maximum results returned per search

  • THREEGPP_FETCH_TEXT_LIMIT: maximum text characters returned by fetch

  • THREEGPP_IMPORT_MAX_BYTES: maximum bytes the browser widget may buffer for one ChatGPT Library import; defaults to 100 MiB and is capped at 512 MiB

The Worker uses nodejs_compat because the Cloudflare Agents SDK currently includes dependencies that import Node built-in modules.

Current Scope

  • Public 3GPP FTP access only

  • Read-only search, fetch, and download_file tools

  • Explicit import_to_chatgpt write tool for ChatGPT Library

  • No portal authentication

  • Original files are relayed on demand with no persistent downloads or storage

  • No ZIP, RAR, Office, or PDF extraction inside the Worker

Cloudflare Workers can natively decompress deflate streams, so a strictly capped ZIP/DOCX proof of concept is technically possible. It is not enabled because the free plan allows only 10 ms of CPU per request, while RAR requires JavaScript/Wasm archive processing and comment/revision-aware Office extraction requires additional ZIP/XML work. That combination would be unreliable for real meeting packages. The relay therefore transfers original bytes without parsing or storing them. A parser service can be added later without changing the search, fetch, or download_file contracts.

Legacy Python Prototype

The original Python/stdin implementation is retained under legacy-python/. It is not used by the Cloudflare Worker or required for deployment.

F
license - not found
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    An MCP server that enables programmatic access to IETF RFC documents, allowing users to fetch, search, and extract specific sections from RFCs.
    3
    56
    19
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    An MCP server that enables file system search and inspection, including directory listing, regex-based file name and content searches, and reading text, PDF, and DOCX files.
    1
    MIT

View all related MCP servers

Related MCP Connectors

  • Read-only MCP server for searching Japan government procurement bid information from the KKJ portal.

  • 2,000+ MCP servers read at source level. Know what one does before you connect. Free, no key.

  • MCP server for Open Archives: Dutch genealogical records and historical page transcriptions.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Kamu1403/3gpp-ftp-connector'

If you have feedback or need assistance with the MCP directory API, please join our Discord server