Skip to main content
Glama

liseur-mcp

Read-only MCP server for a liseur-sync instance: book catalog, reading statistics, highlights and EPUB chapter text, for any MCP client (opencode, Claude Desktop/Code, Cursor, ...).

It talks to the native /v1 API with a device token you mint for it. It never writes to the catalog or your reading state; the only side effect is that list_highlights(book_id=...) resolves the book to your per-user reading work, the same mapping every reading client makes.

Tools

Tool

What it does

list_folders

folders this account can read

list_books

books in a folder, newest first

search_books

search titles, descriptions, series, contributors, tags

get_book

one catalog record by id

reading_stats

totals, streak, pace, plus per-work rows

list_highlights

highlights/notes/bookmarks, for one book or the account

get_book_text

table of contents and chapter text (EPUB parsed locally)

Related MCP server: mcp-kindle

Scopes

Mint a dedicated device token with exactly:

  • library-read — folders, books, search, download

  • read-insights — reading statistics

  • sync — highlights and notes, and the book→work join

Run (stdio, for clients on this machine)

uv sync
export LISEUR_URL=https://books.example.ts.net
export LISEUR_TOKEN=...
uv run liseur-mcp

opencode (opencode.json), pointing at the venv binary so no uv lookup happens at startup:

{
  "mcp": {
    "servers": {
      "liseur": {
        "type": "local",
        "command": ["/path/to/liseur-mcp/.venv/bin/liseur-mcp"],
        "environment": {
          "LISEUR_URL": "https://books.example.ts.net",
          "LISEUR_TOKEN": "{env:LISEUR_TOKEN}"
        }
      }
    }
  }
}

Run (streamable HTTP, one endpoint for several agents)

export MCP_TRANSPORT=streamable-http
export MCP_HOST=0.0.0.0
export MCP_AUTH_TOKEN=...   # required: the endpoint has no anonymous mode
export LISEUR_URL=... LISEUR_TOKEN=...
uv run liseur-mcp

Clients connect to http://<host>:8000/mcp with Authorization: Bearer $MCP_AUTH_TOKEN. In opencode:

{
  "mcp": {
    "servers": {
      "liseur": {
        "type": "remote",
        "url": "http://<host>:8000/mcp",
        "oauth": false,
        "headers": { "Authorization": "Bearer {env:LISEUR_MCP_TOKEN}" }
      }
    }
  }
}

Keep it on your LAN or behind your reverse proxy; the bearer token is the only door.

Docker

docker build -t liseur-mcp .
docker run -d --name liseur-mcp --restart unless-stopped \
  -e MCP_TRANSPORT=streamable-http -e MCP_HOST=0.0.0.0 \
  -e MCP_AUTH_TOKEN -e LISEUR_URL -e LISEUR_TOKEN \
  -p 8000:8000 liseur-mcp

Environment

Variable

Default

Meaning

LISEUR_URL

required

base URL of the instance

LISEUR_TOKEN / LISEUR_TOKEN_FILE

required

device token secret

MCP_TRANSPORT

stdio

stdio or streamable-http

MCP_HOST / MCP_PORT / MCP_PATH

127.0.0.1 / 8000 / /mcp

HTTP listener

MCP_AUTH_TOKEN / MCP_AUTH_TOKEN_FILE

required for HTTP

bearer token clients present

MCP_ALLOWED_HOSTS

localhost

Host headers the HTTP transport accepts

LISEUR_TIMEOUT_SECONDS

30

upstream request timeout

Develop

uv sync
uv run pytest
uv run ruff check
uv run pyright

Available Tools

7 tools
get_bookA

Fetch one catalog record by book_id (same shape list_books returns).

ParametersJSON Schema
NameRequiredDescriptionDefault
book_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full responsibility. It clearly indicates a read operation ('Fetch') and implies non-destructive behavior, but it doesn't disclose behaviors like not-found handling, error conditions, or any authentication requirements. The 'same shape' note is helpful but minimal.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence with zero filler. It front-loads the core action and parameter, and the 'same shape' note is efficient. Every word serves a purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has an output schema, so return values are covered. For a simple get-by-ID tool, the description provides enough to call it correctly if you know book_id, but it omits explicit guidance on when to prefer this over list_books or search_books, and lacks any prerequisite information (e.g., how to obtain a valid book_id). It's sufficient but not comprehensive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate. It names book_id as the lookup key and implies it comes from list_books (via 'same shape list_books returns'), but it doesn't elaborate on its format, provenance, or any constraints beyond the schema's type string. This is adequate but not enriching.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Fetch'), a resource ('catalog record'), and the key parameter ('by book_id'). It also notes the return shape matches list_books, which differentiates it from siblings like get_book_text (text) and search_books (multiple results). This is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when you have a book_id and need a single catalog record, and the 'same shape list_books returns' hint suggests you might already have the data from list_books. However, it doesn't explicitly state when not to use it or name alternatives, so it lacks explicit exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_book_textA

Read the text of a book, one chapter at a time.

    Without chapter: returns the table of contents (index, title, chars).
    With chapter: that chapter's text, cut to max_chars from offset;
    next_offset continues when the chapter is longer. The EPUB is
    downloaded from the server and parsed on each call.
    
ParametersJSON Schema
NameRequiredDescriptionDefault
offsetNo
book_idYes
chapterNo
max_charsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It discloses that the EPUB is downloaded and parsed on each call, which implies network/processing cost and statelessness. It also explains the return behavior for both modes and the pagination continuation mechanism. It doesn't mention error cases or rate limits, but the core behavioral traits are well covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded with the core purpose. The two-mode behavior is explained in a few lines, and the pagination detail is placed after the main use case. Every sentence earns its place; no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the main behaviors, pagination, and the per-call parsing cost. It doesn't describe the output schema in detail, but an output schema exists, so that is acceptable. It could mention error conditions or the meaning of next_offset more explicitly, but for a read tool with a clear schema, it is largely complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explains the meaning of chapter (null vs integer), offset, max_chars, and next_offset behavior. It doesn't explicitly define book_id, but that is self-evident from the tool name and schema. The description adds meaningful semantics beyond the raw schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool reads book text one chapter at a time, and distinguishes the no-chapter case (table of contents) from the with-chapter case (chapter text). It names the resource (book text) and the specific behavior (pagination via offset/max_chars), which differentiates it from siblings like get_book or search_books.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains the two usage modes (without chapter vs with chapter) and how pagination works (max_chars, offset, next_offset). It doesn't explicitly say when to use this tool over siblings like get_book or list_books, but the chapter-by-chapter reading behavior is clear enough to imply the use case. No explicit exclusions or alternatives are named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_booksA

List books in one folder.

    order: "recent" (newest first, default) or "oldest". limit: 1-200.
    Returns full catalog records: book_id, title, contributors, series, tags.
    
ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
orderNorecent
folder_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral disclosure burden. It discloses the return format (full catalog records with listed fields), parameter constraints (order values, limit range), and defaults. It does not explicitly state read-only status or error behavior, but the read-only nature is strongly implied by 'list', and the constraints add practical transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: purpose first, then parameter details and output fields. Every sentence adds value, with no fluff or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity and presence of an output schema, the description covers purpose, parameters, and output fields sufficiently. It lacks explicit error or pagination notes, but for a basic listing tool, the provided details are adequate for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must explain parameters. It explicitly defines 'order' (recent/oldest, default) and 'limit' (1-200, default 50), and 'folder_id' is implicitly clear from 'in one folder'. This adds meaning beyond the schema, though folder_id is not explicitly named.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists books within a specific folder, using a precise verb and resource. This distinguishes it from siblings like search_books (search) and get_book (single item), and the scope is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for listing all books in a given folder but provides no explicit guidance on when to choose this over alternatives like search_books or get_book. It does not mention exclusions or alternative conditions, so the agent must infer appropriate use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_foldersA

List the library folders this account can read.

    Each folder carries a folder_id to pass to list_books and search_books.
    
ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It implies read-only access ('can read') but doesn't explicitly state side effects, authentication requirements, or return behavior. It only mentions the folder_id field, leaving other behavioral aspects undisclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no redundancy, front-loading the purpose and adding a key pointer to folder_id usage.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Simple tool with no parameters and an output schema, so description doesn't need to detail return values. It covers purpose and how to use the result, sufficient for an agent to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Tool has zero parameters, so baseline is 4. The description doesn't need to explain parameters, but it does mention the folder_id that is returned, which is useful context for other tools.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists library folders readable by the account. It distinguishes from sibling tools by focusing on folders rather than books or other resources, though it doesn't explicitly name alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explains that each folder has a folder_id to pass to list_books and search_books, giving clear usage context. However, it doesn't explicitly mention when not to use this tool or compare with other siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_highlightsA

List highlights, notes and bookmarks.

    With book_id: the annotations of that book. The first call joins the
    catalog book to your reading work — a per-user mapping; nothing shared
    changes. Without book_id: every live annotation on the account, each
    carrying its work_id.
    
ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
book_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses a notable behavioral trait: the first call with book_id joins the catalog book to the user's reading work, creating a per-user mapping without changing shared data. This goes beyond the schema and annotations (which are absent), providing useful context about side effects and scope.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded with the core purpose, then explains the two modes. The sentence about the per-user mapping is slightly dense but earns its place as important behavioral context. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has an output schema and only two optional parameters, the description covers the key decision (book_id vs no book_id) and the important side-effect behavior. It doesn't mention pagination or rate limits, but the output schema likely covers return structure. Adequate for a list tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explains the meaning of book_id (filter to that book's annotations) and the default behavior without it (all live annotations). It doesn't detail limit, but limit is self-explanatory and has a default. This is strong compensation for the schema gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists highlights, notes, and bookmarks, and distinguishes two modes: with book_id (annotations of that book) and without (all live annotations on the account). This is specific and differentiates it from siblings like list_books or get_book.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains when to use each mode: with book_id for a specific book's annotations, without for all account annotations. It doesn't explicitly name alternatives or exclusions, but the context is clear enough for an agent to choose correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

reading_statsA

Reading totals, streak and pace over a span, plus per-work rows.

    range is a number of days ("7d", "30d") or "all". Per-work rows are
    ordered by time read and capped at 50; current_progression is always
    the latest position regardless of the span.
    
ParametersJSON Schema
NameRequiredDescriptionDefault
rangeNo30d

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses that results are capped at 50 and that current_progression is always the latest position, which is useful behavioral detail. Since no annotations exist to convey safety or mutation hints, this is helpful but not exhaustive; for example, it doesn't state whether it is read-only, but the tool name implies a read operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded with the main purpose, followed by parameter and output details in two paragraphs. Every sentence adds value, with no fluff, though the formatting with blank lines could be slightly tighter.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a simple single-parameter tool and an output schema present, the description covers the essential usage details: range format, output structure, ordering, and cap. It is sufficient for an agent to call it correctly, though it could mention the default value explicitly, which is already in the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% description coverage, so the description must compensate. It does partially: it explains that range is a number of days like '7d' or 'all'. However, it doesn't specify the full default behavior (default is '30d') or the exact format beyond examples, leaving some ambiguity.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool provides reading totals, streak, pace, and per-work rows over a span. It does not explicitly differentiate from siblings like list_books or list_highlights, but the resource (reading statistics) is distinct enough that a capable agent can infer its purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It describes the range parameter format and what the results include (per-work rows ordered by time read, capped at 50), which gives clear context for when to use it. However, it doesn't explicitly mention alternatives or when not to use this tool, so it's slightly short of an explicit routing guide.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_booksA

Search titles, descriptions, series, contributors and tags.

    Searches every folder when folder_id is omitted. Results are best
    matches per folder, not alphabetically ordered.
    
ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes
folder_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the burden of behavioral disclosure. It reveals that results are per‑folder best matches, not alphabetically ordered, and that folder scoping is optional. It does not cover rate limits, authentication, or empty‑query behavior, but the output schema handles return structure, so a 4 is warranted.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero waste. The purpose is front‑loaded, and the behavioral notes (folder scope and ordering) follow logically. Efficient and scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The output schema covers return values, so the description need not explain that. It explains the search fields, the folder‑scoping behavior, and the ordering. Missing pieces are the limit parameter's effect and any query syntax expectations (e.g., wildcards). For a straightforward search tool, this is largely complete, but the limit gap keeps it from a 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It only implicitly explains folder_id ('Searches every folder when folder_id is omitted'). It says nothing about the query parameter's semantics (e.g., partial matches, case sensitivity) or the limit parameter's role. Two of three parameters remain undocumented semantically.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Search') and resource ('titles, descriptions, series, contributors and tags'). Clearly distinguishes from siblings like list_books (which lists all) and get_book (which fetches a specific book).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context: omitting folder_id searches every folder, implying folder_id scopes the search. However, it does not explicitly contrast with alternatives (e.g., list_books) or state when not to use it, so it stops short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 7 tool updatesv0.1.0
    • First observedget_book
    • First observedget_book_text
    • First observedlist_books
    • First observedlist_folders
    • First observedlist_highlights
    • First observedreading_stats
    • First observedsearch_books

TDQS

A4/5.0

Scored across 7 tools

Disambiguation5/5

Each tool maps to a distinct resource or action: folders, catalog records, book lists, search, stats, highlights, and full text. Even the similarly named get_book and get_book_text are clearly separated by descriptions (metadata vs. chapter text).

Naming Consistency4/5

Most tools follow a verb_noun snake_case pattern (list_books, search_books, get_book_text). reading_stats is the one outlier as a noun phrase, so the pattern is not perfectly uniform.

Tool Count5/5

Seven tools is a well-scoped size for a reading/librarian server. Each tool covers a meaningful part of the workflow without redundancy.

Completeness4/5

The surface covers discovery, metadata, text access, highlights, and reading statistics, which are the core read-only operations. Minor gaps exist around pagination/limits for large catalogs or highlight lists, but agents can usually work around them.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Read-only MCP server for accessing local Kindle library data, exposing tools to query profile, health, and book metadata.
    MIT
  • F
    license
    A
    quality
    C
    maintenance
    Read-only MCP server that provides tools to search books, get book details, list authors, and view library statistics from a PostgreSQL database.
    5
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    A read-only MCP server for an existing Calibre ebook library, enabling metadata search, full-text search, and category browsing via the Model Context Protocol.
    MIT