DEV Community

Cover image for Why do we need MCP Context
aravind_akay
aravind_akay

Posted on

Why do we need MCP Context

Ever since the AI boom, it feels like everyone wants to integrate AI into their applications to supercharge the user experience.

Here is what I've learned: standard AI models and search engines are fantastic at fetching publicly available information. However, our custom applications rely on private data securely tucked away in our own databases. An out-of-the-box LLM can't just magically see what's inside our private DB!

So, how do we bridge the gap?

I discovered that major AI providers—like OpenAI, Anthropic, and Gemini actually give us a way to let their models interact directly with our applications.

To make this magic happen, we write a specific piece of code called a tool (or function calling).

This tool acts as a smart middleman that tells the AI exactly how to fetch the right information from our app.

The workflow is so cool and looks exactly like this:

User Query --> LLM --> Tool --> Your Server --> Your DB

But here is the current puzzle I’m trying to solve: the setup isn't universal!

Every LLM provider gives a each unique way to interact.

For example, Lets setup a simple server with node and express.


const express = require("express");

const app = express();
const PORT = 3000;

app.use(express.json());


let employees = [
  {
    id: 1,
    name: "John Doe",
    salary: 50000,
    location: "Bangalore"
  },
  {
    id: 2,
    name: "Jane Smith",
    salary: 70000,
    location: "Chennai"
  }
];


app.get("/employees", (req, res) => {
  res.status(200).json({
    success: true,
    data: employees
  });
});


app.get("/employees/:id", (req, res) => {
  const id = Number(req.params.id);

  const employee = employees.find(emp => emp.id === id);

  if (!employee) {
    return res.status(404).json({
      success: false,
      message: "Employee not found"
    });
  }

  res.status(200).json({
    success: true,
    data: employee
  });
});


app.post("/employees", (req, res) => {
  const { name, salary, location } = req.body;

  if (!name || !salary || !location) {
    return res.status(400).json({
      success: false,
      message: "name, salary and location are required"
    });
  }

  const newEmployee = {
    id: employees.length
      ? Math.max(...employees.map(emp => emp.id)) + 1
      : 1,
    name,
    salary,
    location
  };

  employees.push(newEmployee);

  res.status(201).json({
    success: true,
    message: "Employee created successfully",
    data: newEmployee
  });
});


app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});
Enter fullscreen mode Exit fullscreen mode

I've exposed 3 endpoints
GET/employees -> gives all the list of employees
GET/employees/:id -> gives an employee detail
POST/employees -> creates a new employee

I didn't used any db here. Since its only for demo purpose.

I'd like to focus on only one endpoint now. For more endpoints you can refer my github

Now I want my server to interact with claude.
I need to setup my tool, This is the information about your endpoint.

tools: [
  {
    name: "getEmployees",
    description: "Get all employees",
    input_schema: {
      type: "object",
      properties: {}
    }
  }
]
Enter fullscreen mode Exit fullscreen mode

if I wish my server to interact with gemini, i have to write my tool like this.

const tools = [
  {
    functionDeclarations: [
      {
        name: "getEmployees",
        description: "Get all employees",
        parameters: {
          type: "OBJECT",
          properties: {}
        }
      }
    ]
  }
];
Enter fullscreen mode Exit fullscreen mode

if I wish to use open ai. My tool would be,

const tools = [
  {
    type: "function",
    function: {
      name: "getEmployees",
      description: "Get all employees",
      parameters: {
        type: "object",
        properties: {}
      }
    }
  }
];
Enter fullscreen mode Exit fullscreen mode

There is a next step in which we have to initiate the respective model and handle the tool call. But the core relies on this tool.

Now here comes the MCP to make it universal like an USB-c port for all phones.

MCP provides a way to declare the tools in one config and make use of it in all LLM's.

mcp-server.js file would be like

const { McpServer } = require("@modelcontextprotocol/sdk/server/mcp.js");
const { StdioServerTransport } = require("@modelcontextprotocol/sdk/server/stdio.js");

const server = new McpServer({
  name: "employee-server",
  version: "1.0.0",
});

server.tool(
  "getEmployees",
  "Get all employees",
  {},
  async () => {
    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(employees, null, 2),
        },
      ],
    };
  }
);
Enter fullscreen mode Exit fullscreen mode

Now I jus need to run this server when my custom server runs. Thats all. Now I can access this server in my claude desktop.

Although you need to provide the config detail in the claude_desktop_config.json

So that my claude desktop would know about this mcp-server.

{
  "mcpServers": {
    "employee-server": {
      "command": "node",
      "args": [
        "your-project-folder/mcp-server.js"
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

I'm attaching the screenshots from my claude-desktop for your reference.

I hope this would clarify why we need mcp in our application.

Top comments (0)