A complete Model Context Protocol (MCP) implementation: MCP Client with Python 3.11+Launches the server, speaks JSON-RPC 2.0 over stdio, exposes a clean async API. MCP Server with C# / .NET 8 Receives tool requests and executes them against the Slack Web API

Slack MCP — Python Client + C# Server

A complete Model Context Protocol (MCP) implementation with four architectural layers.

Layer Language File(s)
1 — Users Python 3.11+ client-python/main.py
2 — Prompt + Agent Python 3.11+ client-python/agent/agent.py
3 — MCP Client/Server Python + C# client-python/transport/mcp_client.py · server-csharp/
4 — Slack C# / .NET 8 server-csharp/Services/SlackService.cs

Architecture

  👤 User(s)
  (human operators / end-users)
       │  natural language input
       ▼
┌──────────────────────────────────────────────────────────┐
│  Prompt + Agent Layer                                    │
│                                                          │
│  Claude (Anthropic) ──or── External Agent                │
│    • interprets user intent                              │
│    • decides which MCP tool(s) to call                   │
│    • formats results back to the user                    │
└──────────────────────┬───────────────────────────────────┘
                       │  tool calls
                       ▼
┌──────────────────────────────────────────────────────────┐
│  Python MCP Client  (client-python/transport/)           │
│                                                          │
│  McpClient                                               │
│    └── StdioTransport                                    │
│          ├── spawns: dotnet run SlackMcpServer           │
│          └── JSON-RPC 2.0 over stdin / stdout            │
└──────────────────────┬───────────────────────────────────┘
                       │  stdio
┌──────────────────────▼───────────────────────────────────┐
│  C# MCP Server  (server-csharp/)                         │
│                                                          │
│  Program.cs  (stdio loop)                                │
│    └── ToolRegistry  (dispatch)                          │
│          └── SlackService  (Slack Web API)               │
└──────────────────────┬───────────────────────────────────┘
                       │  HTTPS
┌──────────────────────▼───────────────────────────────────┐
│  Slack                                                   │
│                                                          │
│  • send_message     → post to channel or thread          │
│  • get_history      → read recent messages               │
│  • list_channels    → browse workspace channels          │
│  • create_channel   → open a new public channel          │
│  • add_reaction     → emoji-react to a message           │
│  • list_users       → enumerate workspace members        │
└──────────────────────────────────────────────────────────┘

MCP Protocol Flow

Python Client                    C# Server
     │                               │
     │── initialize ────────────────►│
     │◄─ InitializeResult ───────────│
     │── initialized (notification) ►│
     │── tools/list ────────────────►│
     │◄─ ListToolsResult ────────────│
     │── tools/call {name, args} ───►│
     │◄─ CallToolResult ─────────────│

Layer Responsibilities

Layer 1 — 👤 Users (main.py)

Entry point for human operators. Provides an interactive REPL or single-prompt CLI. Has no knowledge of Slack or MCP — it only calls agent.handle(prompt).

Layer 2 — Prompt + Agent (agent/agent.py)

Interprets natural language intent and decides which MCP tool to call. The _resolve_intent() method is rule-based by default — replace it with a real LLM call (see comments in the file). Formats raw tool output into human-readable responses.

Layer 3 — MCP Transport (transport/mcp_client.py + server-csharp/)

Pure protocol layer. The Python side spawns the C# process and speaks JSON-RPC 2.0 over stdio. The C# side receives requests, dispatches to ToolRegistry, and writes responses. Neither side knows about user intent.

Layer 4 — Slack (server-csharp/Services/SlackService.cs)

Deepest layer. Each of the six methods maps directly to one Slack Web API endpoint. No MCP concepts here — just HTTP calls and typed DTOs.

Prerequisites

Tool Version
Python 3.11+
.NET SDK 8.0+
Slack Bot Token xoxb-…

Slack Bot Scopes Required

Go to api.slack.com/apps → OAuth & Permissions → Bot Token Scopes:

Scope Used by
chat:write send_message
channels:history get_history
channels:read list_channels
channels:write create_channel
reactions:write add_reaction
users:read list_users

Quick Start

# 1. Set your Slack bot token
export SLACK_BOT_TOKEN="xoxb-your-token-here"

# 2. Build the C# server
cd server-csharp
dotnet build

# 3. Run the interactive client
cd ../client-python
python main.py --server-cmd "dotnet run --project ../server-csharp/SlackMcpServer.csproj"

# Or run a single prompt
python main.py --prompt "List all channels"

Connecting a Real LLM (Claude)

Open client-python/agent/agent.py and replace _resolve_intent() with:

import anthropic

def _resolve_intent(self, prompt: str) -> Intent:
    client = anthropic.Anthropic()
    response = client.messages.create(
        model="claude-opus-4-6",
        max_tokens=1024,
        tools=self._client.tools,   # pass MCP schemas directly
        messages=[{"role": "user", "content": prompt}],
    )
    tool_use = next(b for b in response.content if b.type == "tool_use")
    return Intent(
        tool=tool_use.name,
        args=tool_use.input,
        explanation=prompt,
    )

Install the SDK: pip install anthropic

Running Tests

cd client-python
pip install pytest pytest-asyncio
python -m pytest tests/ -v

Tests are split by layer:

  • tests/test_agent.py — Layer 2: intent resolution and response formatting
  • tests/test_transport.py — Layer 3: JSON-RPC transport and MCP client

Project Structure

mcp-slack/
├── server-csharp/                   # Layer 3 (server) + Layer 4
│   ├── SlackMcpServer.csproj
│   ├── Program.cs                   # stdio JSON-RPC loop
│   ├── Models/
│   │   └── McpModels.cs             # JSON-RPC + MCP protocol types
│   ├── Services/
│   │   └── SlackService.cs          # Layer 4 — Slack Web API
│   └── Tools/
│       └── ToolRegistry.cs          # MCP tool definitions + dispatcher
│
└── client-python/                   # Layers 1, 2, 3 (client)
    ├── main.py                      # Layer 1 — User entry point
    ├── agent/
    │   ├── __init__.py
    │   └── agent.py                 # Layer 2 — Prompt + Agent
    ├── transport/
    │   ├── __init__.py
    │   └── mcp_client.py            # Layer 3 — MCP transport
    ├── tests/
    │   ├── conftest.py
    │   ├── test_agent.py
    │   └── test_transport.py
    ├── pytest.ini
    └── requirements.txt

Troubleshooting

Issue Fix
SLACK_BOT_TOKEN is not set export SLACK_BOT_TOKEN="xoxb-..."
channel_not_found Use a Channel ID like C012AB3CD, not #general
not_in_channel Invite the bot to the channel first
Server won't start Run dotnet build in server-csharp/ first
Intent not recognized Extend _resolve_intent() or plug in a real LLM

MCP Server · Populars

MCP Server · New