goalslot-mcp

goalslot-mcp

Enables AI assistants to manage goals, tasks, weekly schedules, time tracking, reports, notes, and journal entries on a GoalSlot account through MCP tools.

Category
访问服务器

README

goalslot-mcp

An MCP server for GoalSlot. It gives an AI assistant tools for goals, tasks, the weekly schedule template, time tracking, the shared timer, reports, notes and the journal, against your own GoalSlot account.

Runs over stdio, so any MCP host can spawn it. Ships four skills that teach a model how to use the tools well.

Install

You need the goalslot CLI signed in first, because this server reads the credential the CLI writes. It never runs a login flow itself.

npm install -g goalslot-cli
goalslot login

Then add the MCP server to Claude Code:

claude mcp add goalslot -- npx -y goalslot-mcp

For Claude Desktop, or any host that takes a JSON config:

{
  "mcpServers": {
    "goalslot": {
      "command": "npx",
      "args": ["-y", "goalslot-mcp"]
    }
  }
}

Check it is working:

npx -y goalslot-mcp --list-tools

This package is not published to npm yet. Until it is, install it from source: clone the repo, npm install && npm run build, then point the host at node /path/to/goalslot-mcp/dist/cli.js.

How auth works

There is no login flow in this server. stdio is the protocol channel, so a server cannot prompt for anything, and asking a model to handle a token would be worse. It reads a credential that already exists on the machine.

Resolution order:

  1. GOALSLOT_ACCESS_TOKEN from the environment, if set and non-empty.
  2. $GOALSLOT_CONFIG_DIR/credentials.json.
  3. %APPDATA%\goalslot\credentials.json on Windows.
  4. $XDG_CONFIG_HOME/goalslot/credentials.json, else ~/.config/goalslot/credentials.json.

The file is written by goalslot login and shared with the CLI. Its shape:

{
  "version": 1,
  "apiBaseUrl": "https://api.goalslot.io/api",
  "apiUrl": "https://api.goalslot.io/api",
  "accessToken": "<jwt>",
  "refreshToken": "gsl_rt_...",
  "accessTokenExpiresAt": "2026-08-25T12:00:00.000Z",
  "refreshTokenExpiresAt": "2026-11-23T00:00:00.000Z",
  "tokenId": "<uuid>",
  "scopes": ["full"],
  "user": { "id": "...", "email": "..." },
  "defaultTimezone": "Asia/Karachi",
  "weekStartsOn": 1
}

apiBaseUrl and apiUrl are both read and both written with the same value, so the CLI and this server cannot clobber each other. Unknown keys survive a rewrite.

CLI tokens are ordinary Bearer JWTs carrying typ: "cli" and a cid claim naming the revocable token row, and every normal API route accepts them. Access tokens live one hour. On a 401 this server rotates the refresh token against POST /api/auth/cli/token/refresh, writes the new pair to disk atomically before using it, and replays the original request once. Rotation is single-flight: refresh tokens are single use, and replaying a rotated one revokes the whole credential, so two concurrent refreshes would be a permanent logout.

No token, header or Authorization line is ever written to any log, at any level.

If the credential is missing or dead, every tool returns a structured NOT_AUTHENTICATED or SESSION_EXPIRED telling the model to have you run goalslot login. It will not ask you to paste a token.

Headless and CI

GOALSLOT_ACCESS_TOKEN overrides the file entirely. Pair it with GOALSLOT_REFRESH_TOKEN if you want refresh to work; without one, refresh is disabled and the session dies when the one-hour access token expires. For anything long-lived, set GOALSLOT_CONFIG_DIR instead and let the server manage the file.

Tools

Nine read tools and nine write tools. Read tools are safe to call freely and are annotated readOnlyHint. Every write tool's description starts with WRITES. and nothing exposed here deletes user data.

Read

Tool What it does
goalslot_get_context Orientation call, no arguments. User, plan limits and current usage, category value strings, labels, timezone, today's date, the current week, and any running timer. Every skill calls this first.
goalslot_list_goals Goals with target hours, logged hours, progress, deadline and labels. Optional status, category and label filters.
goalslot_get_goal One goal in full, optionally with the user's written reflections on it.
goalslot_list_tasks Tasks filtered by status, goal, schedule block or day of week, capped so a big backlog cannot flood the context.
goalslot_get_schedule The weekly schedule template, grouped by day and sorted by start time, with planned minutes per day.
goalslot_list_time_entries Individual time entries over a window or a preset, with a total. Optional goal filter and text search.
goalslot_get_report Nine report endpoints behind one view enum: dashboard, weekly, monthly, detailed, summary, day_by_task, day_total, schedule, goals_progress.
goalslot_search_notes Finds notes by title or body substring, or fetches one by id. Returns the tree path and converts the HTML body to markdown.
goalslot_get_journal Journal entries and daily check-ins merged by date: mood, energy, focus, what worked, what blocked.

Write

Tool What it does
goalslot_create_goal Creates a goal. targetHours is the one field measured in hours.
goalslot_update_goal Updates a goal including its status. Deliberately cannot set loggedHours.
goalslot_create_task Creates a task, optionally linked to a goal and a schedule block.
goalslot_update_task The whole task lifecycle behind an action: update, complete (which also logs time), restore.
goalslot_log_time Records time already spent. Supports dryRun. Credits the linked goal.
goalslot_start_timer Starts the shared server timer. Returns TIMER_ALREADY_RUNNING rather than silently taking over.
goalslot_stop_timer Stops the timer into a time entry, or discards it.
goalslot_manage_schedule_block Creates, updates or deletes one block in the weekly template. Supports dryRun and updateScope.
goalslot_write_journal Upserts a journal entry and a daily check-in for one date. Markdown in, TipTap HTML out.

Deliberately not tools

Deleting goals, tasks and time entries; clearing the whole schedule; sharing anything publicly or with another person; the AI coach chat endpoints; billing and account settings; template imports. Destruction with cascading effects and anything that publishes personal data belongs where a human types it, not where an agent can call it in a loop. Use the GoalSlot app or the CLI.

Conventions the tools enforce

  • Durations are whole minutes, always named durationMinutes, never a bare duration. Reads also return durationHours as a float for display only. A goal's targetHours is the single exception.
  • Dates are YYYY-MM-DD and are rejected at the boundary if they carry a time. "Today" is computed in your timezone, not from a UTC ISO slice.
  • The schedule is a repeating weekly template, not dated events. Every relevant tool description says so.
  • dayOfWeek is Sunday-first (0 = Sunday), which is not the Monday-first ordering weekly reports use. Both are labelled inline and every response carries a dayName.
  • Weekly buckets are recomputed from entry dates rather than read from the API's stored dayOfWeek column, which is derived in the API server's timezone and can be off by one.

Errors

Failures come back as isError: true with one JSON object:

{
  "error": {
    "code": "PLAN_LIMIT",
    "message": "You've reached your FREE plan limit for goals.",
    "httpStatus": 403,
    "retryable": false,
    "remedy": "The account is at its goal limit. Ask the user to pause a goal with update_goal (status PAUSED), delete one from the CLI, or upgrade. Do not retry.",
    "details": { "plan": "FREE", "limitType": "goals" }
  }
}

remedy is written in the imperative, for the model. Codes: NOT_AUTHENTICATED, SESSION_EXPIRED, PLAN_LIMIT, FORBIDDEN, SCHEDULE_CONFLICT, INVALID_INPUT, NOT_FOUND, RATE_LIMITED, UPSTREAM_ERROR, WRITE_BUDGET_EXCEEDED, READ_ONLY_MODE, TIMER_ALREADY_RUNNING, NO_TIMER_RUNNING.

Skills

Four skills ship in skills/. They carry the judgement the tool descriptions cannot: which order to call things in, what to confirm before writing, and what not to say.

Skill When
goalslot-plan-my-week Planning a week, blocking time for a goal, rebalancing the schedule.
goalslot-log-time Catching up on untracked time, correcting entries, driving the timer.
goalslot-weekly-review End of week, "how did my week go", writing a reflection.
goalslot-goal-checkup "Am I on track for X", deciding between cutting a target and moving a deadline.

Install them into Claude Code by copying the directories into your skills folder:

# macOS and Linux
cp -r "$(npm root -g)/goalslot-mcp/skills/"* ~/.claude/skills/

# Windows PowerShell
Copy-Item "$(npm root -g)\goalslot-mcp\skills\*" "$env:USERPROFILE\.claude\skills\" -Recurse

From a clone, copy skills/* from the repo instead. Project-scoped works too: put them in .claude/skills/ inside a repo.

Configuration

Variable Effect
GOALSLOT_CONFIG_DIR Directory holding credentials.json. Checked first.
GOALSLOT_ACCESS_TOKEN Overrides the credential file entirely. CI escape hatch.
GOALSLOT_REFRESH_TOKEN Refresh token to pair with the above. Rotations are held in memory only.
GOALSLOT_API_URL API base URL. Defaults to https://api.goalslot.io/api.
GOALSLOT_TZ IANA timezone overriding the one from login.
GOALSLOT_MCP_READONLY=1 Every write tool returns READ_ONLY_MODE. Set this when pointing an agent you do not fully trust at a live account.
GOALSLOT_MCP_MAX_WRITES Write calls allowed per process. Defaults to 25. A runaway loop stops here rather than at the plan limit, which only backstops free accounts.

HTTP transport

Optional, behind a flag:

npx -y goalslot-mcp --http --port 7801

It serves the same tool registry at http://127.0.0.1:7801/mcp over the streamable HTTP transport, statelessly.

This is single user and local only. Every request is served with this machine's GoalSlot credentials. There is no per-caller authentication, no OAuth and no token custody, so anyone who can reach the port can read and write the account. It binds to loopback and should stay there. It is not the hosted multi-tenant MCP server tracked in goal-slot-api#55; that needs a real OAuth flow and per-user token storage, which is a different piece of work.

stdio is the supported path.

Development

npm install
npm run typecheck
npm test
npm run build
node dist/cli.js --list-tools

TypeScript strict, ESM, Node 20 or newer. Tests are vitest with a stubbed fetch; nothing in the suite touches a live API. CI runs typecheck, tests and build on Node 20 and 22 across Ubuntu and Windows.

License

MIT

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选