Skip to main content
Glama

METU SAIS API & MCP Server

Современный сервер Model Context Protocol (MCP) и сервис FastAPI для информационной системы Student Affairs Information System (SAIS / student.metu.edu.tr) Ближневосточного технического университета (METU / ODTÜ).

Подключает ваших ИИ-ассистентов (таких как OpenCode, Claude Desktop и Cursor) напрямую к METU SAIS с реальной аутентификацией и структурированным разбором данных.


Возможности

  • Аутентификация SSO: Обрабатывает реальный процесс входа в METU SSO (/sso/backend/request/user/signin) и проверку токенов сеанса.

  • Прокси-скрапер и HTML-парсер: Автоматически устанавливает аутентифицированные прокси-сеансы (/proxy/Student_Information/) и преобразует записи студентов в структурированный JSON.

  • MCP-сервер (MCP 2.x SDK): Предоставляет типизированные инструменты через стандартный ввод-вывод (stdio).

  • REST-сервис FastAPI: Альтернативный HTTP REST-бэкенд для интеграций.

  • Конфиденциальность и безопасность: Никакого логирования или раскрытия учетных данных. Учетные данные остаются локально в вашем файле .env, который игнорируется Git.


Related MCP server: SABIS MCP Server

Доступные MCP-инструменты

Tool

Description

get_student_info

Получает ID студента, имя, факультет, семестр, GPA/CGPA, академический статус и научного руководителя.

get_schedule

Получает еженедельное расписание занятий (дни, часы, коды курсов, названия курсов, аудитории, преподавателей).

get_transcript

Получает академическую справку за все семестры с курсами, кредитами, оценками и статистикой GPA по семестрам.

get_announcements

Получает активные объявления портала.

create_connection

Создаёт запись соединения в памяти.

list_connections

Выводит список всех сохранённых записей соединений.


Установка и настройка

1. Предварительные требования

  • Python >= 3.11

  • uv (рекомендуется) или pip

2. Установка зависимостей

# Using uv (recommended)
uv sync

# Or using pip
pip install -e .

3. Настройка учетных данных

Скопируйте .env.example в .env и введите свои учетные данные METU:

cp .env.example .env

Отредактируйте .env:

SAIS_USERNAME=your_metu_username
SAIS_PASSWORD=your_metu_password
LOCALE=tr
PORT=8300

[!NOTE] .env указан в .gitignore и никогда не будет закоммичен.


Использование с OpenCode

В этот репозиторий уже включён файл opencode.json.

Использование на уровне проекта

При запуске OpenCode внутри этого репозитория:

opencode

OpenCode автоматически подключится к MCP-серверу metu-sais.

Глобальное использование (из любой директории)

Чтобы использовать инструменты METU SAIS в любом проекте OpenCode, добавьте сервер в ~/.config/opencode/opencode.jsonc:

{
  "mcp": {
    "metu-sais": {
      "type": "local",
      "command": [
        "uv",
        "--directory",
        "/absolute/path/to/metu-sais-mcp",
        "run",
        "metu-sais-mcp"
      ],
      "enabled": true
    }
  }
}

Проверка подключения

opencode mcp list

Вы должны увидеть:

●  ✓ metu-sais connected

Запуск MCP-сервера отдельно

Вы можете запустить MCP-сервер напрямую через стандартный ввод-вывод:

uv run metu-sais-mcp

Запуск REST API

Чтобы запустить сервер FastAPI:

uv run uvicorn api.main:app --port 8300 --reload

Интерактивная документация API будет доступна по адресу:

REST-эндпоинты

  • GET /api/sais/info — Информация о студенте

  • GET /api/sais/schedule — Расписание занятий

  • GET /api/sais/transcript — История успеваемости

  • GET /api/sais/announcements — Объявления портала

  • GET|POST|PUT|DELETE /api/connections — CRUD-управление соединениями


Тестирование

Запустите автоматический набор тестов с помощью pytest:

uv run pytest -v

Набор тестов включает:

  • Модульные тесты для HTML-парсеров (parse_student_info, parse_schedule, parse_transcript, parse_announcements).

  • Тесты регистрации MCP-инструментов и вызова инструментов.

  • Тесты REST-эндпоинтов FastAPI.

  • Живые интеграционные тесты с METU SAIS при настроенных учетных данных.


Структура проекта

├── sais/
│   ├── connector.py      # Core SAIS authentication, proxy scraping, and HTML parsers
│   └── connections.py    # Shared in-memory connection store
├── sais_mcp/
│   └── server.py         # MCP stdio server definition and tool registrations
├── api/
│   └── main.py           # FastAPI REST API wrapper
├── tests/
│   ├── test_connector.py # Scraper and HTML parser tests
│   ├── test_mcp_server.py# MCP server tests
│   └── test_api.py       # FastAPI tests
├── .env.example          # Environment variable template
├── opencode.json         # OpenCode MCP configuration
├── pyproject.toml        # Package dependencies and CLI entrypoints
└── README.md             # Project documentation

Лицензия

Лицензия MIT.

Available Tools

6 tools
create_connectionC

Yeni bir bağlantı kaydı oluşturur.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
descriptionNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior2/5

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

With no annotations, the description must carry the behavioral burden, but it only says 'creates a new connection record.' It does not disclose duplicate handling, required permissions, idempotency, or any side effects beyond the basic creation action.

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 short sentence with no filler, repetition, or unnecessary detail. It is front-loaded and every word earns its place, even though the overall content is minimal.

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

Completeness2/5

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

Although the output schema removes the need to document return values, this is a state-changing tool with no annotations and no usage or parameter guidance. The description lacks context about what a connection record represents, when to create one, and what happens on duplicate or invalid input, so it is not complete enough for confident invocation beyond the basic action.

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

Parameters1/5

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

Schema description coverage is 0%, and the description adds no meaning to the 'name' or 'description' parameters. It does not clarify what a valid name should be, whether names must be unique, or how the description field is used, so it provides no value beyond the schema's property titles.

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 distinct action ('Yeni bir bağlantı kaydı oluşturur' / creates a new connection record) with a clear verb and resource. Among sibling tools, it is the only create-style action, so an agent can distinguish it from list_connections and the various get_* tools without opening the schema.

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

Usage Guidelines2/5

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

The description gives no guidance about when to use this tool versus list_connections or other siblings. It only defines the action, leaving the agent to infer prerequisites, typical triggers, or alternatives.

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

get_announcementsB

METU SAIS öğrenci portalındaki güncel duyuruları alır.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.4/5.0
Behavior3/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 signals a read-only retrieval action ('alır') and restricts scope to 'current' announcements, but it does not mention authentication needs, caching, or any other operational traits. This is acceptable for a zero-parameter fetch but not richly transparent.

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, front-loaded sentence with no filler. Every word contributes to identifying the source and content of the tool.

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 is very simple (no parameters, output schema present), so the description covers the basic action. However, it omits any context about whether an existing connection or authentication is required, which is relevant given sibling tools create_connection and list_connections. The absence of annotations makes this a modest gap.

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?

The input schema has zero parameters and 100% coverage, so there are no parameter semantics to clarify. The baseline for a zero-parameter tool is 4, and the description adds no conflicting parameter information.

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 identifies the action ('alır' / gets) and the resource ('METU SAIS öğrenci portalındaki güncel duyurular' / current announcements from the METU SAIS student portal). It is specific but does not explicitly differentiate from sibling tools like get_schedule or get_transcript, though the announcement subject is distinctive.

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

Usage Guidelines2/5

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

No guidance is provided on when to use this tool versus alternatives, nor any exclusions or prerequisites. The name and resource imply 'use when you need announcements,' but the description does not state this or mention sibling tools.

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

get_scheduleB

METU SAIS'ten haftalık ders programını alır. Belirli bir dönem kodu (ör. '20251|1') verilebilir.

ParametersJSON Schema
NameRequiredDescriptionDefault
semesterNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.1/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 behavioral disclosure responsibility. It mentions an optional semester code but does not disclose default behavior when omitted, authentication needs, rate limits, or any other operational characteristics.

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 short sentences with the main purpose front-loaded and the optional parameter explained second. Every word earns its place; there is no redundancy.

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?

For a simple retrieval tool with an output schema and one optional parameter, the description is adequate for basic invocation. However, it lacks usage context and default behavior, making it minimally viable rather than fully complete.

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%, but the description partially compensates with a concrete example semester code ('20251|1') and clearly indicates the parameter is optional. It does not explain what null means or fully define the accepted format.

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 states a specific verb ('alır' – retrieves) and a specific resource: the weekly course schedule from METU SAIS. It is clearly distinct from sibling tools like get_transcript and get_announcements, though it does not explicitly contrast itself with them.

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

Usage Guidelines2/5

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

No guidance is given about when to use this tool versus alternatives, and there are no exclusions or conditions. An agent must infer usage solely from the resource name.

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

get_student_infoC

METU SAIS'ten öğrenci temel bilgilerini, danışmanını, GPA/CGPA ve kayıt durumunu alır.

ParametersJSON Schema
NameRequiredDescriptionDefault
semesterNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior3/5

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

The description conveys a read-only retrieval operation and lists the data included, which is useful behavioral content. However, with no annotations provided, it does not disclose connection/auth requirements, semester handling, or possible error behavior, leaving meaningful gaps.

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 concise sentence with no filler. It front-loads the source and the key data scopes, so it is easy to parse quickly.

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

Completeness2/5

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

Given the simple one-parameter schema and no annotations, the description is incomplete because it omits the only parameter's semantics and any dependency on connections. The output schema may explain return structure, but behavioral and invocation context remain underspecified.

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

Parameters1/5

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

Schema description coverage is 0% and the description never mentions the 'semester' parameter. The agent receives no explanation of the semester value format, whether it is needed, or how it affects the returned GPA/CGPA and registration status.

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 uses a specific verb ('alır') and names a concrete resource: student basic info, advisor, GPA/CGPA, and registration status from METU SAIS. It is clear what the tool returns, though it does not explicitly contrast itself with sibling tools like get_schedule or get_transcript.

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

Usage Guidelines2/5

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

No guidance is given about when to use this tool instead of alternatives such as get_transcript or get_schedule. There are no conditions, exclusions, or prerequisites mentioned, so the agent must infer usage solely from the tool name and sibling names.

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

get_transcriptA

METU SAIS'ten tüm dönemleri, alınan dersleri, harf notlarını, kredileri ve GPA geçmişini (transkript) alır.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/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 of behavioral disclosure. It explicitly says the tool retrieves all semesters and the full transcript data, making the operation's scope clear. It does not discuss auth, rate limits, or failure modes, but for a zero-parameter read operation the enumerated retrieval behavior is sufficient.

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?

A single dense sentence leads with the source and then lists the exact data elements. There is no filler, no repetition of the tool name, and every phrase adds information.

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?

For a no-parameter getter with an output schema, the description covers the source and contents well, and return values are likely already documented by the output schema. The only minor gap is that it does not mention whether an existing connection is required, especially given sibling tools like create_connection and list_connections.

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?

The tool has zero parameters, so there are no parameter semantics for the description to clarify. The baseline score of 4 applies, and the description appropriately focuses on what data is returned rather than input options.

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 action ('alır' - gets), a specific resource (METU SAIS transcript), and enumerates the exact contents: all semesters, courses, letter grades, credits, and GPA history. This clearly differentiates it from siblings like get_student_info and get_schedule.

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 clearly implies the tool should be used when a transcript is needed, but it never explicitly states when to use it versus alternatives or when not to use it. Sibling tools such as get_student_info and get_schedule could partially overlap, so an explicit routing hint would help, but the context is reasonably clear.

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

list_connectionsA

Mevcut tüm bağlantı kayıtlarını listeler.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

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

With no annotations, the description carries the burden of behavioral disclosure. It communicates a read-only 'list all' operation, which is useful, but it adds no further behavioral context such as ordering, scope limitations, or pagination. The output schema presumably covers return shape.

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 front-loaded sentence with no filler. Every word contributes to identifying the action and resource.

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?

For a parameterless read-only list tool with an output schema, the description is largely complete. The main gap is that the term 'connection records' is left ambiguous, but the operation itself is fully specified.

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?

The tool has zero parameters, so the input schema is empty and there are no parameter semantics to explain. The baseline for zero-parameter tools is 4, and the description does not need to compensate for anything.

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 uses a specific verb ('listeler'/'lists') and identifies the resource ('bağlantı kayıtları'/'connection records'), making the tool's purpose reasonably clear. It does not fully define what a 'connection' is in this domain, so it falls short of a 5.

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

Usage Guidelines2/5

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

No guidance is given about when to use this tool instead of siblings like create_connection. There is no stated context, prerequisite, or exclusion, so the agent must infer usage entirely.

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. 6 tool updatesv0.1.0
    • First observedcreate_connection
    • First observedget_announcements
    • First observedget_schedule
    • First observedget_student_info
    • First observedget_transcript
    • First observedlist_connections

TDQS

A3.5/5.0

Scored across 6 tools

Disambiguation5/5

Each tool targets a clearly distinct resource or action: student info, schedule, transcript, announcements, and connection records. There is no meaningful overlap that would cause an agent to select the wrong tool.

Naming Consistency5/5

Tool names follow a consistent snake_case verb_noun pattern: get_student_info, get_schedule, get_transcript, get_announcements, create_connection, list_connections. The only minor variation is singular vs plural nouns, but the pattern is predictable.

Tool Count5/5

Six tools is a well-scoped set for a student portal MCP server. It covers the core read operations and adds connection management without bloating the surface.

Completeness3/5

The student-facing read operations are solid, but connection management is incomplete: create_connection and list_connections have no corresponding update or delete operation, creating a lifecycle dead end. Minor gaps like course-level detail or exam results are less critical but still absent.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    B
    quality
    D
    maintenance
    An MCP server that enables AI agents to authenticate with and interact with Open eClass platform instances, supporting UoA's SSO authentication system for retrieving course information and performing basic platform operations.
    4
    8
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables students to securely access and manage their academic data from Isparta University's OBS system, including grades, transcripts, announcements, and course information through natural language queries.
    1
    -
  • A
    license
    B
    quality
    A
    maintenance
    Unofficial local MCP server for Istanbul Technical University (İTÜ) students. Reads your own Ninova LMS, OBS and Portal data with your own account: assignments and deadlines, grades and cumulative GPA simulation, schedule and exams, registration, course archive, library and campus services. Read-only by default; the two write tools ask for confirmation.
    55
    13
    MIT