Skip to content

Conversation

@souvikghosh04
Copy link
Contributor

@souvikghosh04 souvikghosh04 commented Nov 10, 2025

Why make this change?

Cherry pick MCP fixes and improvements for 1.7.

What is this change?

The PR contains cherry picks from main branch.

Following commits from main are taken-

  • Improve MCP tool descriptions for ChatGPT compatibility 21dde31
  • Bug fix for setting dml tools based on bool value as set in config 7228e60
  • Expand ALL permissions in MCP describe_entities to explicit operations 3b48c49
  • User provided dml-tools property serialization 3adf04f
  • Honoring incoming request role in determining allowed permissions for describe-entities MCP tool 7b31e9a

How was this tested?

  • Integration Tests
  • Unit Tests

Copilot AI and others added 5 commits November 10, 2025 10:03
MCP `list_tools` descriptions were insufficiently clear for ChatGPT to
understand tool usage patterns and workflows, while Claude handled them
adequately.

## Changes

Updated descriptions and input schemas for all 6 MCP tools:

- **describe_entities**: Added "ALWAYS CALL FIRST" directive and
clarified permissions structure (`'ALL'` expands by type: data→CREATE,
READ, UPDATE, DELETE). Expanded `nameOnly` and `entities` parameter
descriptions to include detailed usage guidance:
- `nameOnly`: Explains when to use it (for discovery with many
entities), the two-call strategy (first with `nameOnly=true`, then with
specific entities), and warns that it doesn't provide enough detail for
CRUD/EXECUTE operations
- `entities`: Clarifies its purpose for targeted metadata retrieval and
explicitly warns against combining it with `nameOnly=true`
- **CRUD tools** (create_record, read_records, update_record,
delete_record): Added explicit STEP 1→STEP 2 workflow (describe_entities
first, then call with matching permissions/fields)
- **execute_entity**: Added workflow guidance and clarified use case
(actions/computed results)
- **All tools**: Condensed parameter descriptions (e.g.,
"Comma-separated field names" vs. "A comma-separated list of field names
to include in the response. If omitted, all fields are returned.
Optional.")

## Example

Before:
```csharp
Description = "Creates a new record in the specified entity."
```

After:
```csharp
Description = "STEP 1: describe_entities -> find entities with CREATE permission and their fields. STEP 2: call this tool with matching field names and values."
```

All changes are metadata-only; no functional code modified.

<!-- START COPILOT CODING AGENT SUFFIX -->



<details>

<summary>Original prompt</summary>


----

*This section details on the original issue you should resolve*

<issue_title>[BUG]: MCP `list_tools` need more comprehensive
descriptions.</issue_title>
<issue_description>## What?

Our tools have descriptions already. They need better to help models. 

> Claude works but ChatGPT struggles to understand with our current
descriptions.

## New descriptions

```json
{
  "tools": [
    {
      "name": "describe_entities",
      "description": "Lists all entities and metadata. ALWAYS CALL FIRST. Each entity includes: name, type, fields, parameters, and permissions. The permissions array defines which tools are allowed. 'ALL' expands by type: data->CREATE, READ, UPDATE, DELETE.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "nameOnly": {
            "type": "boolean",
            "description": "True: names and summaries only. False (default): full metadata."
          },
          "entities": {
            "type": "array",
            "items": { "type": "string" },
            "description": "Optional: specific entity names. Omit for all."
          }
        }
      }
    },
    {
      "name": "create_record",
      "description": "STEP 1: describe_entities -> find entities with CREATE permission and their fields. STEP 2: call this tool with matching field names and values.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "entity": {
            "type": "string",
            "description": "Entity name with CREATE permission."
          },
          "data": {
            "type": "object",
            "description": "Required fields and values for the new record."
          }
        },
        "required": ["entity", "data"]
      }
    },
    {
      "name": "read_records",
      "description": "STEP 1: describe_entities -> find entities with READ permission and their fields. STEP 2: call this tool with select, filter, sort, or pagination options.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "entity": {
            "type": "string",
            "description": "Entity name with READ permission."
          },
          "select": {
            "type": "string",
            "description": "Comma-separated field names."
          },
          "filter": {
            "type": "string",
            "description": "OData expression: eq, ne, gt, ge, lt, le, and, or, not."
          },
          "orderby": {
            "type": "array",
            "items": { "type": "string" },
            "description": "Sort fields and directions, e.g., ['name asc', 'year desc']."
          },
          "first": {
            "type": "integer",
            "description": "Max number of records (page size)."
          },
          "after": {
            "type": "string",
            "description": "Cursor token for next page."
          }
        },
        "required": ["entity"]
      }
    },
    {
      "name": "update_record",
      "description": "STEP 1: describe_entities -> find entities with UPDATE permission and their key fields. STEP 2: call this tool with keys and new field values.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "entity": {
            "type": "string",
            "description": "Entity name with UPDATE permission."
          },
          "keys": {
            "type": "object",
            "description": "Primary or composite keys identifying the record."
          },
          "fields": {
            "type": "object",
            "description": "Fields and their new values."
          }
        },
        "required": ["entity", "keys", "fields"]
      }
    },
    {
      "name": "delete_record",
      "description": "STEP 1: describe_entities -> find entities with DELETE permission and their key fields. STEP 2: call this tool with full key values.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "entity": {
            "type": "string",
            "description": "Entity name with DELETE permission."
          },
          "keys": {
            "type": "object",
            "description": "All key fields identifying the record."
          }
        },
        "required": ["entity", "keys"]
      }
    },
    {
      "name": "execute_entity",
      "description": "STEP 1: describe_entities -> find entities with EXECUTE permission and their parameters. STEP 2: call this tool with matching parameter values. Used for entities that perform actions or return computed results.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "entity": {
            "type": "string",
            "description": "Entity name with EXECUTE permission."
          },
          "parameters": {
            "type": "object",
            "description": "Optional parameter names and values."
          }
        },
        "required": ["entity"]
      }
    }
  ]
}
```


</issue_description>

<agent_instruction...

</details>

- Fixes #2936

<!-- START COPILOT CODING AGENT TIPS -->
---

✨ Let Copilot coding agent [set things up for
you](https://github.com/Azure/data-api-builder/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: JerryNixon <1749983+JerryNixon@users.noreply.github.com>
Co-authored-by: Aniruddh Munde <anmunde@microsoft.com>
…2927)

## Why make this change?

Bug fix for setting dml tools correctly.

Closes on - #2942 

## What is this change?

This fix addresses the inconsistency in config where `dml-tools` can be
either set as bool or a dictionary object containing individual tool
names and their bool values. Without this fix, we need to individually
set each `dml-tools` to true currently.

With this change, we will have the following scenarios-

- set `dml-tools` to `true` will enable all dml tools (default is true)
Sample- ```"dml-tools": true```

- set `dml-tools` to `false` will disable all dml tools
Sample-```"dml-tools": false```

- individual tool names can be specified as dictionary object for
`dml-tools` to turn them on (default is true if a tool is not
specified).


## How was this tested?

- [ ] Integration Tests
- [ ] Unit Tests
- [x] Manual testing using various combinations and scenarios

**Scenario 1:** Enable all tools using a single boolean value

`"dml-tools": true`

Note: default is true so even if `dml-tools` unspecified it will default
to true.

**Scenario 2:** Disable `execute-entities` only and keep other tools
enabled as default.

```
      "dml-tools": {
        "execute-entities":  false
      }
```

**Scenario 3:** Use full list of tools and enable or disable them

```
      "dml-tools": {
        "execute-entity": true,
        "delete-record": false,
        "update-record": false,
        "read-records": false,
        "describe-entities": true
      }
```

---------

Co-authored-by: Aniruddh Munde <anmunde@microsoft.com>
#2951)

The MCP `describe_entities` tool returns `"ALL"` for wildcard
permissions, which confuses LLM consumers that need explicit operation
lists.

### Changes

Modified `DescribeEntitiesTool.BuildPermissionsInfo()` to expand
`EntityActionOperation.All`:
- **Tables/Views**: Expands to `["CREATE", "DELETE", "READ", "UPDATE"]`
via `EntityAction.ValidPermissionOperations`
- **Stored Procedures**: Expands to `["EXECUTE"]` via
`EntityAction.ValidStoredProcedurePermissionOperations`

### Example

**Before:**
```json
{
  "name": "Todo",
  "permissions": ["ALL"]
}
```

**After:**
```json
{
  "name": "Todo",
  "permissions": ["CREATE", "DELETE", "READ", "UPDATE"]
}
```

<!-- START COPILOT CODING AGENT SUFFIX -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>[Bug]: MCP `describe_entities` permissions value `ALL`
needs to be expanded.</issue_title>
> <issue_description>## What? 
> 
> Models are confused by `ALL`.
> 
> ```json
> {
>   "entities": [
>     {
>       "name": "Todo",
>       "description": "This table contains the list of todo items.",
>       "fields": [ ],
>       "permissions": [
>         "ALL" // this is the problem
>       ]
>     }
>   ],
>   "count": 1,
>   "mode": "full",
>   "status": "success"
> }
> ```
> 
> ## Solution
> 
> When table/view.
> 
> ```json
> {
>   "permissions: [
>     "CREATE",
>     "DELETE",
>     "READ",
>     "UPDATE"
>   ]
> }
> ```
> 
> When stored procedure.
> 
> ```json
> {
>   "permissions: [
>     "EXECUTE"
>   ]
> }
> ```
> </issue_description>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> </comments>
> 


</details>

- Fixes #2935

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: JerryNixon <1749983+JerryNixon@users.noreply.github.com>
## Why make this change?

This PR addresses the issue where with serialization of `dml-tools`
property for user-provided (non-default) values. This is a follow up to
the fix made for the functionality of `dml-tools` property-
#2927

## What is this change?

If `dml-tools` is not configured, this property should not be
serialized. Serialization should only be done for user provided
configuration. So, any value explicitly set or configured by the user
for `dml-tools` will be serialized.
`dml-tools` can either have either of the below values-
- A boolean value- true or false. This is a global value to enable or
disable all DML tools and `UserProvidedAllTools` is written in JSON
- A dictionary object of individual tool name and boolean values. This
contains individual tool specific values and only the specified tools
will be taken for JSON writing and unspecified tool names will be
ignored.

## How was this tested?

- [x] Integration Tests
- [x] Unit Tests
- [x] Manual Tests

Sample scenarios for testing-

**Scenario 1:** Enable all tools using a single boolean value

`"dml-tools": true`

Note: default is true so even if `dml-tools` unspecified it will default
to true.

**Scenario 2:** Disable `execute-entities` only and keep other tools
enabled as default.

```
      "dml-tools": {
        "execute-entities":  false
      }
```

**Scenario 3:** Use full list of tools and enable or disable them

```
      "dml-tools": {
        "execute-entity": true,
        "delete-record": false,
        "update-record": false,
        "read-records": false,
        "describe-entities": true
      }
```

---------

Co-authored-by: Aniruddh Munde <anmunde@microsoft.com>
… describe-entities MCP tool (#2956)

## Why make this change?

- Addresses follow ups to PR #2900
The `describe_entities` tool response format needed improvements to
better align with MCP specifications and provide more accurate,
user-scoped information. Key issues included non-specification compliant
response fields, overly broad permission reporting across all roles, and
inconsistent entity/field naming conventions that didn't prioritize
user-friendly aliases.


## What is this change?

- **Removed non-spec fields from response**: Eliminated `mode` and
`filter` fields that were not part of the MCP specification
- **Scoped permissions to current user's role**: Modified permissions
logic to only return permissions available to the requesting user's role
instead of all permissions across all roles
- **Implemented entity alias support**: Updated entity name resolution
to prefer GraphQL singular names (aliases) over configuration names,
falling back to entity name only when alias is absent
- **Fixed parameter metadata format**: Changed parameter default value
key from `@default` to `default` in JSON response
- **Enhanced field name resolution**: Updated field metadata to use
field aliases when available, falling back to field names when aliases
are absent
- **Added proper authorization context**: Integrated HTTP context and
authorization resolver to determine current user's role for permission
filtering

## How was this tested?

- [x] Manual Tests

## Sample Request(s)

```
POST http://localhost:5000/mcp

{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "describe_entities"
  },
  "id": 1
}
```

```
POST http://localhost:5000/mcp

{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "describe_entities",
    "arguments": {
      "nameOnly": true
    }
  },
  "id": 2
}
```

```
POST http://localhost:5000/mcp

{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "describe_entities",
    "arguments": {
      "entities": ["Book", "Publisher"]
    }
  },
  "id": 1
}
```
@souvikghosh04
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 6 pipeline(s).

@souvikghosh04 souvikghosh04 marked this pull request as ready for review November 10, 2025 05:58
Copilot AI review requested due to automatic review settings November 10, 2025 05:58
@souvikghosh04 souvikghosh04 enabled auto-merge (squash) November 10, 2025 05:59
Copy link
Contributor

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 enhances the MCP (Model Context Protocol) configuration and tool descriptions by adding granular DML tool configuration support and improving role-based permission filtering.

Key changes include:

  • Addition of DmlToolsConfig structure with individual tool enable/disable flags and user-provided tracking
  • Enhanced tool descriptions with step-by-step usage instructions for AI models
  • Role-based permission filtering in describe_entities tool to show only permissions relevant to the current user's role
  • Default initialization of DmlTools configuration when not specified

Reviewed Changes

Copilot reviewed 50 out of 51 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/Config/ObjectModel/DmlToolsConfig.cs Refactored constructor to handle default values and track user-provided configuration flags; renamed UserProvidedAllToolsEnabled to UserProvidedAllTools
src/Config/ObjectModel/McpRuntimeOptions.cs Changed Enabled parameter to nullable and added default initialization of DmlTools config when null
src/Config/Converters/DmlToolsConfigConverter.cs Updated to reference renamed UserProvidedAllTools property and improved write logic
src/Azure.DataApiBuilder.Mcp/BuiltInTools/DescribeEntitiesTool.cs Added role-based permission filtering, expanded GraphQL aliases support, improved parameter metadata handling
src/Azure.DataApiBuilder.Mcp/BuiltInTools/CreateRecordTool.cs Updated tool description with step-by-step instructions for AI models
src/Azure.DataApiBuilder.Mcp/BuiltInTools/ReadRecordsTool.cs Updated tool description and parameter ordering, simplified field descriptions
src/Azure.DataApiBuilder.Mcp/BuiltInTools/UpdateRecordTool.cs Updated tool description with step-by-step instructions for AI models
src/Azure.DataApiBuilder.Mcp/BuiltInTools/DeleteRecordTool.cs Updated tool description with step-by-step instructions for AI models
src/Azure.DataApiBuilder.Mcp/BuiltInTools/ExecuteEntityTool.cs Updated tool description with step-by-step instructions for AI models
src/Cli.Tests/ConfigGeneratorTests.cs Fixed JSON formatting to add comma after mcp path property
Test snapshot files (various) Updated to reflect new DmlTools section with default configuration values

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@souvikghosh04 souvikghosh04 self-assigned this Nov 10, 2025
@souvikghosh04 souvikghosh04 added the 🍒Cherrypick Cherry-picking another commit/PR label Nov 10, 2025
@souvikghosh04 souvikghosh04 added this to the Nov 2025 milestone Nov 10, 2025
@souvikghosh04 souvikghosh04 moved this from Todo to Review In Progress in Data API builder Nov 10, 2025
@souvikghosh04 souvikghosh04 linked an issue Nov 10, 2025 that may be closed by this pull request
@souvikghosh04 souvikghosh04 merged commit c7927fa into release/1.7 Nov 10, 2025
17 checks passed
@souvikghosh04 souvikghosh04 deleted the cherry-pick/1.7-fixes-v2 branch November 10, 2025 19:41
@github-project-automation github-project-automation bot moved this from Review In Progress to Done in Data API builder Nov 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🍒Cherrypick Cherry-picking another commit/PR

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Cherry pick MCP improvements and fixes

4 participants