starlink-enterprise-mcp

starlink-enterprise-mcp

A hosted MCP server that enables AI agents to interact with the Starlink Enterprise API using service accounts, with transparent OAuth token management and 55 auto-generated tools.

Category
访问服务器

README

Starlink Enterprise MCP Server

License: MIT TypeScript Starlink API MCP Protocol Cloud Run

🛰️ Hosted, multi-account MCP for the Starlink Enterprise API Any AI agent — Claude, ChatGPT, anything that speaks MCP — connects with a real Starlink V2 Service Account, drives the full Enterprise API, and stays connected indefinitely. The Client Secret never touches the model.

⚡ Features

  • 🔐 Hosted OAuth proxy with API-key login — The server is the OAuth 2.1 authorization server. But Starlink has no interactive OAuth and no MFA, so the browser login page doesn't ask for a username and password — it asks for a Service Account Client ID + Client Secret. The server validates them with a client_credentials grant; credentials never enter the model's context.
  • 🔁 Transparent token re-minting — Starlink bearer tokens are short-lived (~15 min) and have no refresh token. The server stores the service-account credentials alongside the issued MCP token and silently re-mints a fresh bearer before expiry, and again on any 401. AI sessions stay alive across long conversations.
  • 🍪 Stateless login state — OAuth pending state rides in HMAC-signed HttpOnly cookies, so logins survive container restarts and Cloud Run instance switches.
  • 🗄️ Firestore persistence — Issued tokens and DCR client registrations survive deploys and scaling events when MCP_PERSISTENCE=firestore.
  • 🤝 Claude and ChatGPT support — Public-client dynamic registration (token_endpoint_auth_method=none, PKCE only) means ChatGPT connects out of the box alongside confidential clients like Claude.
  • 🧬 55 auto-generated tools from the spec — The Starlink Enterprise v2 OpenAPI spec, regenerated on every build. Drop in a new spec and rebuild to pick up new endpoints.
  • 🎯 No curated layer needed — At 55 operations the full tool surface fits comfortably in a model's working memory, so every tool is exposed directly with read/write/destructive annotations.
  • 🪛 Operator-tunable — Disable globs (MCP_DISABLED_TOOLS=delete_*,*reboot*), a semantic destructive toggle (MCP_DISABLE_DESTRUCTIVE=true), branded login page (MCP_LOGIN_HEADER, MCP_ICON_URL). No code change for per-deployment policy.
  • 🧪 A real test suite — including a draft-2020-12 JSON Schema guard that compiles every tool's input schema on every run.

🔑 How auth differs from a username/password MCP

Username/password OAuth proxy This server (Starlink)
Login page collects username + password Service Account Client ID + Client Secret
Upstream grant password (+ MFA) client_credentials
MFA yes none (service accounts skip MFA)
Refresh upstream refresh token re-run client_credentials (no refresh token)
Token TTL hours ~15 min, re-minted on expiry / 401

The DCR + browser-redirect OAuth shell is identical — what changed is the login form and the upstream grant.

🏗️ Architecture

AI client (Claude/ChatGPT)
  │  OAuth 2.1 DCR + browser login (PKCE)
  ▼
[ Starlink MCP HTTP server (this repo) ]   ← OAuth proxy, login page (Client ID + Secret), cookies, Firestore
  │  per-account Starlink bearer (client_credentials)
  ▼
[ Starlink Enterprise API  https://web-api.starlink.com ]

Each issued MCP bearer maps to a stored upstream Starlink token plus the service-account credentials used to mint it, so the server can re-mint silently.

💻 Running locally (stdio)

npm install
npm run build
export STARLINK_CLIENT_ID=<your-service-account-client-id>
export STARLINK_CLIENT_SECRET=<your-service-account-secret>
npm start                                      # MCP_TRANSPORT defaults to stdio

Create a V2 service account at Account Settings → API V2 Service Accounts (requires the Admin or Service Account Management role).

Add this entry to your local MCP client config (Claude Desktop, etc.):

{
  "mcpServers": {
    "starlink": {
      "command": "node",
      "args": ["/path/to/starlink-enterprise-mcp/build/index.js"],
      "env": {
        "STARLINK_CLIENT_ID": "...",
        "STARLINK_CLIENT_SECRET": "..."
      }
    }
  }
}

You can also set STARLINK_ACCESS_TOKEN directly to skip the grant if you already hold a bearer.

🌐 Running as a hosted server (HTTP)

export MCP_TRANSPORT=http
export MCP_PORT=3000
export MCP_BASE_URL=https://mcp.example.com
export MCP_SESSION_SECRET=<32+ random hex>     # signs login-state cookies
npm start

Connect from Claude / ChatGPT by giving it the URL https://mcp.example.com/mcp. The client DCR-registers, redirects the user to /authorize, the user pastes their Service Account Client ID + Secret, and the bearer flows back to the AI automatically. No upstream operator credentials are needed in HTTP mode — each user brings their own service account.

☁️ Cloud Run deployment

Ships with a Cloud Run-friendly Dockerfile and cloudbuild.yaml.

Component Purpose
Cloud Run service Runs the HTTP server with session affinity and min-instances=1
Firestore (native mode) Persistent token store and DCR client registry
Cloud Run SA → roles/datastore.user Firestore access
gcloud builds submit --config cloudbuild.yaml --project=<your-project>

Required env vars on Cloud Run:

Var Notes
MCP_TRANSPORT=http enable the HTTP transport
MCP_BASE_URL public URL, e.g. https://mcp.example.com
MCP_SESSION_SECRET 32+ chars; signs cookies & must be stable across instances
MCP_PERSISTENCE=firestore enable Firestore-backed tokens and clients
GOOGLE_CLOUD_PROJECT Firestore project ID (auto-set on Cloud Run)

Optional: STARLINK_API_URL, STARLINK_TOKEN_URL (defaults are correct for production), MCP_LOGIN_HEADER, MCP_ICON_URL, MCP_LOGIN_LOGO_URL, MCP_DISABLED_TOOLS, MCP_DISABLED_ACTIONS, MCP_DISABLE_DESTRUCTIVE, MCP_CORS_ORIGIN.

Other targets: fly.toml (Fly.io), render.yaml (Render), railway.toml (Railway), docker-compose.yml, and k8s/ manifests (apply with kubectl apply -k k8s/).

Security note on persistence. In HTTP mode the issued-token records hold each user's Starlink service-account Client ID + Secret so the server can re-mint bearers. Protect the token store accordingly — restrict the Firestore collection / file volume, and rotate MCP_SESSION_SECRET and service-account secrets per Starlink's guidance if exposure is suspected.

🔐 OAuth flow (detailed)

  1. AI client hits GET /.well-known/oauth-protected-resource/mcp and /.well-known/oauth-authorization-server for discovery.
  2. AI client POSTs /register (RFC 7591 DCR). Public clients pass token_endpoint_auth_method=none and get back a client_id only; confidential clients also get a client_secret. Registrations persist in Firestore.
  3. AI redirects the user's browser to /authorize?... with PKCE parameters. The server stores the pending request in a signed cookie (mcp_pending_auth, 15 min TTL) and renders the login page.
  4. User submits their Service Account Client ID + Client Secret → server runs POST {STARLINK_TOKEN_URL} with grant_type=client_credentials. On success it stores the Starlink token + credentials and issues an authorization code.
  5. The server redirects back to the AI client; cookies are cleared.
  6. AI exchanges the code at /token for the MCP-issued bearer + refresh token.
  7. On every /mcp request, the server verifies the bearer and transparently re-mints the upstream Starlink token if it's near expiry. On a 401 from the API, the client re-mints and retries once.

🧰 Tools

55 tools generated from spec/starlink-enterprise-v2.json, grouped by tag:

Group Examples
Account get_account, get_products, post_data_usage_query
Service Lines get_service_lines, post_service_lines, put_service_line_nickname, post_service_line_data_top_up, patch_service_line_consume_from_pool
User Terminals get_user_terminals, post_user_terminals, post_user_terminal_reboot, put_user_terminal_l2vpn
Routers get_router, get_routers_configs, post_routers_configs, post_router_reboot, *_routers_configs_tls
Addresses get_addresses, post_addresses, get_address, put_address
Contacts get_contacts, post_contacts, put_contact, delete_contact
Data Pools get_data_pools, get_data_pools_usage, post_data_pools_by_data_pool_id_set_automatic_top_up
Flights post_flights_status (aviation accounts)
Managed post_managed_customers (provider accounts)

Each tool is annotated readOnlyHint / destructiveHint. Reboots and deletes are flagged destructive — hide them all with MCP_DISABLE_DESTRUCTIVE=true, or selectively with e.g. MCP_DISABLED_TOOLS=delete_*,*reboot*.

Tool names map 1:1 to operations ({method}_{path}, with the /public/v2 prefix stripped). Two deep service-line paths are abbreviated to fit the MCP 64-character name limit.

🔄 Regenerating tools

The spec lives at spec/starlink-enterprise-v2.json (sourced from https://web-api.starlink.com/enterprise/swagger/v2/swagger.json). To refresh:

# drop a new spec into spec/starlink-enterprise-v2.json, then:
npm run generate      # rewrites src/generated/
npm run build
npm test

npm run build runs generate automatically via the prebuild hook.

🧪 Tests

npm test

The Firestore-backed tests are emulator-gated and skip cleanly without one.

📋 What this server is

  • Two MCP transports. stdio for local CLI integrations and http (Streamable HTTP) for hosted deployments. Production uses http.
  • Auto-generated tools from the Starlink Enterprise v2 OpenAPI spec, regenerated on every build.
  • Hosted OAuth login where the login page collects Starlink Service Account credentials (Client ID + Secret), not a username/password. MFA does not apply to service accounts.
  • Transparent token re-minting via client_credentials (no refresh token).
  • Firestore persistence for tokens and DCR clients when MCP_PERSISTENCE=firestore.

License

MIT

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选