Skip to content

Conversation

RubenCerna2079
Copy link
Contributor

@RubenCerna2079 RubenCerna2079 commented Oct 3, 2025

Why make this change?

What is this change?

  • Create the read_records tool:
    • First it ensures that the MCP has the proper authorization to run the query
    • Then it creates the context with the parameters that were requested by the user
    • Lastly it calls the SqlQueryEngine in order to create and run the query and receive the results
  • The GenerateOrderByLists function inside the RequestParser.cs file was changed from private to public in order to allow the read_records tool to also use it to generate the proper context for the query.
  • Some functions inside of the SqlResponseHelper.cs file were changed to check if the query request comes from the read_records tool. This is done in order to output the correct information, right now the REST requests can also return a nextLink object which gives the API link necessary to get values in the case that not all of them were shown. We want to do something similar with the read_records tool, however we only want to return the after object which is the parameter that allows the query to know the exact place where it left from the previous query. This gets rid of unecessary information that can be found in the nextLink object.

Exceptions thrown when:

  1. Entity is empty or null.
  2. Parameters are not of the correct type.
  3. Parameters are not correctly written.
  4. Values inside orderby parameter are empty or null. (Note: orderby is an optional value as a whole, but the individual values it contains need to exist)
  5. Not having necessary permissions.

Errors:

  1. PermissionDenied - No permssions to execute.
  2. InvalidArguments - No arguments provided.
  3. InvalidArguments - Some missing arguments.
  4. EntityNotFound - Entity not defined in the configuration.
  5. UnexpectedError - Any other UnexpectedError.

How was this tested?

  • Integration Tests
  • Unit Tests
  • Manual testing via MCP Inspector

These scenarios were manually tested with the MCP Inspector, as automated tests are not yet implemented.

Valid Cases

  1. Successful Read
  • Provided valid entity and other parameters
  • Verified that the received values are the same for MCP as for REST endpoint
  1. Permission Enforcement
  • Modified role permissions and verified that access control is enforced correctly.
  1. Parameter Testing
  • Provided different valid values for the multiple optional parameters and ensured they work the same way they do with the REST endpoint.

Failure Cases

  1. Null/Empty Entity Name
  • Provided an empty string for entity
  • Received InvalidArguments error
  1. Invalid Entity Name
  • Provided string that is not found in config
  • Received InvalidArguments error
  1. Invalid Parameters
  • Provided non-existent fields for select parameter
    • Received InvalidArguments error
  • Provided invalid string for filter parameter
    • Received InvalidArguments error
  • Provided integer values less than or equal to 0 in the first parameter
    • Received InvalidArguments error
  • Provided invalid string for orderby parameter
    • Received InvalidArguments error
  • Provided invalid string for after parameter
    • Received InvalidArguments error
  1. Unauthorized Role Context
  • Removed or misconfigured role-header
  • Received PermissionDenied error

Sample Request(s)

{ Entity: Book }
{ Select: title,publisher_id }
{ First: 3 }
{ Orderby: ["publisher_id asc", "title desc"] }

@RubenCerna2079 RubenCerna2079 added this to the 1.7 milestone Oct 3, 2025
@RubenCerna2079 RubenCerna2079 self-assigned this Oct 3, 2025
@Copilot Copilot AI review requested due to automatic review settings October 3, 2025 00:27
@RubenCerna2079 RubenCerna2079 linked an issue Oct 3, 2025 that may be closed by this pull request
6 tasks
@RubenCerna2079
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 6 pipeline(s).

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements the read_records tool for the MCP (Model Context Protocol), enabling reading of entity records with parameters like select, filter, first, orderby, and after for pagination. The implementation includes proper authorization checks and handles both REST and MCP endpoint responses differently.

  • Added a new ReadRecordsTool class that implements the MCP read_records functionality
  • Modified response formatting to support both REST (nextLink) and MCP (after) pagination approaches
  • Changed GenerateOrderByLists method visibility from private to public for reuse

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
src/Azure.DataApiBuilder.Mcp/BuiltInTools/ReadRecordsTool.cs Complete implementation of the read_records tool with argument parsing, authorization, and query execution
src/Core/Resolvers/SqlResponseHelpers.cs Enhanced response formatting to support both REST nextLink and MCP after pagination patterns
src/Core/Parsers/RequestParser.cs Changed GenerateOrderByLists method from private to public for reuse
src/Core/Parsers/FilterParser.cs Removed blank line formatting change

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@RubenCerna2079
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 6 pipeline(s).

@github-project-automation github-project-automation bot moved this from Todo to Review In Progress in Data API builder Oct 7, 2025
@anushakolan
Copy link
Contributor

nit: Fix the description, Manual testing via MCP Inspecto

@RubenCerna2079
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 6 pipeline(s).

Copy link
Contributor

@souvikghosh04 souvikghosh04 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. please address the open comments. also please add a task to address the refactoring as requested in https://github.com/Azure/data-api-builder/pull/2893/files#r2411041957

@RubenCerna2079
Copy link
Contributor Author

/azp run

@RubenCerna2079
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

Copy link

Azure Pipelines successfully started running 6 pipeline(s).

Copy link
Contributor

@souvikghosh04 souvikghosh04 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@RubenCerna2079
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 6 pipeline(s).

Copy link
Contributor

@anushakolan anushakolan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I received 2 important comments from Aniruddh on the update record tool which will also apply for all other tools.

  1. We should use the SqlResponseHelper to create a response that MCP endpoint needs to avoid the duplicate serialization and deserialization. (I think this is addressed in your PR`
  2. If the ClientRoleHeaderAuthenticationMiddleware isn't invoked, the roleheader here will be empty. Please test that out.

Copy link
Contributor

@anushakolan anushakolan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requested a couple of important changes, please check that out. Rest looks good to me.

@RubenCerna2079
Copy link
Contributor Author

I received 2 important comments from Aniruddh on the update record tool which will also apply for all other tools.

  1. We should use the SqlResponseHelper to create a response that MCP endpoint needs to avoid the duplicate serialization and deserialization. (I think this is addressed in your PR`
  2. If the ClientRoleHeaderAuthenticationMiddleware isn't invoked, the roleheader here will be empty. Please test that out.
  1. You are correct, my PR already uses SqlResponseHelper you can see it under the // Execute comment.
  2. Tested to make sure that the role header isn't empty. Tests were successful.

@RubenCerna2079
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 6 pipeline(s).

@RubenCerna2079
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 6 pipeline(s).

@anushakolan
Copy link
Contributor

anushakolan commented Oct 15, 2025

I received 2 important comments from Aniruddh on the update record tool which will also apply for all other tools.

  1. We should use the SqlResponseHelper to create a response that MCP endpoint needs to avoid the duplicate serialization and deserialization. (I think this is addressed in your PR`
  2. If the ClientRoleHeaderAuthenticationMiddleware isn't invoked, the roleheader here will be empty. Please test that out.
  1. You are correct, my PR already uses SqlResponseHelper you can see it under the // Execute comment.
  2. Tested to make sure that the role header isn't empty. Tests were successful.

Nice work Ruben!! Please update the testing section in the PR description with point no. 2. Everything else LGTM.

@RubenCerna2079 RubenCerna2079 merged commit 3df5d9f into main Oct 15, 2025
11 checks passed
@RubenCerna2079 RubenCerna2079 deleted the dev/rubencerna/mcp-read-records-tool branch October 15, 2025 23:56
@github-project-automation github-project-automation bot moved this from Review In Progress to Done in Data API builder Oct 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[Enh]: Add DML tool: read_records

4 participants