Skip to main content
Glama
duyet
by duyet
README.md
# duyet-mcp-server

[![CI/CD Pipeline](https://github.com/duyet/duyet-mcp-server/workflows/CI/CD%20Pipeline/badge.svg)](https://github.com/duyet/duyet-mcp-server/actions)
[![codecov](https://codecov.io/gh/duyet/duyet-mcp-server/branch/master/graph/badge.svg)](https://codecov.io/gh/duyet/duyet-mcp-server)
[![Security](https://github.com/duyet/duyet-mcp-server/workflows/Security%20and%20Dependencies/badge.svg)](https://github.com/duyet/duyet-mcp-server/actions)

An experimental [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that helps AI assistants connect to and retrieve information about duyet. This server provides access to information primarily available at [https://duyet.net](https://duyet.net), making it available directly to your AI assistant.

**Endpoint:** `https://mcp.duyet.net/mcp` (Streamable HTTP, stateless — works with every major MCP client)

## Connect from Any MCP Client

| Client | How to connect |
|--------|----------------|
| **Claude Code** | `claude mcp add --transport http duyet https://mcp.duyet.net/mcp` |
| **Claude Desktop / claude.ai** | Settings → Connectors → Add custom connector → `https://mcp.duyet.net/mcp` |
| **Cursor** | Add to `~/.cursor/mcp.json` → `{"mcpServers": {"duyet": {"url": "https://mcp.duyet.net/mcp"}}}` |
| **Windsurf** | Add to `~/.codeium/windsurf/mcp_config.json` → `{"mcpServers": {"duyet": {"serverUrl": "https://mcp.duyet.net/mcp"}}}` |
| **VS Code (Copilot)** | `code --add-mcp '{"name":"duyet","type":"http","url":"https://mcp.duyet.net/mcp"}'` |
| **Codex CLI** | Add to `~/.codex/config.toml` → `[mcp_servers.duyet]` with `url = "https://mcp.duyet.net/mcp"` |
| **Gemini CLI** | `gemini mcp add --transport http duyet https://mcp.duyet.net/mcp` |
| **Zed** | Settings → `context_servers` → `{"duyet": {"source": "custom", "url": "https://mcp.duyet.net/mcp"}}` |
| **Cloudflare AI Playground** | Enter `https://mcp.duyet.net/mcp` at https://playground.ai.cloudflare.com |
| **Anything else (stdio-only)** | Use the [mcp-remote](https://www.npmjs.com/package/mcp-remote) proxy — config below |

<details>
<summary>mcp-remote proxy config (for stdio-only clients)</summary>

```json
{
  "mcpServers": {
    "duyet": {
      "command": "npx",
      "args": ["mcp-remote", "https://mcp.duyet.net/mcp"]
    }
  }
}
```

</details>

![](./.github/screenshots/screenshot-1.png)
![](./.github/screenshots/screenshot-2.png)
![](./.github/screenshots/screenshot-3.png)
![](./.github/screenshots/screenshot-4.png)
![](./.github/screenshots/screenshot-5.png)
![](./.github/screenshots/screenshot-6.png)
![](./.github/screenshots/screenshot-7.png)

## About This Project

This is a **study, demo, and experimental project** designed to explore MCP capabilities. The project serves as a learning exercise in building remote MCP servers and is mostly written by LLM as well.

**Purpose**: Enable AI assistants to access and retrieve information about duyet's work, projects, and content that would otherwise require manual web browsing.

## Deploy to Cloudflare Workers

[![Deploy to Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/duyet/duyet-mcp-server)

This will deploy your MCP server to a URL like: `duyet-mcp-server.<your-account>.workers.dev/sse`


Alternatively, you can clone and deploy using the command line:

```bash
git clone https://github.com/duyet/duyet-mcp-server
cd duyet-mcp-server
npm install
npm run deploy
```

## Customizing Your MCP Server

To add your own [tools](https://developers.cloudflare.com/agents/model-context-protocol/tools/) to the MCP server, define each tool inside the `init()` method of `src/index.ts` using `this.server.tool(...)`. 

### Connect to Cloudflare AI Playground

You can test your MCP server using the Cloudflare AI Playground:

1. Go to https://playground.ai.cloudflare.com/
2. Enter your deployed MCP server URL (`duyet-mcp-server.<your-account>.workers.dev/sse` or `duyet-mcp-server.<your-account>.workers.dev/mcp`)
3. You can now use the duyet information tools directly from the playground!

### Connect Claude Desktop to Your MCP Server

You can connect to your remote MCP server from Claude Desktop using the [mcp-remote proxy](https://www.npmjs.com/package/mcp-remote). 

To connect from Claude Desktop, follow [Anthropic's Quickstart](https://modelcontextprotocol.io/quickstart/user) and go to Settings > Developer > Edit Config.

Update with this configuration:

```json
{
  "mcpServers": {
    "duyet-info": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://duyet-mcp-server.<your-account>.workers.dev/sse"
      ]
    }
  }
}
```

You should see the duyet-mcp information tools become available.

# Available Resources and Tools

This MCP server exposes both **Resources** (read-only data access via URIs) and **Tools** (interactive functions with parameters). Resources are automatically discovered by Claude Chat for natural conversation flow, while tools are used for actions that require user input.

## Resources
Resources provide read-only access to information through URI-based requests. These are automatically discoverable by Claude Chat.

### Core Information Resources
- **`duyet://about`** - Basic information about Duyet with dynamically calculated years of experience
- **`duyet://cv/{format}`** - CV/resume with format parameters:
  - `duyet://cv/summary` - Brief CV overview
  - `duyet://cv/detailed` - Comprehensive CV information  
  - `duyet://cv/json` - Structured CV data (when available)

### Content Resources
- **`duyet://blog/posts/{limit}`** - Latest blog posts from Duyet's technical blog
  - `duyet://blog/posts/1` - Latest blog post
  - `duyet://blog/posts/5` - Latest 5 blog posts (limit: 1-10)
- **`duyet://github-activity`** - Recent GitHub contributions and activity

## Tools
Tools provide interactive functionality with input parameters and side effects.

### Core Information Tools
- **`get_cv`** - Retrieve Duyet's CV (curriculum vitae) in different formats - summary, detailed, or JSON format
- **`get_about_duyet`** - Get basic information about Duyet including experience, skills, and contact links

### Content Tools
- **`get_blog_posts`** - Get a list of blog posts from blog.duyet.net in JSON format (1-20 posts)
- **`get_blog_post_content`** - Get the full content of a specific blog post by URL, including title, content, and metadata (author, publish date, tags)
- **`get_github_activity`** - Retrieve Duyet's recent GitHub activity including commits, issues, pull requests, releases, and other public events. View up to 20 recent activities with optional detailed information

### Interaction Tools
- **`send_message`** - Send a message to Duyet for collaboration, job opportunities, consulting, or general inquiries. Messages are saved with a reference ID for follow-up
- **`hire_me`** - Get information about hiring Duyet for various roles - full-time, contract, consulting, or part-time positions. Includes expertise, experience, and next steps
- **`say_hi`** - Send a friendly greeting to Duyet with an optional personal message. Get contact information and connection links

### Management Tools
- **`contact_analytics`** - Generate analytics reports on contact submissions including summary statistics, purpose breakdown, daily trends, and recent activity patterns

## Claude Chat Examples

Here are examples of natural conversation flows using this MCP server:

### Learning About Duyet

| 🧑 User | 🤖 Claude |
|---------|-----------|
| Who is Duyet and what does he do? | *[accesses `duyet://about`]* Duyet is a Data Engineer with 8 years of experience, confident in Data Engineering concepts, best practices and state-of-the-art data and Cloud technologies. Blog: https://blog.duyet.net · CV: https://duyet.net/cv · GitHub: https://github.com/duyet |
| What has he been writing about lately? | *[accesses `duyet://blog/posts/3`]* His latest posts cover data engineering, cloud technologies, and distributed systems. Want details on a specific post? |
| What's he working on currently? | *[accesses `duyet://github-activity`]* Recent GitHub activity shows work on MCP server implementations, data pipeline projects, and open source data engineering tools. |

### Hiring and Collaboration

| 🧑 User | 🤖 Claude |
|---------|-----------|
| I'm looking to hire a data engineer. Can you help me contact Duyet? | I can send a message to Duyet using the `send_message` tool. What type of opportunity is this? |
| It's a full-time position at our startup working with Kafka and Spark | *[prepares `send_message`]* What would you like to say? I'll note it's a full-time role with Kafka and Spark. |
| Hi Duyet, we're a Series A startup building real-time data platforms. We'd love to discuss a Senior Data Engineer role — Kafka, Spark, cloud infra, remote-friendly with equity. | *[executes `send_message`]* Message sent! Reference ID: `abc-123-def`. You can also reach Duyet at me@duyet.net, LinkedIn: https://linkedin.com/in/duyet, GitHub: https://github.com/duyet |

### Technical Research

| 🧑 User | 🤖 Claude |
|---------|-----------|
| I want to understand Duyet's technical background before our interview | *[accesses `duyet://cv/detailed`]* 8 years in data engineering: Apache Spark, Kafka, cloud platforms, distributed systems, scalable data pipelines and the modern data stack. |
| Can you show me some of his recent technical work? | *[accesses `duyet://github-activity`]* Recent contributions include data engineering projects, MCP server implementations, and open source tooling for distributed, cloud-native data systems. |
| What kind of content does he write about? | *[accesses `duyet://blog/posts/5`]* Scalable data pipelines, modern data engineering best practices, cloud technologies, and distributed systems architecture. |

## Natural Discovery Pattern

The key advantage of this MCP server design is that Claude Chat can naturally discover and reference information through resources, making conversations more fluid:

1. **Information Questions** → **Automatic Resource Access**
   - "Who is Duyet?" → `duyet://about`
   - "What's his experience?" → `duyet://cv/detailed`
   - "What's he writing about?" → `duyet://blog/posts/3`
   - "What's he working on?" → `duyet://github-activity`

2. **Action Requests** → **Interactive Tools**
   - "I want to contact him" → `send_message` tool
   - "Can you send him a greeting?" → `say_hi` tool
   - "Get his resume" → `get_cv` tool

3. **Progressive Disclosure**
   - Start with general questions
   - Drill down into specific areas
   - Take actions when ready


## Architecture

- **Framework**: Hono.js running on Cloudflare Workers
- **Database**: Cloudflare D1 with Drizzle ORM
- **Testing**: Jest with comprehensive test coverage
- **Linting**: Biome for code quality
- **Type Safety**: TypeScript with strict configuration

## License

MIT License - see LICENSE file for details.

TDQS

B3.4/5.0

Scored across 8 tools

Disambiguation4/5

Most tools have distinct purposes, such as get_analytics for reports, github_activity for GitHub events, and web-search for web queries. However, send_message and say_hi could be confused as both involve contacting Duyet, though send_message is for formal inquiries and say_hi for greetings. The overlap is minor and clarified by descriptions.

Naming Consistency3/5

The naming is mixed with snake_case (e.g., get_analytics, github_activity) and kebab-case (web-fetch, web-search), breaking consistency. Verb patterns vary, such as 'get_' for retrieval and 'send_' for actions, but the deviation in case styles reduces predictability. It remains readable but lacks a uniform convention.

Tool Count5/5

With 8 tools, the count is well-scoped for a personal server covering analytics, blog content, GitHub activity, hiring info, messaging, and web utilities. Each tool serves a clear purpose without redundancy, fitting the domain of personal and professional interaction with Duyet.

Completeness4/5

The tool set covers key areas like analytics, content retrieval, activity tracking, and communication, with no major gaps for its personal server purpose. Minor gaps might include updating or deleting messages, but core workflows (e.g., fetching, searching, contacting) are adequately supported, allowing agents to function effectively.

Maintenance

ActivitySlowing
ResponsivenessNo issues