rosetta-mcp

rosetta-mcp

Modular MCP hub hosting multiple read-only addons behind a single OIDC authentication layer, enabling agents to use services like Google Maps and transit APIs with server-side API key management.

Category
访问服务器

README

rosetta-mcp

Rosetta is a modular MCP hub: one HTTP service hosting many thin, read-only MCP servers (addons), each mounted under its own path, behind a single OIDC bearer-token authentication layer.

Like the stone: one endpoint, and every agent reads it in its own tongue.

agent ──Bearer JWT──►  https://rosetta.example.com/maps/      (Google Maps, Places, Weather)
                       https://rosetta.example.com/transit/   (SNCF + IDFM/Navitia)
                       https://rosetta.example.com/<addon>/   (drop a module in, it mounts)
                       https://rosetta.example.com/health     (unauthenticated, per-addon state)

Why a hub: provider API keys stay server-side (one deployment, one place to rotate), agents only ever hold an access token, and adding MCP #12 is a new module + nothing else - no new pod, no new image elsewhere, no key sprayed into agent environments.

Addons

An addon is a module in src/rosetta/addons/ exposing:

from ._common import new_server

mcp = new_server("name")          # FastMCP: stateless streamable HTTP at "/"
required_env = ["SOME_API_KEY"]   # optional

The loader mounts each addon under /<module-name> and isolates failures:

Addon state Meaning
ok mounted, fully operational
degraded mounted, but some required_env is missing - tools answer with an explicit error
error import/startup failed - addon skipped, hub and other addons stay up
disabled excluded by ROSETTA_ADDONS

Per-addon state is reported on GET /health. Modules starting with _ are shared helpers, never mounted. Each addon also runs standalone over stdio for local debugging (python -m rosetta.addons.maps).

User-data addons (identity = "user")

An addon may declare identity = "user": the hub then refuses machine tokens on its path (403) - the bearer token must carry a human subject. Tools read the caller's claims via a context variable, so a user-data addon keys its server-side credential store on sub: agents never hold the downstream credentials, only their own identity token. Such addons may also register plain HTTP routes (extra_routes / open_paths) for browser-facing enrolment flows, guarded by the ingress SSO (forwardAuth) instead of the hub JWT.

Bundled addons: maps (Google Routes / Places New / Weather - needs GOOGLE_MAPS_API_KEY), transit (SNCF + IDFM Navitia - needs SNCF_API_KEY, IDFM_API_KEY), google (user-data class: Gmail read/search/draft-only + Calendar list/create/update - deliberately no send, no delete, no labels: the guard is the tool surface itself. One-time per-user enrolment at /google/enroll stores the Google refresh token server-side under ROSETTA_GOOGLE_DATA). Tool descriptions are intentionally in French: they are runtime UX for the French-speaking agents this hub serves, not documentation.

Authentication

Rosetta is an OAuth 2.1 resource server. It stores no credentials and no users: it validates JWT access tokens (RFC 9068) issued by an external OIDC provider (tested with Authelia >= 4.39, clients configured with access_token_signed_response_alg != none), against the provider's JWKS.

  • Machine agents use the client_credentials grant - no human in the loop.
  • User-delegated access (future data-holding addons) uses authorization_code
    • refresh, or the device code flow for headless bodies.
  • RFC 9728 protected-resource metadata is served at /.well-known/oauth-protected-resource (and per addon), and every 401 carries the WWW-Authenticate pointer, so OAuth-aware MCP clients can discover the authorization server on their own.

Note the trailing slash: the MCP endpoint of an addon is /<name>/ - /<name> answers with a 307 redirect.

Configuration

Env Default Purpose
ROSETTA_AUTH oidc off disables auth (local dev only)
ROSETTA_ISSUER https://auth.berard.me OIDC issuer (token iss)
ROSETTA_AUDIENCE external URL required token aud
ROSETTA_EXTERNAL_URL https://rosetta.mcp.berard.me public URL (RFC 9728 metadata)
ROSETTA_JWKS_URI <issuer>/jwks.json JWKS endpoint override
ROSETTA_ADDONS all discovered comma-separated allowlist
GOOGLE_MAPS_API_KEY - maps addon
SNCF_API_KEY, IDFM_API_KEY - transit addon

Development

python3 -m venv .venv
.venv/bin/pip install -e .[dev]
.venv/bin/pytest
ROSETTA_AUTH=off .venv/bin/uvicorn rosetta.main:app --port 8200

Deployment

Published as ghcr.io/antorfr/rosetta-mcp (SemVer tags, docker-publish workflow). Runs as a plain container: port 8200, no volume, configuration by environment only.

推荐服务器

Baidu Map

Baidu Map

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

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

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

官方
精选
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

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

官方
精选
本地
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

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

官方
精选
本地
TypeScript
VeyraX

VeyraX

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

官方
精选
本地
Kagi MCP Server

Kagi MCP Server

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

官方
精选
Python
graphlit-mcp-server

graphlit-mcp-server

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

官方
精选
TypeScript
Neon MCP Server

Neon MCP Server

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

官方
精选
Exa MCP Server

Exa MCP Server

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

官方
精选
mcp-server-qdrant

mcp-server-qdrant

这个仓库展示了如何为向量搜索引擎 Qdrant 创建一个 MCP (Managed Control Plane) 服务器的示例。

官方
精选