Add OpenAI-compatible /v1/tools REST endpoints alongside MCP#4
Merged
Conversation
- New tool_registry.py: module-level dict shared between server.py and
frontend/app.py; populated at startup, read at request time.
- server.py: one-line addition in register_tool() to mirror every MCP
tool registration into tool_registry. No other changes.
- frontend/app.py: two new endpoints on port 8889 (existing UI port):
GET /v1/tools — tool list in OpenAI function-calling schema
POST /v1/tools/{tool_name}/invoke — invoke with {"arguments": {...}}
Result normalisation handles str / list / dict-with-content / plain-dict.
Handler exceptions surface as is_error:true (HTTP 200) so LLMs see them.
- tests/test_server.py: add TestToolRegistry (register, get, get_all,
overwrite, copy isolation, clear).
- tests/test_openai_api.py: 25 new tests covering GET /v1/tools schema
shape, parameter passthrough, all result-normalisation branches,
404 on unknown tool, error handling, and empty-body tolerance.
- tests/test_mcp_client.sh: add MODE selector (1=MCP, 2=OpenAI) after
Ollama model selection. MCP path unchanged; OpenAI path uses
GET /v1/tools for listing and POST /v1/tools/{name}/invoke for calls.
File-listing step (mcpproxy__listfiles/getfile) branches on mode too.
MODE env var skips the menu (mirrors OLLAMA_MODEL pattern).
All 232 tests pass (214 pre-existing + 18 new).
https://claude.ai/code/session_01V9SNVHv8uhS8pejXW9Dt7m
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds OpenAI-compatible REST endpoints (
GET /v1/toolsandPOST /v1/tools/{name}/invoke) to the frontend UI server, allowing tools to be listed and invoked without speaking the MCP protocol. The MCP endpoint and all existing functionality remain completely unchanged.Key Changes
New
tool_registry.pymodule: A shared in-process tool store that bothserver.pyandfrontend/app.pycan access.server.pypopulates it during tool registration;frontend/app.pyreads from it to serve the OpenAI endpoints.OpenAI-compatible endpoints in
frontend/app.py:GET /v1/tools— returns all registered tools in OpenAI function-calling schema formatPOST /v1/tools/{tool_name}/invoke— invokes a tool with{"arguments": {...}}and returns a normalizedtool_resultresponsecontentkey pass through; other dicts are JSON-serialized; lists are used directlyis_error: trueso LLM callers see errors as tool resultsUpdated
server.py: Callstool_registry.register()insideregister_tool()for every enabled tool, populating the shared registry.Enhanced
tests/test_mcp_client.sh:/mcpcalls or REST/v1/toolscalls based on selected modemcpproxy__listfiles/mcpproxy__getfile) works with both protocolsNew test file
tests/test_openai_api.py: Comprehensive test suite for the OpenAI endpoints covering:New tests in
tests/test_server.py: Unit tests for thetool_registrymodule (register, get, get_all, clear, overwrite behavior).Implementation Details
server.pyandfrontend/app.pyrun in the same Python process.ctx=Noneto the dynamic_tool callable, which is safe for tools that don't use MCP context features.MODE=1(MCP) andMODE=2(OpenAI) environment variable overrides to skip the interactive mode menu.https://claude.ai/code/session_01V9SNVHv8uhS8pejXW9Dt7m