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 = {}
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions that annotations provide rich type information and that results generally include JSON-encoded EmbeddedResource results, which adds some behavioral context. However, it doesn't disclose important operational details like error handling, performance characteristics, authentication requirements, or rate limits for a proxy tool that interacts with multiple servers.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and appropriately sized. It starts with a clear purpose statement, then provides a bulleted list of three unified functions, and ends with important behavioral context about annotations and results. Every sentence earns its place, with no redundant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex proxy tool with 7 parameters, no annotations, and no output schema, the description provides adequate but incomplete coverage. It explains the tool's role and general behavior but lacks specifics about error conditions, performance expectations, and detailed output format. The mention of JSON-encoded EmbeddedResource results helps, but more operational context would be beneficial for such a central tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema description coverage, the schema already documents all 7 parameters thoroughly. The description doesn't add any parameter-specific information beyond what's in the schema. It mentions the three actions (list, info, call) and three capability types (tool, resource, prompt), but these are already documented in the schema's enum fields. Baseline 3 is appropriate when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose as a 'unified interface' for three specific actions (listing, getting info, and calling) across mounted MCP servers. It uses specific verbs and resources, and distinguishes itself from sibling tools by being the main proxy tool for dynamic access rather than server management functions like the 'magg_' siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use this tool - for dynamic access to mounted MCP servers. It doesn't explicitly state when NOT to use it or name specific alternatives, but the context strongly implies this is for interacting with capabilities across servers rather than managing the servers themselves (which the sibling tools handle).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

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