Skip to content

Instantly share code, notes, and snippets.

@recursivecodes
Last active June 2, 2025 13:59
Show Gist options
  • Save recursivecodes/549c6a93054332efe22f3c77ac950d71 to your computer and use it in GitHub Desktop.
Save recursivecodes/549c6a93054332efe22f3c77ac950d71 to your computer and use it in GitHub Desktop.

Intro to Model Context Protocol (MCP)

In this document, we will look at the basics of MCP.

Create Server

  1. Create Project
mkdir demo-mcp-server && cd demo-mcp-server
npm init es6 -y
  1. Install MCP framework
npm install @modelcontextprotocol/sdk
touch index.js
  1. Import MCP server module, transport and zod (schema validation library)

index.js:

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from "zod";
  1. Create server
const mcpServer = new McpServer(
  {
    name: "Demo-MCP-Server",
    version: "1.0.0"
  }
);
  1. Create stdio transport
const transport = new StdioServerTransport();
await mcpServer.connect(transport);
  1. Inspect server
npx @modelcontextprotocol/inspector node index.js
Starting MCP inspector...
⚙️ Proxy server listening on port 6277
🔍 MCP Inspector is up and running at http://127.0.0.1:6274 🚀
  1. Add tool
mcpServer.tool(
  "get-current-date-time",
  "Gets the current date and time",
  {},
  async () => {
    return {
      content: [{ type: "text", text: JSON.stringify({ currentDate: new Date().toISOString() }) }]
    };
  }
);
  1. Restart server, test tool

  2. Add dependency

npm install node-html-markdown
  1. Add tool
import { NodeHtmlMarkdown } from 'node-html-markdown';

mcpServer.tool(
  "fetch-url",
  "Fetch a URL and return its contents as markdown",
  {
    url: z.string().describe('The URL to fetch'),
  },
  async ({ url }) => {
    const response = await fetch(url);
    const text = await response.text();
    // convert to markdown
    const md = NodeHtmlMarkdown.translate(text);
    return {
      content: [{ type: "text", text: md }]
    };
  }
);
  1. Restart server, test tool

  2. Add AWS S3 client

npm install @aws-sdk/client-s3
  1. Add tool to list objects in S3 bucket
import { S3Client, ListObjectsV2Command } from "@aws-sdk/client-s3";
const client = new S3Client();

mcpServer.tool(
  "list-s3-objects",
  "Returns some or all (up to 1,000) of the objects in a bucket with each request",
  {
    bucket: z.string().describe('The S3 bucket name'),
  },
  async ({ bucket }) => {
    const command = new ListObjectsV2Command({ Bucket: bucket });
    const response = await client.send(command);
    return {
      content: [{ type: "text", text: JSON.stringify(response?.Contents) }]
    };
  }
);
  1. Stop inspector

Create Client

  1. Create Project
cd ../
mkdir demo-mcp-client && cd demo-mcp-client
npm init es6 -y
  1. Install MCP framework
npm install @modelcontextprotocol/sdk
touch index.js
  1. Import MCP client module and transport
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
  1. Create transport
const customTransport = new StdioClientTransport({
  command: "node",
  args: ['/projects/demos/ivs-mcp/mcp-demo/demo-mcp-server/index.js'],
  env: {
    ...process.env,
  }
});
  1. Create client
const demoClient = new Client(
  {
    name: "Demo-MCP-Client",
    version: "1.0.0"
  },
  {
    capabilities: {
      tools: {},
      // prompts: {},
      // resources: {},
    }
  }
);
  1. Connect client
await demoClient.connect(customTransport);
  1. List tools
const tools = await demoClient.listTools();
console.log(tools);
  1. Use tool
const toolResponse = await demoClient.callTool({ name: 'get-current-date-time', arguments: {} });
console.log(toolResponse);
const s3BucketResponse = await demoClient.callTool({ name: 'list-s3-bucket', arguments: {bucket: '[YOUR BUCKET NAME]'} });
console.log(s3BucketResponse);

Enhance custom client that accepts user prompts and invokes LLM with the configured tools exposed to the invocation. Handle LLM response and invoke tools as requested by the LLM.

mcp-server-flow

Connect Amazon Q to Custom MCP Server

Install Amazon Q

  1. Enter project root
cd ../
  1. Create MCP config

MCP config is stored for all projects at ~/.aws/amazonq/mcp.json. This can be overridden for a single project by placing a local file at ./amazonq/mcp.json. Update the path to the custom MCP server created above.

{
  "mcpServers": {
    "demo-mcp-server": {
      "command": "node",
      "args": [
        "/projects/demos/ivs-mcp/mcp-demo/demo-mcp-server/index.js"
      ],
      "env": {}
    }
  }
}
  1. Use existing MCP server
"awslabs.aws-documentation-mcp-server": {
  "command": "uvx",
  "args": [
    "awslabs.aws-documentation-mcp-server@latest"
  ],
  "env": {
    "FASTMCP_LOG_LEVEL": "ERROR"
  },
  "disabled": false,
  "autoApprove": [
    "read_documentation"
  ]
}
  1. Run Amazon Q
q chat
  1. Tool commands
/tools        View and manage tools and permissions
  help        Show an explanation for the trust command
  trust       Trust a specific tool or tools for the session
  untrust     Revert a tool or tools to per-request confirmation
  trustall    Trust all tools (equivalent to deprecated /acceptall)
  reset       Reset all tools to default permission levels
  1. Optional: use q mcp
$ q mcp     
Model Context Protocol (MCP)

Usage: qchat mcp [OPTIONS] <COMMAND>

Commands:
  add     Add or replace a configured server
  remove  Remove a server from the MCP configuration
  list    List configured servers
  import  Import a server configuration from another file
  status  Get the status of a configured server
  help    Print this message or the help of the given subcommand(s)

Options:
  -v, --verbose...  Increase logging verbosity
  -h, --help        Print help

Docs

Public MCP Servers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment