Self-hosted MCP gateway: one endpoint per client, upstream OAuth that does not go stale
Junctio is an MCP gateway with 19 tools spanning server management, OAuth, and test fixtures. Tool naming follows verb_noun conventions well (list_servers, create_server, delete_server). Descriptions are present and substantive (avg ~120 chars), explaining WHAT each tool does and WHEN to use it. Input schemas are complete with types and descriptions for all parameters. However, output schemas are not documented, callers cannot see what fields to expect from responses. Error handling is minimal; tools lack recovery guidance. Test fixture tools (echo, add, whoami) are trivial and dilute the quality signal. No tool annotations (readOnlyHint/destructiveHint) despite clear risk levels being assigned. Composition is strong, tools chain well (list_servers → get_server → update_server). Security-sensitive tools (delete_server, disconnect_server_oauth) lack explicit permission checks in visible code.
Adds two numbers
Add an upstream server. For stdio pick a runtime and pass every argument separately, in order: npx wants -y and the package name. For a remote server set transport to http with its streamable http url, or sse with the stream url of a legacy HTTP+SSE server, plus authMode header with an Authorization header, or oauth to run the client flow later. Nothing is added to the arguments behind your back.
Remove a server, stop its process and drop it from every namespace. This cannot be undone.
Delete the stored access and refresh tokens of a server. It will need a fresh login.
Echoes the provided message
One upstream server in full, including its arguments and masked headers.
Output schemas not documented. Tools return responses but callers cannot see field names, types, or structure. LLMs cannot plan downstream tool calls or extract required data.
Tool annotations missing. Risk levels (READ_ONLY, WRITE, DESTRUCTIVE) are assigned but not exposed via readOnlyHint/destructiveHint/idempotentHint. LLMs cannot distinguish safe from dangerous operations.
Error handling lacks recovery guidance. Tools do not document what errors can occur, whether they are retryable, or what the LLM should do next. E.g., 'server not found' should suggest list_servers().
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 64 | 2026-07-28+ | v2 |
The tail of what a stdio server wrote to stdout and stderr, newest last.
The tools, resources and prompts of one upstream, as the gateway last saw them.
Every upstream server the gateway knows, with its transport, status and oauth state.
Show the exact argv a stdio server would run, without saving anything.
Force a token refresh for an oauth server instead of waiting for the scheduler.
Clear the backoff of a server that failed too often, without restarting it.
Stop the server, clear its failure count and connect again.
Connect to a server now instead of waiting for the first call.
Begin the oauth client flow for a server with authMode oauth. Answers with an authorization url that a human has to open in a browser; the gateway stores the tokens when they come back.
Close the connection and stop the child process. The server stays configured and enabled.
Connect, negotiate the protocol and count the tools. Answers with the failure instead of throwing when the server does not come up.
Change an existing server. Only the fields you pass are touched. Editing anything that affects the connection stops the running process so the next call reconnects.
Returns the value of the MOCK_TOKEN environment variable
Test fixture tools (echo, add, whoami) are trivial and dilute quality. They belong in a separate test server, not the production gateway. Removes signal from the 19-tool count.
Destructive operations lack confirmation step. delete_server and disconnect_server_oauth are irreversible but have no dry-run or confirmation mechanism. Agents can accidentally destroy configuration.