freakynit/mcp-like-server
If you are the rightful owner of mcp-like-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
This is a custom MCP server implementation created for understanding the core concepts behind such tools, developed in under 3 hours for learning and experimentation purposes.
This is MCP server like custom implementation created for understanding the core concepts behind such tools. This was done in under 3 hours end to end, so, no focus is given to code quality or anything else. This is purely for learning (and experimentation).
Sample Chat Runs
Log level was set to info, not debug, for these, hence, no background messages are shown.
Search for latest US politics news
> custom-mcp-server-implementation@1.0.0 example_chat
> node src/example_chat.js
Query (exit/quit/bye to exit)...search for latest US politics news
info: [Final Answer]
[{"type":"ORGANIC","link":"https://www.cnn.com/politics","description":"The IRS is drafting plans to cut as much as half of its 90,000-person workforce, sources say � Trump says US has apprehended 'top terrorist' responsible for�...","title":"Politics - CNN"},{"type":"ORGANIC","link":"https://www.nbcnews.com/politics","description":"Find the latest political news stories, photos, and videos on NBCNews.com. Read breaking headlines covering Congress, Democrats, Republicans, and more. � � � ","title":"Politics: Latest news and headlines | NBC News"},{"type":"ORGANIC","link":"https://www.nytimes.com/international/section/politics","description":"Breaking news and analysis on U.S. politics, including the latest coverage of the White House, Congress, the Supreme Court and more. � � � ","title":"U.S. Politics - The New York Times International"},{"type":"ORGANIC","link":"https://www.theguardian.com/us-news/us-politics","description":"President Donald Trump addresses a joint session of Congress at the US Capitol. Trump touts renewal of rightwing policies in lengthy speech as Democrats jeer,�...","title":"US politics | The Guardian"},{"type":"ORGANIC","link":"https://www.politico.com/politics","description":"Protesters rally in support of Ukraine outside the U.S. Capitol. Trump: Zelenskyy says Ukraine is ready for peace. By DASHA BURNS. 03/�... � � ","title":"Latest and breaking political news today - POLITICO"},{"type":"ORGANIC","link":"https://abcnews.go.com/Politics","description":"Trump orders a 'pause' on military aid to Ukraine. The move followed a fiery Oval Office meetup of the U.S. and Ukraine leaders. March 03. � � ","title":"Breaking Political News, Video & Analysis-ABC News"},{"type":"ORGANIC","link":"https://www.bbc.com/news/topics/cwnpxwzd269t","description":"7 hours ago � The president declares \"America is back\" as he soaks up Republican ovations and spars with Democrats. Just now. World.","title":"US politics - BBC News"},{"type":"ORGANIC","link":"https://www.independent.co.uk/news/world/americas/us-politics","description":"US politics � Truth behind the US economy and where it's heading after Trump tariffs � Stock markets drop as Trump's tariffs with Mexico and Canada begin. � � ","title":"US Politics | Latest news, comment and analysis - The Independent"},{"type":"ORGANIC","link":"https://www.politico.com/","description":"Democrats Are Serious About a Shutdown � Republicans squirm as Trump's tariffs come for their states � Zelenskyy says it is 'time to make things right' after Oval�... � � � ","title":"Politics, Policy, Political News - POLITICO"}]
Query (exit/quit/bye to exit)...
Server CPU count
> custom-mcp-server-implementation@1.0.0 example_chat
> node src/example_chat.js
Query (exit/quit/bye to exit)...tell me server cpu count
info: [Final Answer]
8
Query (exit/quit/bye to exit)...
No tool call and then page scrape tool call
> custom-mcp-server-implementation@1.0.0 example_chat
> node src/example_chat.js
Query (exit/quit/bye to exit)...how are you doing today?
info: [Final Answer]
I'm just a computer program, so I don't have feelings, but I'm here and ready to help you with whatever you need! How can I assist you today?
Query (exit/quit/bye to exit)...extract this page content: https://example.com/
info: [Final Answer]
# Example Domain
This domain is for use in illustrative examples in documents. You may use this
domain in literature without prior coordination or asking for permission.
[More information...](https://www.iana.org/domains/example)
Query (exit/quit/bye to exit)...quit
Installation and Running
- Set up qdrant vector store. See below (Setup Qdrant as Vector Store)
- Clone the repo
- Copy
.env.example
to.env
and fill needed values.FIRECRAWL_KEY
is only needed if you want to use page scraping tool. Others are needed. - Set
CHAT_LOG_LEVEL
todebug
for the time being. - Start server (make sure
qdrant
is running with everything default):npm run server
. - In another window, start sample chat loop that transparently uses this MCP-like server for tool invocations:
npm run example_chat
. - Try with simple message first that does NOT need to call any tool:
how are you doing
. - Now, let's test tool call. A few tools are available in
functions
directory. Check them out. - Type:
search for latest US politics news
. A lot of messages will appear on console.. those are debug messages. Final results are prefixed withFinal Answer
. You can also set log level toinfo
to only see final answers. - Another one:
tell me server cpu count
. - FireCrawl test (signup for a free key):
extract this page content: https://example.com/
. - Confusing one:
Add these numbers: 10, 20
. Why this is confusing? Because for such simple addition, LLM's do NOT need to rely on tool calls. Hence, this is NOT using any tool call. - Let's force tool call for this one:
Add these numbers: 10, 20 using tool call
. This time, our tool:functions/add_numbers.js
is called. Enabledebug
logging any time to see behind-the-scenes messages.
Setup Qdrant as Vector Store
docker run -p 6333:6333 -p 6334:6334 \
-v $(pwd)/qdrant_storage:/qdrant/storage \
qdrant/qdrant
UI at: http://localhost:6333/dashboard
Understanding what's happening behind the scenes
- Broadly speaking, MCP exposes two endpoints: first to query for registered functions/tools, and second one to execute chosen function with arguments.
- This choice of function to execute is performed by the LLM.
- If you look at our , you'll see we have, in the beginning itself, defined two such functions/tools using variable:
toolsServerTools
. - These correspond EXACTLY to two endpoints:
/api/functions/search
and/api/functions/execute
. - The chat loop basically adds these two tool call definitions to every user chat message.
- It then relies on LLM deciding whether current question can be answered natively (without relying on any external tool), or it needs the help of a tool to correctly answer user's question.
- Important to keep in mind: as of NOW (first user chat message), it does NOT have any knowledge of registered tools/functions. It simply knows there is a
tool
that it can use tosearch
for functions (or more tools), one of which might be able to answer user's question. - This is where the first registered tool in
toolsServerTools
comes into play. - Now, the LLM responds back with tool call in its response. This is caught by the example_chat loop:
let content = result?.choices?.[0]?.message?.content; let toolCalls = result?.choices?.[0]?.message?.tool_calls; if(content) { logger.info(`[Final Answer]\n${typeof content === 'object' ? JSON.stringify(content) : content}`); } else { // ... tool call caught here }
- Now,
handleToolCall
method is called after extracting function/tool name and it's corresponding arguments. Since this is first tool call, this is actuallysearchFunctions
tool call corresponding to our/api/functions/search
endpoint. - We call this endpoint with arguments given by LLM, and in return, receive most applicable functions (top-3 for now). These are then added to existing
toolsServerTools
variable:for(const availableTool of toolCallResult?.result) { toolsServerTools.push({ "type": "function", "function": availableTool?.definition }); }
- Now, original message is sent again, but this time, our LLM
already
has access to most probable function(s) that canfinally
, answer user's question (since we have added searched function as shown above). - Now, LLM responds back with the final tool call and corresponding arguments. We call
handleToolCall
method yet again, but this time, the finalelse
case matches with correct registered function and corresponding arguments are passed to it. - This tool is executed by our server on
/api/functions/execute
endpoint. - The result from this function/tool/server-api call is the final answer that is shown to the user.
- Do note that this chat loop does NOT keep chat history. This is one-shot chat only.
Example flows for various inputs
how are you doing
=> user -> llm -> done.search for latest US politics news
=> user -> llm -> tool call (searchFunctions
) => [top 3 matching functions] => add these to tool call definitions => LLM call again => tool call (googleSearch
) => final result => user.extract this page content: https://example.com/
=> similar flow as above, but, second tool call isextractPageContent
.