mcp-loom 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcp_loom-1.2.0/.github/workflows/ci.yml +28 -0
- mcp_loom-1.2.0/.github/workflows/publish.yml +27 -0
- mcp_loom-1.2.0/.gitignore +6 -0
- mcp_loom-1.2.0/.mise.toml +46 -0
- mcp_loom-1.2.0/CHANGELOG.md +88 -0
- mcp_loom-1.2.0/CLAUDE.md +13 -0
- mcp_loom-1.2.0/CONTRIBUTING.md +31 -0
- mcp_loom-1.2.0/LICENSE +21 -0
- mcp_loom-1.2.0/PKG-INFO +9 -0
- mcp_loom-1.2.0/README.md +253 -0
- mcp_loom-1.2.0/fastmcp.json +11 -0
- mcp_loom-1.2.0/pyproject.toml +23 -0
- mcp_loom-1.2.0/src/loom_mcp/__init__.py +0 -0
- mcp_loom-1.2.0/src/loom_mcp/client.py +1048 -0
- mcp_loom-1.2.0/src/loom_mcp/server.py +1670 -0
- mcp_loom-1.2.0/tests/test_server.py +513 -0
- mcp_loom-1.2.0/uv.lock +1435 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
|
|
14
|
+
- uses: jdx/mise-action@v2
|
|
15
|
+
|
|
16
|
+
- name: Install dependencies
|
|
17
|
+
run: mise run install
|
|
18
|
+
|
|
19
|
+
- name: Lint
|
|
20
|
+
run: mise run lint
|
|
21
|
+
|
|
22
|
+
- name: Format check
|
|
23
|
+
run: mise run format-check
|
|
24
|
+
|
|
25
|
+
- name: Test
|
|
26
|
+
run: mise run test
|
|
27
|
+
env:
|
|
28
|
+
LOOM_COOKIE: test=dummy
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
environment: pypi
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
id-token: write
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- uses: jdx/mise-action@v2
|
|
19
|
+
|
|
20
|
+
- name: Install dependencies
|
|
21
|
+
run: mise run install
|
|
22
|
+
|
|
23
|
+
- name: Build
|
|
24
|
+
run: uv build
|
|
25
|
+
|
|
26
|
+
- name: Publish to PyPI
|
|
27
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
[tools]
|
|
2
|
+
python = "3.13"
|
|
3
|
+
uv = "latest"
|
|
4
|
+
|
|
5
|
+
[env]
|
|
6
|
+
UV_PROJECT_ENVIRONMENT = "{{cwd}}/.venv"
|
|
7
|
+
|
|
8
|
+
[tasks.install]
|
|
9
|
+
description = "Install dependencies"
|
|
10
|
+
run = "uv sync --all-extras"
|
|
11
|
+
|
|
12
|
+
[tasks.test]
|
|
13
|
+
description = "Run tests"
|
|
14
|
+
run = "uv run --with pytest pytest tests/ -v"
|
|
15
|
+
|
|
16
|
+
[tasks.lint]
|
|
17
|
+
description = "Run ruff linter"
|
|
18
|
+
run = "uv run --with ruff ruff check ."
|
|
19
|
+
|
|
20
|
+
[tasks.format]
|
|
21
|
+
description = "Run ruff formatter"
|
|
22
|
+
run = "uv run --with ruff ruff format ."
|
|
23
|
+
|
|
24
|
+
[tasks.format-check]
|
|
25
|
+
description = "Check formatting without writing"
|
|
26
|
+
run = "uv run --with ruff ruff format --check ."
|
|
27
|
+
|
|
28
|
+
[tasks.check]
|
|
29
|
+
description = "Run lint and format check"
|
|
30
|
+
depends = ["lint", "format-check"]
|
|
31
|
+
|
|
32
|
+
[tasks.install-hooks]
|
|
33
|
+
description = "Install git pre-commit hook"
|
|
34
|
+
run = """
|
|
35
|
+
cat > .git/hooks/pre-commit << 'EOF'
|
|
36
|
+
#!/bin/sh
|
|
37
|
+
mise run format
|
|
38
|
+
git add -u
|
|
39
|
+
mise run lint && mise run test
|
|
40
|
+
EOF
|
|
41
|
+
chmod +x .git/hooks/pre-commit
|
|
42
|
+
echo "pre-commit hook installed"
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
[hooks]
|
|
46
|
+
enter = "[ -f .git/hooks/pre-commit ] || mise run install-hooks"
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [1.2.0] - 2026-03-17
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- GitHub Actions CI workflow (lint, format, test) triggered on push and PRs
|
|
10
|
+
- PyPI publish workflow using OIDC trusted publishing, triggered on version tags
|
|
11
|
+
- mise tasks: `install`, `lint`, `format`, `test`, `build`
|
|
12
|
+
- `install-hooks` mise task and `mise enter` hook for automatic pre-commit setup
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Renamed PyPI package from `loom-mcp` to `mcp-loom`
|
|
17
|
+
- Pre-commit hook now auto-formats and re-stages files
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- Publish workflow permissions include `contents: read` so `actions/checkout` works alongside `id-token: write`
|
|
22
|
+
|
|
23
|
+
## [1.1.0] - 2026-02-17
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- Optional `save_dir` parameter on all per-video read tools (`get_video`, `get_transcript`, `get_captions`, `get_summary`, `get_chapters`, `get_description`, `get_key_takeaways`, `get_comments`, `get_tasks`, `get_reactions`, `get_tags`, `get_backlinks`, `get_video_details`)
|
|
28
|
+
- When `save_dir` is provided, tool output is saved to `{save_dir}/{video_id}/` with appropriate filenames (e.g. `transcript.txt`, `captions.vtt`, `metadata.json`)
|
|
29
|
+
- `get_video_details` saves each piece individually plus a combined `details.md`
|
|
30
|
+
- Saved file path is returned alongside the content
|
|
31
|
+
|
|
32
|
+
## [1.0.2] - 2026-02-10
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
|
|
36
|
+
- `get_space` tool — get details of a space by ID (parallels `get_folder`)
|
|
37
|
+
- `limit` parameter on `search_videos` (default 50, max 200)
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- `search_videos` now uses the paginated `SearchVideos` endpoint instead of the semantic `Search` endpoint — faster and no longer capped at 10 results
|
|
42
|
+
- Remove unused `fetch_videos_by_id` and `get_all_videos` from client
|
|
43
|
+
|
|
44
|
+
## [1.0.1] - 2026-02-10
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
|
|
48
|
+
- 401 error message now says to refresh the browser cookie instead of referencing removed `login.js`
|
|
49
|
+
- `.env` and `auth.json` path resolution no longer breaks when installed via `uvx` (gracefully skipped when no local `pyproject.toml` is found)
|
|
50
|
+
- Clear error message when neither `LOOM_COOKIE` nor `LOOM_AUTH_FILE` is set
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
|
|
54
|
+
- `get_video_details` now fetches transcript, chapters, summary, comments, and tasks concurrently via `asyncio.gather` instead of sequentially
|
|
55
|
+
- Rewrite README with per-client install instructions, badges, and improved auth docs
|
|
56
|
+
- Add MIT license, CONTRIBUTING.md
|
|
57
|
+
|
|
58
|
+
## [1.0.0] - 2026-02-10
|
|
59
|
+
|
|
60
|
+
### Changed
|
|
61
|
+
|
|
62
|
+
- Restructure to `src/` layout (`src/loom_mcp/server.py`, `src/loom_mcp/client.py`)
|
|
63
|
+
- Move tests to `tests/` directory
|
|
64
|
+
- Add hatchling build-system for proper packaging
|
|
65
|
+
- Resolve `.env`/`auth.json` paths by walking up to `pyproject.toml`
|
|
66
|
+
- Lower `requires-python` from 3.14 to 3.11
|
|
67
|
+
- Remove `.python-version` (redundant with `requires-python`)
|
|
68
|
+
- Simplify README auth docs, drop parent repo references
|
|
69
|
+
- Rename package to `loom-mcp` with console script entry point
|
|
70
|
+
- Switch to `@lifespan` decorator
|
|
71
|
+
- Add `read`/`write` tags and `timeout=30.0` to all tools
|
|
72
|
+
- Use `uvx` entry point in `fastmcp.json`
|
|
73
|
+
|
|
74
|
+
## [0.1.0] - 2026-02-08
|
|
75
|
+
|
|
76
|
+
### Added
|
|
77
|
+
|
|
78
|
+
- FastMCP server exposing 58 tools (29 read, 29 write) for Loom's internal GraphQL API
|
|
79
|
+
- Async Python client using httpx with concurrency limiter (5 concurrent requests)
|
|
80
|
+
- Auth via `LOOM_COOKIE` env var, `LOOM_AUTH_FILE` path, or `auth.json`
|
|
81
|
+
- Auto-load `.env` file for auth config
|
|
82
|
+
- Tool annotations (`readOnlyHint`, `destructiveHint`, `idempotentHint`) on all tools
|
|
83
|
+
- Input ID validation via `_id()`/`_ids()` helpers to reject injection-style inputs
|
|
84
|
+
- `LoomAPIError` and `ToolError` for actionable error messages (401, 403, connection errors)
|
|
85
|
+
- Lifespan-managed httpx client with proper cleanup
|
|
86
|
+
- 31 tests covering tool registration, annotations, ID validation, happy paths, and error paths
|
|
87
|
+
- `fastmcp.json` for FastMCP run support
|
|
88
|
+
- Ruff T20 lint rule to ban `print()` in stdio server code
|
mcp_loom-1.2.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Project Instructions
|
|
2
|
+
|
|
3
|
+
## Testing
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
uv run --with pytest pytest tests/ -v
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Releasing
|
|
10
|
+
|
|
11
|
+
- Tag versions with annotated tags: `git tag -a v1.2.3 -m "v1.2.3"`
|
|
12
|
+
- Do NOT create GitHub releases — tags + CHANGELOG.md is sufficient
|
|
13
|
+
- Bump version in both `pyproject.toml` and `src/loom_mcp/server.py`
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in contributing to loom-mcp!
|
|
4
|
+
|
|
5
|
+
## Getting started
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
git clone git@github.com:karbassi/loom-mcp.git
|
|
9
|
+
cd loom-mcp
|
|
10
|
+
uv sync
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Running tests
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
uv run --with pytest --with anyio pytest tests/ -q
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Linting and formatting
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
uv run --with ruff ruff check src tests
|
|
23
|
+
uv run --with ruff ruff format src tests
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Submitting changes
|
|
27
|
+
|
|
28
|
+
1. Fork the repo and create a branch from `main`
|
|
29
|
+
2. Make your changes
|
|
30
|
+
3. Ensure tests pass and code is formatted
|
|
31
|
+
4. Open a pull request
|
mcp_loom-1.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ali Karbassi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
mcp_loom-1.2.0/PKG-INFO
ADDED
mcp_loom-1.2.0/README.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# Loom MCP Server
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/mcp-loom/)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://www.python.org/downloads/)
|
|
6
|
+
|
|
7
|
+
[MCP](https://modelcontextprotocol.io) server exposing 59 tools for Loom's internal GraphQL API. Works with Claude, Cursor, or any MCP-compatible client.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- List, search, and get detailed metadata for Loom videos
|
|
12
|
+
- Read transcripts, captions, AI summaries, chapters, and key takeaways
|
|
13
|
+
- Save any fetched content to disk on demand via `save_dir` parameter
|
|
14
|
+
- Manage comments, tasks, reactions, and tags
|
|
15
|
+
- Organize with folders, spaces, and watch lists
|
|
16
|
+
- Update video settings, share to spaces, and more
|
|
17
|
+
|
|
18
|
+
## Prerequisites
|
|
19
|
+
|
|
20
|
+
- Python 3.11+
|
|
21
|
+
- [uv](https://docs.astral.sh/uv/) package manager
|
|
22
|
+
|
|
23
|
+
## Setup
|
|
24
|
+
|
|
25
|
+
### Authentication
|
|
26
|
+
|
|
27
|
+
> [!IMPORTANT]
|
|
28
|
+
> This server uses Loom's internal GraphQL API via a browser session cookie. There is no official API key — you must grab the cookie from your browser.
|
|
29
|
+
|
|
30
|
+
1. Open [loom.com](https://www.loom.com) in your browser
|
|
31
|
+
2. Open DevTools (F12) → Application → Cookies → `https://www.loom.com`
|
|
32
|
+
3. Copy the **value** of the `connect.sid` cookie (starts with `s%3A...`)
|
|
33
|
+
4. Paste it as `LOOM_COOKIE` in your MCP client config below, prefixed with `connect.sid=`
|
|
34
|
+
|
|
35
|
+
The cookie lasts about 30 days. See [Troubleshooting](#troubleshooting) if you get auth errors.
|
|
36
|
+
|
|
37
|
+
### Installation
|
|
38
|
+
|
|
39
|
+
Pick your MCP client below for the appropriate config. Each uses `uvx` to install and run from PyPI — no clone needed.
|
|
40
|
+
|
|
41
|
+
<details>
|
|
42
|
+
<summary><b>Claude Desktop</b></summary>
|
|
43
|
+
|
|
44
|
+
Add to your `claude_desktop_config.json`:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"mcpServers": {
|
|
49
|
+
"loom": {
|
|
50
|
+
"type": "stdio",
|
|
51
|
+
"command": "uvx",
|
|
52
|
+
"args": ["--from", "git+https://github.com/karbassi/loom-mcp.git", "loom-mcp"],
|
|
53
|
+
"env": {
|
|
54
|
+
"LOOM_COOKIE": "connect.sid=s%3A..."
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
</details>
|
|
62
|
+
|
|
63
|
+
<details>
|
|
64
|
+
<summary><b>Claude Code</b></summary>
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
claude mcp add loom -- uvx --from mcp-loom loom-mcp
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Then set the env var in your shell or `.env`:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
export LOOM_COOKIE="connect.sid=s%3A..."
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
</details>
|
|
77
|
+
|
|
78
|
+
<details>
|
|
79
|
+
<summary><b>Cursor</b></summary>
|
|
80
|
+
|
|
81
|
+
Add to your Cursor MCP settings (`.cursor/mcp.json`):
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"mcpServers": {
|
|
86
|
+
"loom": {
|
|
87
|
+
"type": "stdio",
|
|
88
|
+
"command": "uvx",
|
|
89
|
+
"args": ["--from", "git+https://github.com/karbassi/loom-mcp.git", "loom-mcp"],
|
|
90
|
+
"env": {
|
|
91
|
+
"LOOM_COOKIE": "connect.sid=s%3A..."
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
</details>
|
|
99
|
+
|
|
100
|
+
<details>
|
|
101
|
+
<summary><b>VS Code</b></summary>
|
|
102
|
+
|
|
103
|
+
Add to your VS Code settings (`.vscode/mcp.json`):
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"mcpServers": {
|
|
108
|
+
"loom": {
|
|
109
|
+
"type": "stdio",
|
|
110
|
+
"command": "uvx",
|
|
111
|
+
"args": ["--from", "git+https://github.com/karbassi/loom-mcp.git", "loom-mcp"],
|
|
112
|
+
"env": {
|
|
113
|
+
"LOOM_COOKIE": "connect.sid=s%3A..."
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
</details>
|
|
121
|
+
|
|
122
|
+
<details>
|
|
123
|
+
<summary><b>Local clone</b></summary>
|
|
124
|
+
|
|
125
|
+
```sh
|
|
126
|
+
git clone git@github.com:karbassi/loom-mcp.git
|
|
127
|
+
cd loom-mcp
|
|
128
|
+
uv sync
|
|
129
|
+
uv run loom-mcp
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Or reference it from any MCP client:
|
|
133
|
+
|
|
134
|
+
```json
|
|
135
|
+
{
|
|
136
|
+
"mcpServers": {
|
|
137
|
+
"loom": {
|
|
138
|
+
"type": "stdio",
|
|
139
|
+
"command": "uv",
|
|
140
|
+
"args": ["run", "--directory", "/path/to/loom-mcp", "loom-mcp"],
|
|
141
|
+
"env": {
|
|
142
|
+
"LOOM_COOKIE": "connect.sid=s%3A..."
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
</details>
|
|
150
|
+
|
|
151
|
+
## Tools
|
|
152
|
+
|
|
153
|
+
### Read (30 tools)
|
|
154
|
+
|
|
155
|
+
Tools marked with **Save** accept an optional `save_dir` parameter — see [Saving to disk](#saving-to-disk).
|
|
156
|
+
|
|
157
|
+
| Tool | Description | Save |
|
|
158
|
+
|---|---|:---:|
|
|
159
|
+
| `list_videos` | List your videos, sorted by most recent | |
|
|
160
|
+
| `search_videos` | AI-powered semantic search | |
|
|
161
|
+
| `get_video` | Video metadata (name, duration, owner, views) | `metadata.json` |
|
|
162
|
+
| `get_transcript` | Full transcript with timestamps and speakers | `transcript.txt` |
|
|
163
|
+
| `get_captions` | WebVTT captions with start+end timestamps per cue | `captions.vtt` |
|
|
164
|
+
| `get_summary` | AI-generated summary | `summary.txt` |
|
|
165
|
+
| `get_chapters` | AI-generated chapters | `chapters.txt` |
|
|
166
|
+
| `get_description` | AI-generated detailed description with timestamped sections | `description.txt` |
|
|
167
|
+
| `get_key_takeaways` | AI-generated key takeaways | `takeaways.txt` |
|
|
168
|
+
| `get_comments` | Comments and replies | `comments.txt` |
|
|
169
|
+
| `get_tasks` | AI-generated action items | `tasks.txt` |
|
|
170
|
+
| `get_reactions` | Emoji reactions | `reactions.txt` |
|
|
171
|
+
| `get_tags` | Video tags | `tags.txt` |
|
|
172
|
+
| `get_backlinks` | External references (where the video is shared/embedded) | `backlinks.txt` |
|
|
173
|
+
| `get_meeting_notes` | Confluence meeting notes URL | |
|
|
174
|
+
| `get_confluence_pages` | Linked Confluence pages | |
|
|
175
|
+
| `get_download_url` | Signed MP4 download URL | |
|
|
176
|
+
| `get_video_details` | All-in-one: metadata + transcript + chapters + summary + comments + tasks | `details.md` + all above |
|
|
177
|
+
| `list_folders` | List your folders | |
|
|
178
|
+
| `list_spaces` | List your workspaces | |
|
|
179
|
+
| `get_space` | Space details (name, privacy, primary) | |
|
|
180
|
+
| `search_folders` | Search folders by name | |
|
|
181
|
+
| `get_folder` | Folder details | |
|
|
182
|
+
| `get_last_watch_time` | Last timestamp where you stopped watching | |
|
|
183
|
+
| `get_watch_later_count` | Number of videos in your Watch Later list | |
|
|
184
|
+
| `get_total_videos_count` | Total videos created by a user | |
|
|
185
|
+
| `get_frequent_reactions` | Your most-used emoji reaction types | |
|
|
186
|
+
| `get_comment_reactions` | Emoji reactions on a specific comment | |
|
|
187
|
+
| `get_user` | User profile by ID (name, email, company, avatar) | |
|
|
188
|
+
| `search_workspace_tags` | Search tags in your workspace | |
|
|
189
|
+
|
|
190
|
+
### Write (29 tools)
|
|
191
|
+
|
|
192
|
+
> [!NOTE]
|
|
193
|
+
> Write tools modify your Loom data. Destructive actions (delete, archive, move) cannot always be undone.
|
|
194
|
+
|
|
195
|
+
| Tool | Description |
|
|
196
|
+
|---|---|
|
|
197
|
+
| `update_video_name` | Rename a video |
|
|
198
|
+
| `update_video_description` | Update video description |
|
|
199
|
+
| `update_video_settings` | Update video settings (downloads, comments, etc.) |
|
|
200
|
+
| `create_comment` | Post a comment (with optional timestamp) |
|
|
201
|
+
| `edit_comment` | Edit an existing comment |
|
|
202
|
+
| `delete_comment` | Delete a comment |
|
|
203
|
+
| `create_task` | Create an action item on a video |
|
|
204
|
+
| `update_task` | Update the content of an action item |
|
|
205
|
+
| `delete_task` | Delete an action item |
|
|
206
|
+
| `approve_task` | Mark a task as approved |
|
|
207
|
+
| `respond_to_task` | Respond to a task |
|
|
208
|
+
| `add_reaction` | Add an emoji reaction at a timestamp |
|
|
209
|
+
| `delete_reaction` | Delete a reaction |
|
|
210
|
+
| `add_comment_reaction` | React to a comment with an emoji |
|
|
211
|
+
| `toggle_following` | Follow/unfollow a video |
|
|
212
|
+
| `toggle_following_tag` | Follow/unfollow a workspace tag |
|
|
213
|
+
| `archive_videos` | Archive or unarchive videos |
|
|
214
|
+
| `duplicate_video` | Duplicate a video |
|
|
215
|
+
| `delete_video` | Permanently delete a video |
|
|
216
|
+
| `recover_video` | Recover a deleted video from trash |
|
|
217
|
+
| `pin_video` | Pin or unpin a video in your library |
|
|
218
|
+
| `add_to_watch_later` | Add to Watch Later list |
|
|
219
|
+
| `remove_from_watch_later` | Remove from Watch Later list |
|
|
220
|
+
| `create_folder` | Create a new folder |
|
|
221
|
+
| `rename_folder` | Rename a folder |
|
|
222
|
+
| `delete_folders` | Delete folders |
|
|
223
|
+
| `move_videos` | Move videos to a different folder |
|
|
224
|
+
| `move_folders` | Move folders into a different parent folder |
|
|
225
|
+
| `share_videos_to_spaces` | Share videos to one or more spaces |
|
|
226
|
+
|
|
227
|
+
## Saving to disk
|
|
228
|
+
|
|
229
|
+
Most per-video read tools accept an optional `save_dir` parameter. When provided, the tool saves its output to `{save_dir}/{video_id}/` and returns the file path alongside the content. When omitted, nothing is saved.
|
|
230
|
+
|
|
231
|
+
Just ask naturally — *"get the details from my last meeting and save them to the `ask` directory"* — and the LLM will pass `save_dir="ask"` to the tool.
|
|
232
|
+
|
|
233
|
+
`get_video_details` saves each piece individually (`metadata.json`, `transcript.txt`, `summary.txt`, etc.) plus a combined `details.md`.
|
|
234
|
+
|
|
235
|
+
## Troubleshooting
|
|
236
|
+
|
|
237
|
+
### Auth errors
|
|
238
|
+
|
|
239
|
+
If you get auth errors, your `connect.sid` cookie has expired (~30 days). Grab a fresh one from your browser using the steps in [Authentication](#authentication).
|
|
240
|
+
|
|
241
|
+
### Debugging with MCP Inspector
|
|
242
|
+
|
|
243
|
+
```sh
|
|
244
|
+
npx @modelcontextprotocol/inspector uvx --from mcp-loom loom-mcp
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Contributing
|
|
248
|
+
|
|
249
|
+
Issues and pull requests are welcome on [GitHub](https://github.com/karbassi/loom-mcp).
|
|
250
|
+
|
|
251
|
+
## License
|
|
252
|
+
|
|
253
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Loom",
|
|
3
|
+
"description": "Access Loom videos, transcripts, summaries, and comments via Loom's internal GraphQL API.",
|
|
4
|
+
"mcpServers": {
|
|
5
|
+
"loom": {
|
|
6
|
+
"type": "stdio",
|
|
7
|
+
"command": "uvx",
|
|
8
|
+
"args": ["--from", "git+https://github.com/karbassi/loom-mcp.git", "loom-mcp"]
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "mcp-loom"
|
|
3
|
+
version = "1.2.0"
|
|
4
|
+
description = "MCP server for Loom's internal GraphQL API"
|
|
5
|
+
license = "MIT"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"fastmcp>=3.0.0b2",
|
|
9
|
+
"httpx>=0.28.1",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
[project.scripts]
|
|
13
|
+
loom-mcp = "loom_mcp.server:main"
|
|
14
|
+
|
|
15
|
+
[tool.hatch.build.targets.wheel]
|
|
16
|
+
packages = ["src/loom_mcp"]
|
|
17
|
+
|
|
18
|
+
[build-system]
|
|
19
|
+
requires = ["hatchling"]
|
|
20
|
+
build-backend = "hatchling.build"
|
|
21
|
+
|
|
22
|
+
[tool.ruff.lint]
|
|
23
|
+
select = ["T20"]
|
|
File without changes
|