Skip to main content
Glama

Athena

당신의 AI가 작성하고, 당신이 직접 탐색할 수 있는 개인 위키.

Athena는 Wiki.js 앞에 MCP 서버를 둡니다. 당신의 어시스턴트는 위키를 검색하고, 페이지를 읽고, 새로운 페이지를 작성합니다: 노트, 문서, 전체 대화. 그것이 작성하는 모든 것은 평범한 Markdown 페이지로, 특정 모델이 사라진 후에도 오랫동안 열고, 편집하고, 보관할 수 있습니다.

Claude / ChatGPT / Cursor
        │  MCP over HTTPS
        ▼
   athena-mcp ──── search ──▶ Wiki.js (keyword) + Postgres (meaning)
        │          read ────▶ Wiki.js
        └────────  write ───▶ Wiki.js ──▶ athena-indexer ──▶ Postgres

Wiki.js가 진실을 보유합니다. 벡터 인덱스는 단지 검색을 돕는 역할만 하며, 언제든지 삭제하고 재구축할 수 있습니다.

시작하기

빠른 시작 · AI 연결하기

사용하기

도구 · 대시보드

실제 운영하기

서버에 배포 · 백업

참고 자료

설정 · 보안 · 운영 · 개발


빠른 시작

로컬에서 약 5분이면 됩니다. 인터넷상의 모든 항목에 대해서는 먼저 서버에 배포를 읽어보세요.

git clone https://github.com/jannismilz/athena.git
cd athena
cp .env.example .env
$EDITOR .env          # fill in every CHANGE_ME, one per secret:
                      #   openssl rand -hex 32
docker compose up -d

그런 다음:

  1. Wiki.js를 열고 설정 마법사를 완료하세요.

  2. Wiki.js에서: 관리 → API를 활성화하고, 토큰을 생성한 후 .env 파일에 WIKI_API_TOKEN으로 저장하세요.

  3. docker compose up -d를 다시 실행하여 적용하세요.

  4. 대시보드를 열고 DASHBOARD_TOKEN으로 로그인하세요.

어떤 포트도 공개되지 않으므로, 서비스에 접근하려면 리버스 프록시를 사용하거나, 임시로 ports: 매핑을 추가하여 테스트해보세요.

첫 번째 시작 시 수백 MB 크기의 임베딩 모델을 다운로드합니다. 인덱서는 준비될 때까지 재시도하므로, 첫 부팅 시 1~2분 동안 embeddings의 상태가 비정상으로 보이는 것은 정상입니다.


AI 연결하기

모든 것은 MCP_PUBLIC_URL에서 제공되며, 이는 경로가 없는 순수한 https:// 오리진이어야 합니다. /mcp가 아닙니다.

Claude.ai → 설정 → 커넥터 → 사용자 지정 커넥터 추가

  • URL: https://athena-mcp.example.com/mcp

  • 클라이언트 ID와 시크릿은 비워두세요. Athena가 클라이언트를 직접 등록합니다.

  • 브라우저 페이지에서 비밀번호를 묻습니다. 이 비밀번호는 MCP_TOKEN입니다.

Cursor, Claude Desktop 및 기타 헤더 클라이언트

{
  "mcpServers": {
    "athena": {
      "url": "https://athena-mcp.example.com/mcp",
      "headers": { "Authorization": "Bearer YOUR_MCP_TOKEN" }
    }
  }
}

도구

도구

기능

search_knowledge

키워드 및 의미 검색, 융합됨. 모든 결과에는 경로가 포함됩니다.

get_page

한 페이지의 전체 Markdown

get_page_structure

제목 개요, 본문 제외

append_to_page

제목 아래에 추가, 나머지 부분은 그대로 유지

create_page

새 Markdown 페이지

update_page

페이지 본문 교체

move_page

이동 또는 이름 변경

delete_page

삭제 및 인덱스에서 제거

save_conversation

대화를 conversations/YYYY/MM/ 아래에 저장

capture_note

나중에 정리하기 위해 inbox/에 빠른 노트 저장

list_pages

모든 페이지, 경로 및 타임스탬프 포함

get_wiki_stats

크기, 구조, 오래된 정도 — AI가 무엇이 누락되었는지 답할 수 있도록 함

append_to_page는 알아둘 가치가 있는 도구입니다: 사실을 추가하는 것은 전체 페이지를 다시 쓰는 것이 아니라 한 단락만 추가하면 됩니다.

검색이 잘 되는 이유. 정확한 용어는 Wiki.js 전체 텍스트 인덱스를, 모호한 질문은 벡터 인덱스를 사용하며, 결과는 상호 순위 융합(reciprocal rank fusion)으로 융합되어 어느 한 소스도 다른 소스를 묻지 못합니다. 청크는 그 위에 있는 제목을 기록하므로, 반환된 결과는 문맥을 유지합니다. 어시스턴트가 접근한 모든 페이지는 모델이 자신에 대해 주장하는 내용이 아닌, 인증된 클라이언트에서 가져온 어시스턴트와 시간이 기록됩니다.


대시보드

자체 서비스로, 포트 8082에서 실행됩니다. DASHBOARD_TOKEN으로 로그인하며, URL에는 토큰이 없습니다. 스크립트의 경우 Bearer 헤더를 사용하세요:

curl -H "Authorization: Bearer $DASHBOARD_TOKEN" \
  https://wiki.example.com/dashboard/api/metrics?days=30

패널

제공 정보

콘텐츠

페이지, 단어, 영역별, 가장 큰 것, 오래된 것

AI 활동

일별 호출 수, 사용된 도구, 어시스턴트, 읽기 vs 쓰기

검색 결과 없음

위키가 답변하지 못한 내용

인덱스 상태

저장된 청크, 인덱싱된 페이지, 지연 정도

백업

마지막 실행 시점, 크기, 저장 위치

세 번째 행이 가장 가치 있는 부분입니다. 모든 항목은 작성할 가치가 있는 페이지입니다.

이중으로 읽기 전용입니다: 쓰지 않으며, athena_readonly 역할로 Postgres에 연결하는데, 이 역할은 SELECT만 보유하고 다른 권한은 없습니다. 수치는 Postgres에서 집계되고 캐시되므로, 새로고침 비용이 거의 없습니다.


서버에 배포

4GB VPS로 모든 것을 실행할 수 있으며, CPU에서 임베딩 모델도 포함됩니다.

1. 호스트 및 방화벽

sudo ufw default deny incoming && sudo ufw default allow outgoing
sudo ufw allow 22/tcp && sudo ufw allow 80/tcp && sudo ufw allow 443/tcp
sudo ufw enable

Docker를 설치한 후 배포를 소유할 사용자를 생성하세요:

sudo useradd --create-home --shell /bin/bash athena
sudo usermod -aG docker athena
sudo mkdir -p /srv/athena && sudo chown athena:athena /srv/athena

컴포즈는 해당 사용자로 실행하고, 절대 sudo를 사용하지 마세요. 그렇지 않으면 바인드 마운트가 root 소유가 됩니다. docker 그룹의 구성원은 호스트의 root와 동등하므로, 그룹을 작게 유지하세요.

2. DNS

호스트를 가리키는 두 개의 A 레코드:

이름

제공

wiki.example.com

Wiki.js 및 /dashboard/ 아래 대시보드

athena-mcp.example.com

MCP 엔드포인트

3. 설정

cd /srv/athena
git clone https://github.com/jannismilz/athena.git .
cp .env.example .env
chmod 600 .env        # it holds every secret

최소한 다음을 설정하세요:

ATHENA_DATA_DIR=/srv/athena/data
POSTGRES_PASSWORD=...
MCP_TOKEN=...
DASHBOARD_TOKEN=...
DASHBOARD_DB_PASSWORD=...
MCP_PUBLIC_URL=https://athena-mcp.example.com
WIKI_PUBLIC_URL=https://wiki.example.com

4. 리버스 프록시

어떤 컨테이너도 포트를 공개하지 않습니다. 모든 것은 athena Docker 네트워크에 있으며, 프록시가 이 네트워크에 연결됩니다. 다음을 라우팅하세요:

호스트

대상

비고

wiki.example.com

wikijs:3000

WebSocket 업그레이드, 100M 본문 제한

wiki.example.com/dashboard/

dashboard:8082

athena-mcp.example.com

mcp:8080

버퍼링 금지, MCP 스트림

X-Forwarded-For를 전달하세요: 로그인은 주소별로 속도 제한이 있으며, 전달하지 않으면 모든 시도가 프록시에서 온 것으로 보입니다.

nginx를 athena 네트워크에 연결된 컨테이너로 실행하거나, 호스트에서 127.0.0.1에 바인딩된 ports: 매핑으로 실행하세요.

server {
    listen 80;
    server_name wiki.example.com;

    location / {
        proxy_pass http://wikijs:3000;
        proxy_http_version 1.1;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade           $http_upgrade;
        proxy_set_header Connection        "upgrade";
        client_max_body_size 100M;
        proxy_read_timeout 120s;
    }

    location /dashboard/ {
        proxy_pass http://dashboard:8082/;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

server {
    listen 80;
    server_name athena-mcp.example.com;

    location / {
        proxy_pass http://mcp:8080;
        proxy_http_version 1.1;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # MCP streams responses. Without these, long tool calls appear to hang.
        proxy_set_header Connection "";
        proxy_buffering off;
        proxy_cache off;
        proxy_read_timeout 300s;
    }
}

그런 다음 certbot으로 인증서를 발급하거나, 이미 TLS를 종료하는 곳에서 처리하세요.

5. 시작한 후 위키 잠그기

docker compose up -d && docker compose ps

즉시 Wiki.js 마법사를 완료하세요. 완료하기 전까지는 호스트를 찾은 사람이 누구나 관리자 계정을 가져갈 수 있습니다. 그런 다음 Wiki.js에서:

  • 그룹 → 게스트: 읽기 접근을 제거하세요. 위키를 공개하려는 경우는 제외합니다.

  • 인증: 자체 등록을 끄세요.

  • API: 활성화하고 WIKI_API_TOKEN에 사용할 토큰을 생성하세요.

6. 확인

curl -s https://athena-mcp.example.com/health

# Must reject unauthenticated calls:
curl -s -o /dev/null -w '%{http_code}\n' -X POST https://athena-mcp.example.com/mcp
# expected: 401

백업

하나의 pg_dump가 완전한 백업입니다. Wiki.js는 페이지, 히스토리, 사용자, 권한, 설정, 그리고 업로드된 모든 파일의 바이트를 Postgres에 저장합니다. 업로드된 파일은 assetData 테이블에 있으며, data/wikijs/uploads 아래의 파일은 캐시일 뿐입니다. Athena의 활동 로그와 검색 벡터는 동일한 서버의 두 번째 데이터베이스에 있습니다.

데이터

백업에 포함

페이지, 히스토리, 사용자, 설정

업로드된 이미지 및 파일

활동 로그 및 검색 벡터

인덱스 관리 정보, OAuth 등록

아니요, 재구축 또는 재연결

.env

아니요, 비밀번호 관리자에 사본 보관

backup 컨테이너는 매시간 실행됩니다. 각 실행은 두 데이터베이스를 덤프하고, 모든 덤프가 읽을 수 있는지 확인하며, 로컬 사본을 보관하고, rclone 대상에 푸시한 후 업로드가 일치하는지 확인한 다음에만 정리합니다. 실패한 실행은 마지막으로 성공한 백업을 절대 삭제하지 않습니다.

docker compose run --rm backup now            # take one now
docker compose run --rm backup restore list   # see what exists
docker compose logs -f backup                 # watch the schedule

.env에서 완전히 설정하세요. 모든 rclone 대상이 작동합니다: S3, Backblaze, Wasabi, MinIO, Hetzner. BACKUP_REMOTE를 비워두면 호스트에만 백업을 보관합니다.

crypt 원격을 추가하고 BACKUP_REMOTE를 가리키세요. 그러면 대상은 파일 이름을 포함한 암호문만 수신합니다.

BACKUP_REMOTE=crypt:
RCLONE_CONFIG_CRYPT_TYPE=crypt
RCLONE_CONFIG_CRYPT_REMOTE=s3:my-bucket/athena
RCLONE_CONFIG_CRYPT_PASSWORD=<rclone obscure ...>
RCLONE_CONFIG_CRYPT_PASSWORD2=<rclone obscure ...>

두 비밀번호를 비밀번호 관리자에 보관하세요. 없으면 백업을 읽을 수 없습니다. 사용자 본인도 읽을 수 없습니다.

복원

필요하기 전에 연습하세요. 아무도 실행하지 않은 복원은 추측에 불과합니다.

docker compose run --rm backup restore list
docker compose stop wikijs mcp indexer dashboard
docker compose run --rm backup restore run 2026-08-18T115529Z
docker compose start wikijs mcp indexer dashboard

데이터베이스 이름을 입력하여 확인하라는 메시지가 표시됩니다. restore fetch <stamp>는 복원하지 않고 백업을 다운로드하며, 각 덤프가 읽을 수 있는지 보고합니다.

검색 인덱스는 이후 자체 복구됩니다: 인덱서가 모든 페이지를 다시 읽고 내용이 변경된 항목을 다시 임베딩합니다.


설정

모든 것은 환경에서 가져옵니다. 각 서비스는 부팅 시 자체 설정을 검증하고 잘못된 항목 목록과 함께 종료되므로, 오타는 새벽 3시가 아니라 즉시 실패합니다.

다섯 가지 비밀, 모두 사용자가 생성합니다. Claude, OpenAI 또는 다른 회사의 자격 증명은 .env에 저장되지 않습니다.

비밀

보유 주체

보호 대상

POSTGRES_PASSWORD

postgres, mcp, indexer

전체 데이터베이스 접근

WIKI_API_TOKEN

mcp, indexer

Wiki.js API

MCP_TOKEN

mcp

MCP 엔드포인트

DASHBOARD_TOKEN

dashboard

대시보드 로그인

DASHBOARD_DB_PASSWORD

dashboard, mcp, indexer

SELECT 전용 데이터베이스 역할

실행되는 서비스

서비스

포트

역할

postgres

내부

Wiki.js 데이터, 활동 로그, pgvector를 통한 벡터

wikijs

3000

읽고 편집하는 위키

embeddings

내부

임베딩 모델, CPU에서 실행

mcp

8080

AI가 연결하는 대상

indexer

8081

벡터 인덱스를 위키와 동기화 상태로 유지

dashboard

8082

메트릭

backup

없음

매시간 덤프, 확인, 푸시

별도의 벡터 데이터베이스는 없습니다. 벡터는 Postgres에 저장되므로, 하나의 백업으로 모든 것을 커버합니다.

ARM 호스트에서 embeddings 이미지는 linux/amd64용으로만 게시되므로 네이티브로 실행되지 않습니다. EMBEDDINGS_PROVIDER=openai를 Ollama와 같은 OpenAI 호환 엔드포인트로 지정하세요.

변수

기본값

설명

ATHENA_DATA_DIR

./data

모든 바인드 마운트의 루트 디렉터리

ATHENA_INSTANCE_NAME

Athena

로그인 페이지와 대시보드에 표시되는 이름

ATHENA_LOG_LEVEL

info

debug, info, warn, error

TZ

UTC

출처 스탬프 및 날짜 경로

POSTGRES_DB

wiki

Wiki.js 데이터베이스

ATHENA_DB

athena

활동 로그 및 벡터, 자동 생성됨

WIKI_LOCALE

en

콘텐츠 언어

WIKI_PUBLIC_URL

http://localhost:3000

대시보드 링크에 사용됨

MCP_PUBLIC_URL

필수

순수 https 출처, 경로 없음

METRICS_CACHE_SECONDS

60

대시보드 수치가 재사용되는 시간

EMBEDDINGS_MODEL

intfloat/multilingual-e5-small

변경 시 모든 항목 재색인

EMBEDDINGS_PROVIDER

tei

tei 또는 호환 가능한 엔드포인트용 openai

INDEX_INTERVAL_SECONDS

300

전체 동기화 간격

CHUNK_MAX_CHARS

1200

청크 크기 상한

BACKUP_*

.env.example 참조

일정, 보존 기간, rclone 대상

EMBEDDINGS_MODEL을 변경하면 벡터 너비가 변경되며, 두 모델의 벡터는 비교할 수 없으므로 인덱서가 테이블을 다시 빌드하고 모든 페이지를 다시 임베딩합니다. Wiki.js 콘텐츠는 영향을 받지 않습니다.


보안

각 컨테이너는 사용하는 자격 증명만 받습니다. 대시보드는 POSTGRES_PASSWORDWIKI_API_TOKEN도 받지 않으므로, 대시보드가 손상되어도 읽기 권한 이상은 얻을 수 없습니다. 언제든지 확인하세요:

docker inspect athena-dashboard -f '{{range .Config.Env}}{{println .}}{{end}}' | grep -iE 'PASSWORD|TOKEN'
  • 인증되지 않은 MCP 요청은 401 응답과 함께 설명 없이 거부됩니다.

  • 두 로그인 경로 모두 주소당 5회 실패 후 제한됩니다. 로그인 링크는 3회 시도 후 만료됩니다.

  • 대시보드 세션은 만료 시간과 nonce가 포함된 서명된 쿠키이며, 토큰은 절대 포함되지 않습니다. HttpOnly, SameSite=Strict이며, 교차 사이트 게시는 거부됩니다.

  • 비밀 비교는 일정 시간 내에 수행됩니다.

  • 프록시 헤더는 루프백에서만 신뢰되므로, 원격 클라이언트가 주소를 위조하여 제한을 회피할 수 없습니다.

  • 컨테이너는 루트가 아닌 사용자로 실행됩니다.

의도적으로 생략된 기능: 도구별 권한. 인증된 모든 클라이언트는 delete_page를 포함한 모든 도구를 호출할 수 있습니다. Wiki.js는 페이지 기록을 유지하므로 삭제는 복구 가능하지만, MCP_TOKEN을 위키에 대한 전체 쓰기 권한으로 취급하십시오. 또한 Athena는 단일 소유자를 가정합니다. Wiki.js에는 위키 읽기를 위한 자체 사용자가 있습니다.

MCP_TOKEN은 두 가지 방식으로 작동합니다. AI 클라이언트가 두 가지 방식으로 인증하기 때문입니다.

헤더 클라이언트(Cursor, Claude Desktop 등)는 Authorization: Bearer <MCP_TOKEN>을 전송합니다. 이것이 전체 메커니즘입니다.

브라우저의 Claude.ai는 그렇게 할 수 없습니다. 해당 사용자 지정 커넥터는 OAuth만 지원하며, MCP 사양은 동적 클라이언트 등록을 요구하므로, 브라우저 Claude를 수락하는 서버는 인증 서버가 되어야 합니다. Athena는 이를 구현합니다:

  1. Claude가 자체 등록하고 생성된 클라이언트 ID를 받습니다. 사용자의 비밀은 관여하지 않습니다.

  2. Claude가 사용자를 자체 서버의 로그인 페이지로 보냅니다.

  3. 사용자가 비밀번호로 MCP_TOKEN을 입력합니다. 이것이 사람의 승인 단계입니다.

  4. Athena가 자체적으로 생성한 Claude 토큰을 발급합니다.

해당 토큰은 data/mcp/oauth-state.json에 기록되며, 절대 .env에 기록되지 않습니다. 다음 명령으로 취소하세요:

rm data/mcp/oauth-state.json && docker compose restart mcp

브라우저 Claude를 사용하지 않는다면 이 모든 것을 무시하십시오. Bearer 경로는 이와 관련이 없습니다.


운영

docker compose logs -f mcp
curl -s localhost:8081/stats | python3 -m json.tool

# Force a full reconciliation
docker compose exec -T indexer bun -e 'await fetch("http://127.0.0.1:8081/sync",{method:"POST"})'

업그레이드. 항상 먼저 백업하십시오: Wiki.js는 시작 시 자체 마이그레이션을 실행하며, 컨테이너를 중지해도 되돌릴 수 없습니다.

docker compose run --rm backup now
git pull && docker compose build && docker compose up -d

증상

원인

서비스가 부팅 시 설정을 표시하며 종료됨

필수 변수가 누락되었거나 여전히 CHANGE_ME 상태임

Claude가 연결할 수 없고 로그인 페이지가 표시되지 않음

MCP_PUBLIC_URL에 경로가 있거나 https가 아님

올바른 비밀번호로 로그인이 거부됨

5회 실패 후 제한됨, 1분 기다리세요

시맨틱 검색 결과 없음

embeddings가 아직 다운로드 중임, 로그 확인

대시보드에 페이지가 뒤처져 표시됨

인덱서가 따라잡는 중임, 로그 확인

도구 호출이 401로 실패함

상태 파일이 지워졌거나 토큰이 변경됨, 클라이언트 재연결

Postgres가 "데이터베이스 파일이 호환되지 않음" 오류와 함께 종료됨

기존 데이터 아래에서 이미지 주요 버전이 변경됨

Postgres는 다른 주요 버전으로 작성된 데이터 디렉터리를 읽지 않습니다. 덤프, 삭제, 복원:

docker compose run --rm backup now             # on the OLD version
docker compose down
mv data/postgres data/postgres.old             # keep until you are happy
# edit the image tag in docker-compose.yml and the FROM line in
# docker/backup/Dockerfile to the same new major version
docker compose build backup
docker compose up -d postgres
docker compose run --rm backup restore run <stamp>   # once per database
docker compose up -d

벡터 인덱스는 다른 모든 것과 함께 복원되므로, 다시 임베딩할 필요가 없습니다.


개발

bun install
bun test          # 145 tests
bun run check     # typecheck, lint, test

패키지

설명

packages/core

Wiki.js 클라이언트, 청킹, 검색 병합, 벡터, 인증, 설정

packages/mcp

MCP 서버, OAuth 인증 서버, 도구

packages/indexer

동기화 루프, 임베딩, 벡터 쓰기, 내부 검색 API

packages/dashboard

메트릭 인터페이스

docker/backup

백업 및 복원 컨테이너

website/

단일 페이지 사이트

themes/wikijs/

선택적 Wiki.js CSS 및 JS

Bun은 TypeScript를 직접 실행하므로 빌드 단계가 없으며 컨테이너는 소스를 실행합니다. bun run --cwd packages/dashboard preview는 샘플 데이터로 preview.html을 생성합니다.

구성 방식:

  • 인덱서는 증분 방식입니다. 각 페이지의 지문을 생성하고 변경되지 않은 항목은 건너뛰므로, 변경되지 않은 위키를 한 번 처리하는 데 비용이 들지 않습니다.

  • 관리자 자격 증명이 있는 모든 서비스는 부팅 시 어드바이저리 락 아래에서 데이터베이스를 준비하므로 시작 순서는 중요하지 않습니다.

  • 대시보드는 인라인 SVG 차트가 포함된 서버 렌더링 HTML입니다. 클라이언트 JavaScript, 차트 라이브러리, 빌드 단계가 없습니다.

웹사이트 게시. website/index.html은 해당 파일을 건드리는 모든 푸시에서 GitHub Pages에 배포됩니다. 먼저 수동으로 Pages를 한 번 활성화하십시오: Settings → Pages → Build and deployment → Source: GitHub Actions. 이는 자동화할 수 없습니다. Pages 사이트를 생성하려면 관리 권한이 있는 토큰이 필요하며 GITHUB_TOKEN에는 해당 권한이 없기 때문입니다.


라이선스

Apache-2.0. LICENSE를 참조하십시오.

-
license - not tested
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • Driflyte MCP server which lets AI assistants query topic-specific knowledge from web and GitHub.

  • Person-owned, portable AI memory as a remote MCP server, readable and writable by any MCP client.

  • An MCP server that gives your AI access to the source code and docs of all public github repos

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jannismilz/athena'

If you have feedback or need assistance with the MCP directory API, please join our Discord server