Skip to main content
Glama

proxy

Proxy tool enables dynamic access to MCP servers by listing, retrieving detailed info, or calling tools, resources, and prompts. Provides a unified interface with JSON-encoded results for client interpretation.

Instructions

Main proxy tool for dynamic access to mounted MCP servers.

This tool provides a unified interface for:

  • Listing available tools, resources, or prompts across servers

  • Getting detailed info about specific capabilities

  • Calling tools, reading resources, or getting prompts

Annotations are used to provide rich type information for results, which can generally be expected to ultimately include JSON-encoded EmbeddedResource results that can be interpreted by the client.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYesAction to perform: list, info, or call.
argsNoArguments for a 'call' action (call tool, read resource, or get prompt). Can be a dict or JSON string.
filter_serverNoFilter results by server name prefix (for 'list' action only)
limitNoMaximum number of items to return (for 'list' action only). Default: 100
offsetNoNumber of items to skip (for 'list' action only). Default: 0
pathNoName or URI of the specific tool/resource/prompt (with FastMCP prefixing). Not allowed for 'list' and 'info' actions.
typeYesType of MCP capability to interact with: tool, resource, or prompt.

Implementation Reference

  • The core handler function for the 'proxy' tool. It validates inputs and dispatches to _proxy_list, _proxy_info, or _proxy_call based on the action, using the backend client to interact with proxied MCP capabilities.
    async def _proxy_tool(
        self,
        action: Annotated[LiteralProxyAction, Field(
            description="Action to perform: list, info, or call."
        )],
        a_type: Annotated[LiteralProxyType, Field(
            description="Type of MCP capability to interact with: tool, resource, or prompt.",
            alias="type"
        )],
        args: Annotated[dict[str, Any] | str | None, Field(
            description="Arguments for a 'call' action (call tool, read resource, or get prompt). Can be a dict or JSON string."
        )] = None,
        path: Annotated[str | None, Field(
            description="Name or URI of the specific tool/resource/prompt (with FastMCP prefixing).\n"
                        "Not allowed for 'list' and 'info' actions.",
            # validation_alias=AliasChoices("name", "uri"),
        )] = None,
        limit: Annotated[int | None, Field(
            description="Maximum number of items to return (for 'list' action only). Default: 100",
            ge=1,
            le=1000
        )] = None,
        offset: Annotated[int | None, Field(
            description="Number of items to skip (for 'list' action only). Default: 0",
            ge=0
        )] = None,
        filter_server: Annotated[str | None, Field(
            description="Filter results by server name prefix (for 'list' action only)"
        )] = None,
    ) -> Any:
        """Main proxy tool for dynamic access to mounted MCP servers.
    
        This tool provides a unified interface for:
        - Listing available tools, resources, or prompts across servers
        - Getting detailed info about specific capabilities
        - Calling tools, reading resources, or getting prompts
    
        Annotations are used to provide rich type information for results,
        which can generally be expected to ultimately include JSON-encoded
        EmbeddedResource results that can be interpreted by the client.
        """
        self.validate_operation(action=action, a_type=a_type)
    
        if action in frozenset({"info", "call"}) and not path:
            raise ValueError(
                f"Parameter 'path' is required for action {action!r}"
            )
    
        if action in frozenset({"list", "info"}) and args:
            raise ValueError(
                f"Parameter 'args' should not be provided for action {action!r}"
            )
    
        if action == "list" and path:
            raise ValueError(
                "Parameter 'path' should not be provided for action 'list'"
            )
    
        if action != "list" and (limit is not None or offset is not None or filter_server is not None):
            raise ValueError(
                "Parameters 'limit', 'offset', and 'filter_server' are only allowed for 'list' action"
            )
    
        if action == "list":
            result, result_type = await self._proxy_list(a_type)
    
            if filter_server and result:
                result = [item for item in result if hasattr(item, 'name') and item.name.startswith(filter_server)]
    
            total_count = len(result) if result else 0
            if result and (limit or offset):
                offset_val = offset or 0
                limit_val = limit or 100
                result = result[offset_val:offset_val + limit_val]
    
            if result:
                result = embed_python_object_list_in_resource(
                    typ=result_type,
                    obj=result,
                    uri=f"{self.PROXY_TOOL_NAME}:{action}/{a_type}",
                    proxyAction=action,
                    proxyType=a_type,
                    totalCount=total_count,
                    offset=offset or 0,
                    limit=limit or 100,
                )
    
        elif action == "info":
            result = await self._proxy_info(a_type, path)
    
            if result:
                result = embed_python_object_in_resource(
                    obj=result,
                    uri=f"{self.PROXY_TOOL_NAME}:{action}/{a_type}/{path}",
                    proxyAction=action,
                    proxyType=a_type,
                    proxyPath=path,
                )
    
        elif action == "call":
            result = await self._proxy_call(a_type, path, json_to_dict(args))
        else:
            raise ValueError(
                f"Unknown action: {action!r}. Supported actions are 'list', 'info', and 'call'."
            )
    
        return result
  • Registers the 'proxy' tool on the FastMCP server by creating a FunctionTool from the _proxy_tool handler with name PROXY_TOOL_NAME ("proxy") and adding it via add_tool.
    def _register_proxy_tool(self):
        tool = FunctionTool.from_function(
            self._proxy_tool,
            name=self.PROXY_TOOL_NAME,
            serializer=self._tool_serializer,
        )
    
        self.add_tool(tool)
  • Pydantic Literal type definitions for the 'type' and 'action' parameters in the proxy tool schema.
    LiteralProxyType = Literal["tool", "resource", "prompt"]
    LiteralProxyAction = Literal["list", "info", "call"]
  • Defines the tool name constant PROXY_TOOL_NAME = "proxy" used in registration.
    PROXY_TOOL_NAME: ClassVar[str] = "proxy"
  • Instantiates the ProxyFastMCP server instance, which via ProxyMCP mixin __init__ calls _register_proxy_tool to register the proxy tool.
    self.mcp = ProxyFastMCP(
        name=self.self_prefix,
        instructions=MAGG_INSTRUCTIONS.format(self_prefix=self.self_prefix),
        auth=auth_provider
    )
    self.mounted_servers = {}

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sitbon/magg'

If you have feedback or need assistance with the MCP directory API, please join our Discord server