Skip to content
Merged
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
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ repos:
- id: mypy
args: ["--config-file=pyproject.toml"]
exclude: ^tests/
additional_dependencies:
- "pydantic>=2.0"

- repo: https://github.com/crate-ci/typos
rev: typos-dict-v0.11.2
Expand Down
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,25 @@ An LLM agent built using Model Context Protocol to play online games

# 🏃 How do I get started?
If you haven't already done so, please read [DEVELOPMENT.md](DEVELOPMENT.md) for instructions on how to set up your virtual environment using Poetry.

# Pre-requisites

- `uv` installable via brew.
- [Claude Desktop](https://claude.ai/download)
- Create [Lichess account](https://lichess-org.github.io/api-demo/) and [API key](https://lichess.org/api).

Set up project:

```bash
make project-setup
```

# Quick Start

1. Install server in Claude Desktop:

```bash
uv run mcp install agent_uno/server.py
```

2. Interact with MCP server with Claude Desktop.
50 changes: 50 additions & 0 deletions agent_uno/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"""An MCP server for playing Chess with LiChess.

Aim:
# 1. Agent logs in with an API key
# 2. Agent is able to start a game
# 3. Agent is able to play the game by getting the current state and making moves.
"""
import datetime

from berserk import Client, TokenSession # type: ignore [import-not-found]
from mcp.server.fastmcp import FastMCP # type: ignore [import-not-found]
from pydantic import BaseModel, Field


class AccountInfo(BaseModel):
"""The account info of a LiChess user."""

id: str
username: str
perfs: dict[str, dict[str, int | bool]]
created_at: datetime.datetime = Field(alias="createdAt")
seen_at: datetime.datetime = Field(alias="seenAt")
play_time: dict[str, int] = Field(alias="playTime")
url: str
count: dict[str, int]
followable: bool
following: bool
blocking: bool


mcp = FastMCP("chess-mcp", dependencies=["berserk"])

session_state = {}


@mcp.tool(description="Login to LiChess.") # type: ignore
async def login(api_key: str) -> None:
"""Login to LiChess using the provided API key.

Args:
api_key: The API key to use for logging in.
"""
session = TokenSession(api_key)
session_state["client"] = Client(session)


@mcp.tool(description="Get account info.") # type: ignore
async def get_account_info() -> AccountInfo:
"""Get the account info of the logged in user."""
return AccountInfo(**session_state["client"].account.get())
9 changes: 6 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
name = "agent_uno"
version = "0.0.1"
description = "An LLM agent built using Model Context Protocol to play online games package."
authors = [
{ name = "Fuzzy Labs", email = "info@fuzzylabs.ai" },
]
authors = [{ name = "Fuzzy Labs", email = "info@fuzzylabs.ai" }]
readme = "README.md"
requires-python = ">=3.12,<4.0"
dependencies = [
"berserk>=0.13.2",
"mcp[cli]>=1.6.0",
"pydantic>=2.11.1",
]

[dependency-groups]
dev = ["pytest>=7.2.0", "pytest-cov>=4.0.0", "licensecheck>=2024.1.2"]
Expand Down
Loading