Connected Protocol Workflows

By the Syncfusion DevTutorials team · Last updated

Custom integrations versus MCP, hardcoded versus discovered tools, the steps of one connected request from discovery to answer, context assembly, interoperable servers, and governance basics.

Imagine two offices. In the first office, every worker keeps their own phone numbers on sticky notes. When a phone number changes, someone has to find and update every sticky note. Most of the time, these notes are not correct.

In the second office, everyone uses one shared phone book. When a number changes, it is updated in one place, and everyone sees the new number right away.

AI apps that do not use MCP are like the first office. AI apps that use MCP are like the second office. This lesson will show you how a request moves through MCP, and why this way is better than using custom code.

The main idea: With MCP, the app finds out about tools while running, puts together the needed information from what servers send back, and uses tools in the same way for every server.

A Real-World Example

Brightgrid's support assistant started simple. It had one special link to the order database, written directly in the app's code.

Then the team added tickets, then shipping, then the wiki. Each new thing needed new code in the app, a new release, and new tests. The chat app, the phone app, and the email bot each had their own copy of these links, and over time, these copies became different.

After switching to MCP, the help-desk team runs one MCP server. When they add a track_parcel tool, every MCP app sees it the next time it asks for the tool list. No app needs a new release.

In simple words: Custom code is like a sticky note in every app. MCP is like the shared phone book.

What You Will Learn

In this lesson, you will learn:

  1. How custom connections and MCP are different.
  2. Why tools you discover are better than tools written into the code.
  3. The steps of one connected request, from finding the server to getting an answer.
  4. How the host puts together information from MCP results.
  5. The basics of rules and safety: policies, limits, user agreement, and logs.

In the MCP Lab, the Chat with tools tab shows this whole process with a small model in your browser. It needs WebGPU. The Explorer and Inspector tabs work in any modern browser.

Custom APIs vs MCP

Two Ways to Connect

Custom integrationMCP
How the app learns about toolsWritten into the app's codeAsks the server with tools/list
How a tool is calledA different API for each systemAlways tools/call
Adding a toolChange and release every appChange the server once
Sharing between appsCopy the code into each appEvery MCP app can connect
Who owns the linkThe app teamThe system's team runs the server

Custom connections are not always bad. They can be quick and simple for one app and one system. MCP is most useful when many AI apps need many tools that change often.

Hardcoded vs Discovered Tools

With custom code, the app has a fixed list of tools. The model can only use the tools in that list.

With MCP, the app asks each server for its tools when it connects. The list comes from the server, so it is always up to date.

Hardcoded list vs discovered list

// Before MCP: the app's code lists the tools it knows. Adding one means changing the app.
const hardcoded = ["lookup_order", "create_ticket"];

// With MCP: the app asks the server, and uses whatever comes back.
const toolsListReply = {
  result: {
    tools: [
      { name: "lookup_order" },
      { name: "create_ticket" },
      { name: "track_parcel" },
    ],
    resultType: "complete",
  },
};
const discovered = toolsListReply.result.tools.map((t) => t.name);

console.log("Hardcoded: ", hardcoded.join(", "));
console.log("Discovered:", discovered.join(", "));
console.log(
  "New without an app update:",
  discovered.filter((n) => !hardcoded.includes(n)).join(", "),
);

Expected output:

Hardcoded:  lookup_order, create_ticket
Discovered: lookup_order, create_ticket, track_parcel
New without an app update: track_parcel

Start from the starting server

Try it yourself. Open the Server code tab in the lab. Copy the lookup_order block, rename the copy to track_parcel, and press Restart with this code. The Explorer shows the new tool right away. The host's code did not change.

Scattered vs Unified Context

Without MCP, facts reach the model in many ways: one function for orders, another for the wiki, a third for files. Each one formats its data differently.

With MCP, every tool result and every resource comes back in the same format: content blocks, like { "type": "text", "text": "..." }. The host can label, trim, and organize them all in one place. This makes the model's information cleaner and easier to check if something goes wrong.

This is where MCP meets context engineering. MCP brings the data to the host. The host still has to choose what goes into the context, label it, and keep it short. If you took the Context Engineering course, everything you learned there applies to MCP results.

The Connected Workflow

One connected request: discover the server, list its tools, give the model the question and tools, call the tool it picks, then give the model the result.

Discovery

The client's first message to a server is server/discover. The server answers with:

  • The spec versions it supports, like 2026-07-28.
  • Its capabilities: tools, resources, prompts.
  • Optional instructions: a short note on how to use the server.

Then the client asks for the lists it needs: tools/list, resources/list, and prompts/list.

Open the Inspector after you press the button. The first row is server/discover. Click it, and look at the response: supportedVersions, capabilities, and instructions.

Context Assembly

The host now builds the information for the model:

  • The user's question.
  • The tool list, with each tool's name, description, and input format.
  • Any resources the host chose to include, like the shipping policy.

Later, when tool results come back, the host adds them with clear labels, so the model knows where each fact came from.

Assemble context with source labels

// Context assembly: the host turns MCP results into labeled context for the model.
const pieces = [
  {
    source: "helpdesk/tools/call lookup_order",
    text: "A-1002: Air purifier, processing, arrives Oct 18",
  },
  {
    source: "helpdesk/resources/read kb://shipping",
    text: "Standard shipping takes 3 to 6 days.",
  },
];

const context = pieces
  .map((p) => `<source name="${p.source}">\n${p.text}\n</source>`)
  .join("\n");

console.log(context);
console.log("\nQuestion: Where is my order A-1002?");

Expected output:

<source name="helpdesk/tools/call lookup_order">
A-1002: Air purifier, processing, arrives Oct 18
</source>
<source name="helpdesk/resources/read kb://shipping">
Standard shipping takes 3 to 6 days.
</source>

Question: Where is my order A-1002?

Standard Tool Calls

The model reads the question and the tool list. If a tool would help, it asks for one by name, with arguments. The host checks its approval rules, then the client sends tools/call. The server runs the tool and returns the result. The host gives the result to the model, and the model writes the final answer.

The steps of one connected request

// The six steps of one connected request, in order.
const steps = [
  ["client -> server", "server/discover", "Which versions and features do you have?"],
  ["client -> server", "tools/list", "Which tools do you offer?"],
  ["host -> model", "context", "Question + tool list"],
  ["model -> host", "tool request", 'lookup_order {"order_id":"A-1002"}'],
  ["client -> server", "tools/call", "Run lookup_order"],
  ["host -> model", "context", "Question + tool result -> final answer"],
];

steps.forEach(([who, what, note], i) => {
  console.log(`${i + 1}. ${who.padEnd(16)} ${what.padEnd(15)} ${note}`);
});

Expected output:

1. client -> server server/discover Which versions and features do you have?
2. client -> server tools/list      Which tools do you offer?
3. host -> model    context         Question + tool list
4. model -> host    tool request    lookup_order {"order_id":"A-1002"}
5. client -> server tools/call      Run lookup_order
6. host -> model    context         Question + tool result -> final answer

In the Chat with tools tab, press Ask. You will see each step: what the host sent, the model's tool request, the server's result, and the model's final answer. The Inspector records the real MCP messages at the same time.

A small model in the browser can make mistakes. It may skip a tool, pick the wrong one, or make up arguments. This is normal and helpful to see. The server's checks and the host's approval steps exist because models can make these mistakes.

Interoperable Servers

Interoperable means "works together without special changes". Because every server uses the same protocol, one client function can talk to any of them. A calendar server, a file server, and a help-desk server all answer tools/list the same way.

One client, any server

// The same client code works with any MCP server.
const servers = {
  helpdesk: { tools: ["lookup_order", "create_ticket"] },
  calendar: { tools: ["find_slot", "book_meeting"] },
  files: { tools: ["read_file"] },
};

// A stand-in for a real client: one function, any server.
function listTools(serverName) {
  return {
    result: {
      tools: servers[serverName].tools.map((name) => ({ name })),
      resultType: "complete",
    },
  };
}

for (const name of Object.keys(servers)) {
  const names = listTools(name).result.tools.map((t) => t.name);
  console.log(`${name.padEnd(9)} -> ${names.join(", ")}`);
}

Expected output:

helpdesk  -> lookup_order, create_ticket
calendar  -> find_slot, book_meeting
files     -> read_file

This also works between companies. A server made by one company works with a host made by another, as long as both follow the rules.

Governance Overview

Governance means the rules about who can do what, and how you check it later. MCP gives you the tools. The host and the organization set the rules.

Policies

A policy is a written rule the host checks in code. For example: "only connect to these servers" or "never call refund tools for orders over $500".

Scope Isolation

Scope means what a server is allowed to reach. Each server should only reach its own system, with the fewest rights it needs. The help-desk server reads orders. It should not be able to read salaries. Because each client talks to just one server, one server can't see another's data through MCP.

Consent

Consent means the user agrees before something happens. The host asks before a tool changes data, and before user data is sent to a new server.

Audit Logs

An audit log is a record of every tool call: who asked, which server and tool, what arguments, and what happened. When something goes wrong, the log shows what the AI actually did.

Policy check and audit log

// Governance: a policy check before each call, and an audit log entry after.
const policy = {
  allowedServers: ["helpdesk", "wiki"],
  needsConsent: ["create_ticket", "refund_order"],
};
const audit = [];

function tryCall(user, server, tool, consent) {
  let outcome;
  if (!policy.allowedServers.includes(server)) {
    outcome = "blocked: server not allowed";
  } else if (policy.needsConsent.includes(tool) && !consent) {
    outcome = "waiting: needs the user's OK";
  } else {
    outcome = "called";
  }
  audit.push({ user, server, tool, outcome });
  return outcome;
}

tryCall("maya", "helpdesk", "lookup_order", false);
tryCall("maya", "helpdesk", "create_ticket", false);
tryCall("maya", "helpdesk", "create_ticket", true);
tryCall("maya", "payroll", "get_salary", true);

for (const a of audit) {
  console.log(`${a.user} | ${a.server}.${a.tool} | ${a.outcome}`);
}

Expected output:

maya | helpdesk.lookup_order | called
maya | helpdesk.create_ticket | waiting: needs the user's OK
maya | helpdesk.create_ticket | called
maya | payroll.get_salary | blocked: server not allowed

You will learn more about these in Chapters 7 and 8.

Common mistakes

  • Expecting MCP to pick the tool. MCP carries the request. The model picks the tool, and the host decides whether to allow it.
  • Sending every tool and every resource to the model. A long tool list confuses small models and costs tokens. Only send what the task needs.
  • Forgetting that lists change. A server's tool list can change. A host should ask for the list again when it reconnects, or when the server says the list changed.
  • Treating consent as a one-time checkbox. Risky actions need approval each time, or a clear, limited rule the user agreed to.
  • Logging only failures. Successful calls matter too. Many problems are calls that worked but should not have happened.

Exercises

Each exercise ends with a value on the last line. Press Check to compare it with the expected answer.

What to Remember

  • Custom integrations put tool lists in each app's code. MCP lets apps discover tools from servers.
  • One connected request: discover, list, assemble context, model picks, tools/call, answer.
  • Every server answers the same methods, so servers are interoperable.
  • The host labels MCP results before adding them to the context.
  • Governance = policies in code, narrow scope per server, user consent, and audit logs of every call.

Next: Chapter 2, Protocol Architecture, the layers of MCP and the messages that travel between them.