Skip to main content
Glama
kristoffervp

Skolemelding MCP

by kristoffervp

Skolemelding MCP

English · Norsk

Read Skoleplattform Oslo messages and attachments through a local MCP server. Its three tools list messages, read a message, and download an attachment. They do not send replies or mark messages as read.

This is a simple local version that runs on your own computer. list_messages shows at most 100 messages; there is no keyword or date-range search yet. If you know a message ID, get_message can also find older messages by scanning up to 1,500 inbox entries. There is no fixed date cutoff in this code, but how far back it can reach depends on the Skolemelding service and how many newer messages you have.

At some Oslo schools, email notifications no longer include message contents or attachments. This MCP makes it easier to retrieve them from Skolemelding and use them in an agent workflow. You are responsible for deciding whether to share school information with ChatGPT or other cloud-based or commercial AI services.

Tested only on macOS with Google Chrome. Other platforms and browsers have not been tested.

Install

Install Node.js 20 or later and Google Chrome. In Terminal, open this project folder and run:

npm install
npm run login

Complete the ID-porten sign-in in Chrome. Run npm test to check the server without using your account.

Related MCP server: @injaan.dev/ms365-email-cli-mcp

Add to the ChatGPT desktop app (example)

Open Settings → MCP servers → Add server and choose STDIO. Enter:

Field

Value

Command to launch

Absolute path to Node.js; find it with command -v node

Arguments

One argument: absolute path to this project's src/server.js

Working directory

Absolute path to this project folder

Environment variables

Leave empty

Save, restart ChatGPT, then type /mcp in a chat to check the connection. Replace the example paths in the screenshot with your own. The pictured ~/code is only a placeholder for the working directory.

ChatGPT desktop MCP server setup showing the command, argument, and working directory fields

This screenshot shows just one setup example. The server can also work with Claude Desktop, Grok Build, or a client using a local AI model if that client supports local stdio MCP servers. Follow each client's setup instructions; a model alone cannot connect to MCP. ChatGPT in a web browser does not use this local setup.

Security and privacy

This MCP runs locally and does not open a network port. An AI client you connect can still retrieve school messages and attachments from your account. Content used with a cloud AI service may be sent to that service. Messages may also contain text intended to influence the agent. Use clients you trust, review tool calls, and never share the sign-in files in .data/.

The integration uses undocumented Skolemelding endpoints that may change. If your session expires, run npm run login again.

License

The code and documentation use the 0BSD license: free for anyone to use, change, and share for any purpose, including commercial use, without attribution. The license does not cover the Skolemelding service or its data.

To publish, use Git and check git status --short before committing. .gitignore excludes local sign-ins, research files, installed packages, and ZIP archives. Do not upload the whole folder manually.

Available Tools

3 tools
get_attachmentB

Get base64 bytes of a message attachment (maximum 10 MB).

ParametersJSON Schema
NameRequiredDescriptionDefault
attachment_idYes

TDQS

B3/5.0
Behavior3/5

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

With no annotations, the description carries the full behavioral burden, and it does add two genuinely useful facts: the return encoding (base64) and the 10 MB size cap. However, it is silent on what happens when an attachment exceeds the cap, permission/auth requirements, and failure modes.

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?

A single tight sentence with the return format and size limit front-loaded. No wasted words, though it is arguably under-specified rather than truly concise.

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 one-parameter read tool with no output schema, the description covers the essentials of what comes back and its size bound, but omits how to obtain the ID and the behavior on limit violations or errors.

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 coverage is 0% and the single attachment_id parameter has an unusual composite pattern (^\d+:\d+$) that is nowhere explained. The description says nothing about the parameter, so it fails to compensate for the coverage gap.

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?

States a specific verb ('Get') and resource ('message attachment'), and the parenthetical clarifies that raw base64 bytes are returned rather than metadata. It is distinguishable from get_message by the 'attachment' resource, though it never explicitly contrasts the two siblings.

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 on when to use this versus get_message, and no hint that the attachment_id must first be discovered via get_message. The agent is left to infer the retrieval workflow entirely.

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

get_messageB

Read full text and attachment metadata, including for unread messages, without changing their read status.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes

TDQS

B3.1/5.0
Behavior3/5

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

With no annotations, the description carries the full burden and does disclose one valuable non-obvious trait: reading does not flip an unread message to read status. It omits other behavioral facts such as what happens for an invalid or missing id, permission requirements, or error behavior.

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?

One front-loaded sentence with no filler. The critical behavioral constraint (no read-status change) is stated inline rather than buried, so nothing needs trimming or reordering.

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 one-parameter read tool with no output schema, the description covers the key side-effect concern but leaves the parameter, failure modes, and its boundary with get_attachment undefined. Adequate but with clear gaps for an agent to call it confidently.

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?

The single id parameter has no description in the schema (0% coverage) and the description says nothing about it. The schema's numeric pattern hints at format, but the description adds no meaning about which identifier is expected or where it comes from.

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?

States a specific verb (Read) and resource (full text and attachment metadata of a message), which is clear and unambiguous. It does not, however, distinguish itself from the sibling get_attachment, whose scope partially overlaps with 'attachment metadata', nor from list_messages.

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?

There is no explicit guidance on when to use this tool versus list_messages or get_attachment. The phrase 'including for unread messages' hints at a use case but never states conditions, exclusions, or the alternative to pick for other needs.

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

list_messagesB

List received Skolemelding messages with previews, unread state, and attachment names.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo

TDQS

B3.2/5.0
Behavior3/5

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

With no annotations, the description carries the full behavioral burden. It usefully discloses the returned field set (previews, unread state, attachment names) and the 'received' scope, but says nothing about pagination, ordering, limit behavior, or the read-only/safe nature of the call.

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?

A single front-loaded sentence with no filler; the returned-field enumeration is efficient. It is appropriately sized for a one-parameter list 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?

For a simple listing tool with one optional parameter and no output schema, the description covers what the tool is and roughly what it returns. It is incomplete on the things an agent needs to call it correctly — the meaning/effect of 'limit' and pagination behavior.

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% for the single 'limit' parameter, and the description never mentions it. Bounds and default exist only as bare schema constraints (1–100, default 30), so the description does not compensate for the missing pagination semantics.

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?

States a specific verb ('List') and resource ('received Skolemelding messages') plus the returned fields (previews, unread state, attachment names). It is implicitly distinguishable from get_message/get_attachment by being a bulk listing, but it never names those siblings or contrasts 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 Guidelines3/5

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

Usage is only implied — an agent can infer this is the inbox-browse step before calling get_message, but the description gives no explicit when-to-use, no exclusions, and no mention of the alternatives.

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. 3 tool updatesv0.2.0
    • First observedget_attachment
    • First observedget_message
    • First observedlist_messages

TDQS

A3.5/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: list_messages returns previews, get_message returns full text and attachment metadata, and get_attachment returns raw bytes. The boundaries between reading a message and fetching its attachment are clear and unlikely to be confused.

Naming Consistency5/5

All three tools follow a consistent verb_noun snake_case pattern: list_messages, get_message, get_attachment. The naming is predictable and easy to parse.

Tool Count4/5

Three tools is a reasonable minimum for a read-only message client, and each earns its place. However, it is on the low end, and a slightly larger surface for common read workflows could be expected.

Completeness3/5

The surface covers listing, reading, and downloading attachments, but it lacks any operation to mark messages as read, send/reply, or delete. For a messaging domain, these are notable missing operations that create dead ends for common workflows.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    A lightweight MCP server for personal Microsoft Outlook/Hotmail accounts, enabling email search, reading, attachment management, and folder operations via Microsoft Graph API with OAuth device-code flow.
    6
    1
    -
  • A
    license
    A
    quality
    D
    maintenance
    Deprecated MCP server wrapper for ms365-email-cli that exposes Microsoft 365 email operations (list, read, send, reply, search, etc.) as MCP tools. Use the main ms365-email-cli package instead, which now includes built-in MCP server support.
    10
    4 npm
    ISC
  • A
    license
    A
    quality
    D
    maintenance
    A local stdio MCP server that enables reading, sending, and searching emails, as well as listing calendar events via Microsoft Graph API, using device-code authentication.
    10
    54 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    An MCP server that reads, searches, organizes, and deletes Proton Mail through the local Proton Mail Bridge, with read-only mode and sender authentication checks. It cannot send mail.
    23 npm
    MIT