web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

News and Announcements icon
Community site session details

Community site session details

Session Id :
Power Platform Community / Forums / Copilot Studio / missing or improperly ...
Copilot Studio
Suggested Answer

missing or improperly passed paramter after one tool to another in C#

(1) ShareShare
ReportReport
Posted on by 6

I am developing MCP tool in C# Asp.Net Core.

The LoginTool works correctly and returns a sessionId (see Image 1).

When calling PaymentTool, the sessionId is required (see Image 2), but it doesn’t appear to be passed properly, resulting in an error or incomplete workflow.

It works in Studio, but not in mcp-streamable mode within Copilot Studio.

I also added the following instruction to Copilot:

When you use the LoginTool, save the sessionId it returns. For every subsequent call to PaymentTool or CreditTool, include the same sessionId in the parameters.

 

I’m looking to resolve this issue.

Yaml 
 
swagger: '2.0'
info:
  title: MCP
  description: >-
    Provides .NET 8 MCP tools for searching, summarizing, and managing member access,
    details. Designed for integration with .NET 8 projects.
  version: 1.0.0
host: https://test.test.com/memberaccessinfo
basePath: /
schemes:
  - https
consumes: []
produces: []
paths:
  /:
    post:
      summary:  MCP
      x-ms-agentic-protocol: mcp-streamable-1.0
      operationId: InvokeMCP
      responses:
        '200':
          description: Success
definitions: {}
parameters: {}
responses: {}
securityDefinitions: {}
security: []
tags: []
 
 
 
  [McpServerToolType]
  public class LoginToolController 
  {
      // Public static session store for per-login session management
      public static readonly Dictionary<string, SessionData> SessionStore = new();
      [McpServerTool(
          Name = "LoginTool",
          Title = "User Login Tool",
          UseStructuredContent = true
      )]
      [Description("A tool to authenticate users and provide session tokens.")]
      public async Task<LoginResponse> LoginTool(string username, string password)
      {
          if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
              return new LoginResponse { Message = "Username and password are required." };
          // Simulate login check (replace with DB/API in production)
          if (username == "demo" && password == "demo")
          {
              var sessionId = Guid.NewGuid().ToString();
              // Store session data
              SessionStore[sessionId] = new SessionData
              {
                  Username = username,
                  LoginTime = DateTime.UtcNow
              };
              var response = new LoginResponse
              {
                  Success = true,
                  SessionId = sessionId,
                  Message = "Login successful"
              };
              return response;
          }
          else if (username == "demo1" && password == "demo1")
          {
              var sessionId = Guid.NewGuid().ToString();
              // Store session data
              SessionStore[sessionId] = new SessionData
              {
                  Username = username,
                  LoginTime = DateTime.UtcNow,
                  sessionId= sessionId
              };
              var response = new LoginResponse
              {
                  Success = true,
                  SessionId = sessionId,
                  Message = "Login successful"
              };
              return response;
          }

          return new LoginResponse{Success = false, Message = "Invalid credentials" };
      }
      // Method to get session data by sessionId (for use in PaymentToolController)
      public static SessionData? GetSession(string sessionId)
      {
          SessionStore.TryGetValue(sessionId, out var session);
          return session;
      }
  }
  public class SessionData
  {
      [Description("Name of the member associated with the creditor information.")]
      public string Username { get; set; } = "";
      [Description("Session identifier for the logged-in user.")]
      public string sessionId { get; set; } = "";
      [Description("UTC time when the user logged in.")]
      public DateTime LoginTime { get; set; }
  }
  public class LoginRequest
  {
      [Description("Username provided by the user for authentication.")]
      public string Username { get; set; } = "";
      [Description("Password provided by the user for authentication.")]
      public string Password { get; set; } = "";
  }
  public class LoginResponse
  {
      [Description("Indicates whether the login was successful.")]
      public bool Success { get; set; }
      [Description("Session identifier returned after successful login.")]
      public string? SessionId { get; set; }
      [Description("Message describing the result of the login attempt.")]
      public string Message { get; set; } = "";
  }
 
 [McpServerToolType]
 public class PaymentToolController 
 {
     [McpServerTool(
      Name = "PaymentTool",
      Title = "User Payment Tool",
      UseStructuredContent = true
     )]
     [Description("Use this tool to process payments. Always include the 'sessionId' returned by the LoginTool result when calling this tool.")]
     public async Task<PaymentResponse>  PaymentTool(string sessionId)
     {
         if (string.IsNullOrWhiteSpace(sessionId))
             return new PaymentResponse { Message = "SessionId missing. Please login first." };
         // Validate session
         var session = LoginToolController.GetSession(sessionId);
         if (session == null)
             return new PaymentResponse { Message = "Invalid or expired session. Please login again." };
         if(session.Username == "demo")
         {
             // Simulate pulling payment data for the logged-in user
             var response = new PaymentResponse
             {
                 MemberName = session.Username,
                 sessionId = session.sessionId,
                 DueAmount = 150.75m,
                 DueDate = DateTime.UtcNow.AddDays(5),
                 Status = "Payment Pending"
             };
             return response;
         }
         else if (session.Username == "demo1")
         {
             // Simulate pulling payment data for the logged-in user
             var response = new PaymentResponse
             {
               
                 MemberName = session.Username,
                 sessionId = session.sessionId,
                 DueAmount = 123123,
                 DueDate = DateTime.UtcNow.AddDays(5),
                 Status = "Payment Approvded"
             };
             return response;
         }
         return new PaymentResponse { Message = "User not authorized to access payment information." }; ;

      
     }
 }
 public class PaymentRequest
 {
     public string SessionId { get; set; } = "";
 }
 public class PaymentResponse
 {
     [Description("Name of the member associated with the creditor information.")]
     public string MemberName { get; set; } = "";
     [Description("Session ID used for authentication and tracking.")]
     public string sessionId { get; set; } = "";
     [Description("Amount due for the payment.")]
     public decimal DueAmount { get; set; }
     [Description("Date by which the payment is due.")]
     public DateTime DueDate { get; set; }
     [Description("Current status of the payment.")]
     public string Status { get; set; } = "";
     [Description("Additional message or error information.")]
     public string Message { get; set; } = "";
 }
I have the same question (0)
  • Suggested answer
    sannavajjala87 Profile Picture
    748 Super User 2026 Season 1 on at
    Hi,
     
    Based on the behavior you're seeing, this appears to be a limitation of how mcp-streamable tools are orchestrated in Copilot Studio, rather than an issue with your C# implementation.
     
    Your LoginTool is successfully returning the sessionId, as shown in your test results. However, Copilot Studio does not automatically persist tool outputs and inject them into subsequent tool calls simply because they are returned by a previous tool. Even with agent instructions telling Copilot to "save the sessionId and reuse it," the model may not reliably pass that value to PaymentTool in later turns.
    A few observations from your implementation:
    • PaymentTool requires sessionId as a mandatory input parameter.
    • After LoginTool completes, Copilot acknowledges the login but does not appear to retain the returned sessionId as structured state.
    • When PaymentTool is invoked, Copilot sees that sessionId is required and asks the user for it instead of supplying the value returned from LoginTool.
    • This explains why the tool works in Studio testing but fails in conversational MCP Streamable scenarios.
    One thing to consider is whether the session identifier really needs to be passed between tool calls. MCP tools are generally designed to be stateless from the model's perspective, and relying on the model to remember and forward session tokens can be unreliable. A more robust pattern is to manage the session on the server side, using the authenticated user context or a backend session store, so that PaymentTool can retrieve the active session without requiring Copilot to pass the sessionId explicitly.
     
    You may also want to verify whether the sessionId is being exposed in the tool schema as structured output that Copilot can reference. Even then, current tool orchestration does not guarantee that values returned by one MCP tool will automatically be used as inputs to another tool across conversation turns.
     
    In short, the issue is likely not with your C# code. The challenge is that Copilot Studio is not reliably maintaining and reusing the sessionId returned by LoginTool when invoking PaymentTool. The recommended approach is to handle session persistence within the MCP service itself rather than relying on the agent to pass session tokens between tools.
     
    Thanks,
    Manoj Annavajjala
    www.powerplatformengineer.com

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Season of Sharing Community Challenge Winners!

Congratulations to our community stars!

Kudos to our 2025 Community Spotlight Honorees

Expanding mentorship, skilling, and AI innovation

Congratulations to the June Top 10 Community Leaders!

These are the community rock stars!

Leaderboard > Copilot Studio

#1
sannavajjala87 Profile Picture

sannavajjala87 160 Super User 2026 Season 1

#2
11manish Profile Picture

11manish 145

#3
Haque Profile Picture

Haque 121

Last 30 days Overall leaderboard