Skip to content

Add support for tools output filtering #10

@lbroudoux

Description

@lbroudoux

Reshapr CustomTools (see #133) allows the redefinition of a tool input schema. However, it offers no control over the output of this tool.

So if, for example, you invoke a GraphQL APIs node that has a lot of scalar properties or a REST API where the response is a JSON tree with a lot of deep branches, you may fetch a lot of data that will sit in the client context window. Sometimes, only a subset of this data is actually helpful for a tool - especially if we leverage an existing broad API!

This enhancement proposition aims at defining a new capability for filtering a tool output response. As we're using an architecture based on converters (from JSON request to protocol-specific request, and then from protocol specific reponse to JSON response), it would be easy to filter out the response in a universal way once we finish the converter invocation, just before wrapping the response into JSON-RPC MCP standard for sending back the response to the client.

Because we're manipulating JSON, I propose to base this filtering feature on JSON Patch that is now a well-established standard. JSON Patch provides semantic operations like add, replace, remove, copy, move and test that allows precises transformation specification.

One thing that JSON Patch doesn't provide is the retain semantic: you can't specify a few branches to keep, you need to explicitly tell all the one you want to remove. I find this impractical when dealing with a small subset of a large number of branch. As a consequence, I propose to add the retain operation as an optional, pre-processing step before applying an orderes sequence of JSON Patches (as per the specification explains ordering importance).

In a nutshell, this would allow us to define this kind of filtering specification:

apiVersion: reshapr.io/v1alpha1
kind: ToolsFilters           # Is it the good name?
service:
  name: GitHub GraphQL
  version: '20250917'
filters:
  get_user_with_latest_followers:  # This applies to this tool.
    retain:
       - /userInfo       # This retains only the userInfo, removing all the other branches.
    patches:
      - op: add 
        path: /userInfo/country
        value: "France"
      - op: remove
        path: /userInfo/age
      - op: remove
        path: /userInfo/bioHTML
      - op: remove
        path: /userInfo/companyHTML
      - op: remove
        path: /userInfo/copilotEndpoints
      - op: remove
        path: /userInfo/monthlyEstimatedSponsorsIncomeInCents
     - op: replace
       path: /userInfo/city
       value: Parigne Le Polin

Additional considerations:

  • JSON Patch provides a test operation (see https://jsonpatch.com/#test) that allows defining a condition to apply following patches or stop there. I think having higher level similar construct can be useful in the cases where a tool can provide very different answers based on different inputs. In that case, we could have something like:
filters:
  get_user_with_latest_followers: 
    - test: 
        path: /userInfo/type
        value: PhysicalPerson
      retain:
        - /userInfo/person
      patches: # ...
    - test: 
        path: /userInfo/type
        value: MoralPerson
     retain:
        - /userInfo/entity
     patches: # ...
  • Where Prompts, Resources, and CustomTools directly apply and transform an imported reshapr Service. I think that ToolsFilters may be much more related to security or optimisation issues and thus much more related to a Configuration Plan. We could also imagine having the same Service and custom tools deployed multiple times on different gateways using different filters depending on the type of partners that will access the MCP Endpoint. As a consequence, it could be useful to name ToolsFilters and then explicitly reference the name of a filter set to apply within a ConfigurationPlan. That would open the need of a new name attribute somewhere in the spec.

Comments are welcome!

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions