Welcome to the second chapter of the McpAuthTool tutorial!
In the previous chapter, MCP Server Configuration, we learned how to read the "Contact Card" of a server to know where it lives. Now, we need to teach our AI how to interact with that server.
Imagine you have a super-smart robot butler (the AI). It wants to help you, but it doesn't know how to use your new fancy coffee machine.
To fix this, you don't rewrite the robot's brain. Instead, you hand it a manual (an Interface) that says:
In our project, this manual is called a Tool Interface.
The McpAuthTool acts as a specific skill: "Authenticate Server". We need to package the code that handles logging in so the AI understands when and how to use it.
In our codebase, a Tool is just a TypeScript object with four main parts.
This is the text the AI reads.
weather-server_authenticate).This acts like a generic form. It defines what data the AI needs to provide.
{ city: "London" }.call)This is the actual code that runs when the AI decides to use the tool. This is where the magic happens.
Let's look at how we construct this object in McpAuthTool.ts. We wrap the creation in a function called createMcpAuthTool.
Here is the simplified structure of our tool. Notice how it maps to the "Manual" analogy.
// Ideally, this returns a Tool object
export function createMcpAuthTool(serverName: string, config: any) {
return {
name: `${serverName}_authenticate`, // Unique ID
// The "Manual" for the AI
async description() {
return `The ${serverName} server needs login. Call this to get an auth URL.`
},
// The "Form" (Empty, because we don't need arguments)
get inputSchema() {
return z.object({})
},
// The "Action" button
async call(input, context) {
// Code to start the login process goes here...
return { data: { message: "Here is your login URL..." } }
}
}
}
Explanation: We are returning an object that adheres to the Tool contract. The AI platform (like Claude) will receive the name, description, and inputSchema to understand what this tool does.
What happens when the AI actually uses this tool?
The AI doesn't run code itself. It just sends a text message saying, "I want to run tool X." The application acts as the executor.
description. It realizes the server requires authentication.weather_authenticate."call() function we defined.
Let's look at the real implementation in McpAuthTool.ts to see how the call function works.
First, the tool checks if it can actually perform the action based on the config we learned about in Chapter 1.
async call(_input, context) {
// We check the config type from Chapter 1
if (config.type !== 'sse' && config.type !== 'http') {
return {
data: {
status: 'unsupported',
message: `Server uses ${config.type}. No OAuth support.`
},
}
}
// ... continue to auth logic
}
Explanation: Just like a physical machine might have safety sensors, our code checks if the transport type allows for web-based logging in.
If the check passes, we perform the OAuth flow. We need to get a URL to show the user.
// Start the background process to get the URL
const authUrlPromise = new Promise<string>(resolve => {
// This logic extracts the URL from the OAuth service
performMCPOAuthFlow(serverName, config, (url) => resolve(url), /*...*/)
})
// Wait for the URL to be ready
const authUrl = await authUrlPromise
Explanation: We start the authentication process. This code waits until the system generates a clickable link (the authUrl).
Finally, we return the data in a format the AI understands.
return {
data: {
status: 'auth_url',
authUrl,
// Instructions for the AI to tell the user
message: `Ask the user to open this URL: ${authUrl}`
},
}
}
Explanation: This is the return value of the function. The AI receives this message and will likely say to the user: "Please click this link to log in."
In this chapter, we explored the Tool Interface. We learned that a Tool is simply a standard contract containing:
However, there is something unique about this specific tool. It's not a permanent tool like "Calculator" or "Weather". It only exists until the user logs in, and then it should disappear to be replaced by the real server tools.
How do we handle a tool that is meant to be temporary? We'll discuss this special behavior in the next chapter.
Next Chapter: Pseudo-Tool Pattern
Generated by Code IQ