Pyloros is a headless Java 21 / Vert.x agent capability gateway that exposes local and remote MCP servers behind one MCP endpoint.
Canonical public endpoint:
https://current-car.com/pyloros
Legacy compatibility alias:
https://current-car.com/sse(deprecated)
- loads MCP upstreams from a Copilot-style
mcp.json - aggregates tools from multiple upstreams into one MCP catalog
- formats external MCP tool names as
provider<separator>tool(default separator__) - routes
tools/callby exact tool name through a map-backed catalog - keeps optional upstreams non-fatal so Pyloros can still start with native tools only
Default external MCP tool names use __:
intellij__get_project_modulesgithub__get_meintellij-index__ide_index_status
Override priority for separator:
--tool-name-separator=...-Dmcp.tool-name-separator=...- default
__
Example compatibility/test mode:
--tool-name-separator=/(or-Dmcp.tool-name-separator=/)- yields names like
intellij/get_project_modules /mode is intended for legacy test compatibility only and is not recommended for connector-facing tool calls; use the default__separator for normal operation
Important:
- external names are still routed by exact string match only
- internal routing address remains
ToolAddress(providerId, upstreamToolName) - no split/prefix/path-fragment routing is used
Native tools may intentionally keep their own names, for example:
pyloros__ping
| Provider | Transport |
|---|---|
intellij |
SSE |
github |
Streamable HTTP |
intellij-index |
Streamable HTTP |
pyloros |
native/local |
Pyloros reads the same Copilot-style mcp.json that Copilot IntelliJ uses.
Default discovery order:
--mcp-config=C:\path\to\mcp.json-Dmcp.config=C:\path\to\mcp.json%LOCALAPPDATA%\github-copilot\intellij\mcp.json./mcp.json./data/mcp.json
On Angelo's machine the default path is:
C:\Users\angel\AppData\Local\github-copilot\intellij\mcp.json
If no file is found, Pyloros starts with native tools only and logs:
[MCP-CONFIG] no mcp.json found; starting without external MCP upstreams
{
"servers": {
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"requestInit": {
"headers": {
"Authorization": "Bearer <TOKEN>"
}
}
},
"intellij": {
"type": "sse",
"url": "http://127.0.0.1:64343/sse"
},
"intellij-index": {
"url": "http://127.0.0.1:29170/index-mcp/streamable-http"
}
}
}Rules:
servers.<key>is theproviderIdtype=sse-> SSE upstream clienttype=http-> Streamable HTTP upstream client- missing
typewithhttp://orhttps://URL -> Streamable HTTP upstream client requestInit.headersis forwarded to the upstream- header values are never logged
- if a server exists in
mcp.json, it is considered configured - if a server is missing from
mcp.json, it does not exist for Pyloros - unsupported server types such as stdio are ignored for Pyloros HTTP aggregation
Do not commit secrets.
Important:
- do not hardcode tokens into repository files
- keep real credentials in the local Copilot
mcp.jsonor other local-only config - Pyloros will forward configured headers but does not log header values
- Java 21
- Gradle wrapper included
Set-Location 'C:\Projects\pyloros'
$env:JAVA_HOME='C:\Program Files\Zulu\zulu-21'
$env:Path="$env:JAVA_HOME\bin;$env:Path"
.\gradlew.bat clean build --no-daemon
.\gradlew.bat :pyloros-app:shadowJar --no-daemonFat jar output:
pyloros-app\build\libs\pyloros.jar
Wichtig: Vor jedem Start muessen die OAuth-Umgebungsvariablen gesetzt sein. Ohne sie schlaegt die ChatGPT-Verbindung mit
401 invalid_clientfehl. Jedes neue PowerShell-Fenster verliert die Variablen — sie muessen jedes Mal neu gesetzt werden.
Set-Location 'C:\Projects\pyloros'
$env:OAUTH_CLIENT_ID='angel'
$env:OAUTH_CLIENT_SECRET='<das gleiche Secret wie in deiner ChatGPT-Connector-Konfiguration>'
& "C:\Program Files\Zulu\zulu-21\bin\java.exe" -jar .\pyloros-app\build\libs\pyloros.jarSet-Location 'C:\Projects\pyloros'
$env:JAVA_HOME='C:\Program Files\Zulu\zulu-21'
$env:Path="$env:JAVA_HOME\bin;$env:Path"
$env:OAUTH_CLIENT_ID='angel'
$env:OAUTH_CLIENT_SECRET='<das gleiche Secret wie in deiner ChatGPT-Connector-Konfiguration>'
& "$env:JAVA_HOME\bin\java.exe" -jar .\pyloros-app\build\libs\pyloros.jarSet-Location 'C:\Projects\pyloros'
$env:OAUTH_CLIENT_ID='angel'
$env:OAUTH_CLIENT_SECRET='<das gleiche Secret wie in deiner ChatGPT-Connector-Konfiguration>'
& "C:\Program Files\Zulu\zulu-21\bin\java.exe" -jar .\pyloros-app\build\libs\pyloros.jar --mcp-config=C:\pfad\zu\mcp.json| Variable | Beschreibung |
|---|---|
OAUTH_CLIENT_ID |
Dein OAuth-Client-Identifier (z. B. angel) |
OAUTH_CLIENT_SECRET |
Das Secret aus deiner ChatGPT-Connector-Konfiguration |
Diese Variablen ueberschreiben die Defaults aus application.properties.
Sind sie nicht gesetzt, verwendet Pyloros die Werte aus der Properties-Datei —
die aber nicht mit dem ChatGPT-Connector uebereinstimmen muessen.
Invoke-WebRequest http://127.0.0.1:8081/health | Select-Object -ExpandProperty ContentExpected:
{"status":"ok"}When mcp.json changes or Pyloros restarts:
- restart Pyloros
- refresh or update the ChatGPT / Copilot connector view
- call
tools/listagain - use the refreshed exact names returned by Pyloros (
__by default)
The local smoke test verifies only the local Pyloros router and local MCP endpoint behavior.
It checks exact tool names such as:
pyloros__pingintellij__get_project_modulesgithub__get_meintellij-index__ide_index_status
Run:
Set-Location 'C:\Projects\pyloros'
$env:JAVA_HOME='C:\Program Files\Zulu\zulu-21'
$env:Path="$env:JAVA_HOME\bin;$env:Path"
$env:PYLOROS_SMOKE_ACCESS_TOKEN='<pyloros access token>'
$env:PYLOROS_SMOKE_MCP_URL='http://127.0.0.1:8081/pyloros'
.\gradlew.bat :pyloros-app:runMcpAggregationSmokeTestFor legacy compatibility verification, override the smoke URL with http://127.0.0.1:8081/sse.
This is separate from the local smoke test.
A real ChatGPT / connector invocation test validates the external client layer as well. The local smoke test does not prove that the ChatGPT connector or api_tool layer is correct.
pyloros-server: core MCP gateway and provider/tool aggregation logicpyloros-app: runtime bootstrap for the Pyloros gateway processpyloros-manager-agent: separate Java 21 Gradleapplicationbootstrap module (distribution/start script), independent from core server/app runtime- stdio safety: module-local logging is routed to
stderrso ACP JSON-RPCstdoutremains free
- stdio safety: module-local logging is routed to
PylorosApplication: bootstrap and wiring onlyProviderRegistry: deterministic provider registration byproviderIdToolCatalog: immutable map-backed snapshotsToolRouter: exact-name routing by external MCP tool nameOAuthService: OAuth token handling for the public Pyloros endpoint- external upstreams are discovered from
mcp.json
pyloros-manager-agent is currently packaged as a Gradle application distribution/start script (not a fat JAR):
./gradlew :pyloros-manager-agent:installDist
./pyloros-manager-agent/build/install/pyloros-manager-agent/bin/pyloros-manager-agent- see
docs/plugin-development.md