Skip to content

Feat/lark mcp #139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions mcp/server/mcp_server_lark/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by https://smithery.ai. See: https://smithery.ai/docs/config#dockerfile
# Use an official Python image
FROM python:3.11-slim

# Create and set working directory
WORKDIR /app

# Install build system and dependencies
RUN pip install --upgrade pip && \
pip install poetry

# Copy the project files into the container
COPY . /app

RUN poetry install --no-root
# Expose the port that the MCP server will run on
EXPOSE 8000

# Run the MCP server
CMD ["poetry", "run", "python3", "server.py"]
83 changes: 83 additions & 0 deletions mcp/server/mcp_server_lark/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Lark MCP Server

MCP Server for the Lark API

## Tools

1. `create_document`
- Create document in a folder
- Optional inputs:
- `document_name` (string): name of the document
- `dest_folder_token` (string): folder token. Optional. If not set, it will take configured default value
- Returns: str

2. `write_text`
- Write content into a document
- Required inputs:
- `document_id` (string): The ID of the document
- `body` (string): document body
- Returns: Any

3. `send_message`
- Send message to a person or a chat group. You can configure a contact list to whom the agent can send to.
- Required inputs:
- `message` (string): The content to send
- `contact_name` (string): The person/group name to send to
- Returns: Any

## Setup

1. Create a Lark App

Check out [this doc](https://bytedance.sg.larkoffice.com/docx/WAXHduITJoVYVExGXfNlRKqYgaf) for details on how to create your lark app

2. Configure config.yaml

Copy `config.template.yaml` into `config.yaml` and fill in your app's detail

Check out [this doc](https://bytedance.sg.larkoffice.com/docx/WAXHduITJoVYVExGXfNlRKqYgaf) for details on how to obtain the configs.

3. Run the server

There are two ways to run the MCP Lark server:

### Option 1: Direct Command
Run the server directly using:
```bash
uvx --from git+https://github.com/volcengine/mcp-server@master#subdirectory=server/mcp_server_lark \
mcp-server-lark \
--transport stdio \
--config /path/to/config.yaml
```

### Option 2: Claude Desktop Integration
1. Visit the [Claude Desktop Quick Start Guide](https://modelcontextprotocol.io/quickstart/user)
2. Create or update your `mcp.json` configuration file:
```json
{
"mcpServers": {
"lark": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/volcengine/mcp-server@master#subdirectory=server/mcp_server_lark",
"mcp-server-lark",
"--transport",
"stdio",
"--config",
"/path/to/config.yaml"
]
}
}
}
```

> **Note**: Replace `/path/to/config.yaml` with the actual path to your configuration file.

4. Debug

After starting your server, start your inspector

```bash
npx @modelcontextprotocol/inspector
```
11 changes: 11 additions & 0 deletions mcp/server/mcp_server_lark/config.template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
app_id: "YOUR APP ID"
app_secret: "YOUR APP SECRET"
dest_folder_token: "YOUR WORKING FOLDER"
contact_list:
- name: "Your name"
id_type: "email"
id: "[email protected]"
- name: "Arkitect代码开发群"
description: "将和arkitect代码仓库相关的信息发送到这个群"
id_type: "chat_id"
id: "oc_xxxxxxxxxx"
35 changes: 35 additions & 0 deletions mcp/server/mcp_server_lark/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[project]
name = "mcp-server-lark"
version = "0.1.0"
description = "Lark MCP Server"
readme = "README.md"
requires-python = ">=3.10,<4.0"
dependencies = [
"lark-oapi (>=1.4.8)",
"mcp (>=1.3.0)",
"PyYAML (>=6.0.2)"
]

[project.scripts]
mcp-server-lark = "mcp_server_lark.server:main"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.pyright]
include = ["src"]
venvPath = "."
venv = ".venv"

[tool.ruff.lint]
select = ["E", "F", "I"]
ignore = []

[tool.ruff]
line-length = 88
target-version = "py310"

[tool.uv]
dev-dependencies = ["pyright>=1.1.378", "pytest>=8.3.3", "ruff>=0.6.9"]

Empty file.
38 changes: 38 additions & 0 deletions mcp/server/mcp_server_lark/src/mcp_server_lark/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from enum import Enum
from pathlib import Path
from typing import List, Optional, Dict

import yaml
from pydantic import BaseModel


class IdType(str, Enum):
email = "email"
chat_id = "chat_id"
user_id = "user_id"


class Contact(BaseModel):
name: str
description: Optional[str] = None
id_type: IdType
id: str


class Config(BaseModel):
app_id: str
app_secret: str
dest_folder_token: str
contact_list: List[Contact]

@property
def contact_dict(self) -> Dict[str, Contact]:
return {c.name: c for c in self.contact_list}


def load_config(file_path: str) -> dict:
path = Path(file_path)
try:
return Config(**yaml.safe_load(path.read_text()))
except FileNotFoundError as e:
raise FileNotFoundError(f"Config file not found: {file_path}") from e
Loading