Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Hosted at [getpluck.io](https://getpluck.io), or run your own with `docker compo
- `packages/db`: the only code that touches MongoDB. Every query is scoped to one person.
- `packages/extract`: reading pages, PDFs, email and imports.
- `packages/blob`: S3 (MinIO locally).
- `packages/mcp`: the connector's tools, resources and prompts. `packages/mcp-stdio` is `npx @pluck/mcp`.
- `packages/mcp`: the connector's tools, resources and prompts. `packages/mcp-stdio` is `npx @getpluck/mcp`.
- `packages/shared-schemas`: every type, as a Zod schema, shared by server and clients.
- `packages/client`: the API client, offline queue and PKCE shared by the iPhone app and the extension.
- `packages/i18n`: the words in ten languages (English, Spanish, Portuguese (Brazil), French, German, Japanese, Italian, Dutch, Korean, Chinese (Simplified)).
Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Tell us what you found, how to see it, and what someone could do with it. A proo

## What is in scope

The hosted service at getpluck.io, the code in this repository (web app, API, MCP connector, browser extension, iPhone app and share extension, the Docker image), and the published `@pluck/mcp` package.
The hosted service at getpluck.io, the code in this repository (web app, API, MCP connector, browser extension, iPhone app and share extension, the Docker image), and the published `@getpluck/mcp` package.

Self-hosted copies are run by their owners; report problems in the code here, and the owner of that copy for problems in how it is run.

Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/(app)/settings/AiToolsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function AiToolsSection({ connectorUrl, keyPrefix, initial, lastCallAt }:
const [lastCall, setLastCall] = useState<string | null>(null); // relative time is worked out after hydration
useEffect(() => setLastCall(lastCallAt && ago(lastCallAt)), [lastCallAt, ago]); // a new ago each render sets the same string: no loop
const hosted = new URL(connectorUrl).hostname === "getpluck.io";
const npx = `npx @pluck/mcp${hosted ? "" : ` --server ${new URL(connectorUrl).origin}`} --key ${keyPrefix ? `pk_live_${keyPrefix}••••` : "pk_live_…"}`;
const npx = `npx @getpluck/mcp${hosted ? "" : ` --server ${new URL(connectorUrl).origin}`} --key ${keyPrefix ? `pk_live_${keyPrefix}••••` : "pk_live_…"}`;
const copy = async (text: string, copied: string) => {
await navigator.clipboard?.writeText(text).catch(() => {});
showToast({ message: copied });
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/(site)/connect/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const TOOLS = [
{ key: "code", label: "Claude Code", code: `claude mcp add --transport http pluck ${CONNECTOR_URL}` },
{ key: "chatgpt", label: "ChatGPT", code: CONNECTOR_URL },
{ key: "cursor", label: "Cursor", codeLabel: "mcp.json", code: `{ "mcpServers": { "pluck": { "url": "${CONNECTOR_URL}" } } }` },
{ key: "self", code: "npx @pluck/mcp --server https://pluck.your.host --key pk_live_…" },
{ key: "self", code: "npx @getpluck/mcp --server https://pluck.your.host --key pk_live_…" },
] as const;

const TOOL_LIST = ["search_items", "list_items", "get_item", "save_item", "batch_update", "list_tags", "create_tag", "list_lists", "get_list", "create_list", "update_list", "get_digest"] as const;
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/(site)/open-source/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default async function OpenSource() {
<span>cd pluck</span>
<span className={styles.mint}>docker compose up -d</span>
<span className={`${styles.comment} ${styles.gap}`}>{t("terminalComment")}</span>
<span>npx @pluck/mcp --server http://localhost:3000 \</span>
<span>npx @getpluck/mcp --server http://localhost:3000 \</span>
<span> --key pk_live_…</span>
</div>
</section>
Expand Down
2 changes: 1 addition & 1 deletion apps/web/content/blog/de/ask-your-ai-what-you-plucked.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Einstellungen, dann KI-Tools, dann Trennen. Sie hört sofort auf, nicht erst am
Selbst gehostet, ohne öffentliche Adresse? Leg in den Einstellungen einen API-Schlüssel an und verbinde ihn lokal:

```
npx @pluck/mcp --server https://pluck.your.host --key pk_live_…
npx @getpluck/mcp --server https://pluck.your.host --key pk_live_…
```

Du bekommst dieselben Tools und dieselben Prompts, nur mit deinem Server verbunden.
Expand Down
2 changes: 1 addition & 1 deletion apps/web/content/blog/de/run-your-own-pluck.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Pluck startet auf einer öffentlichen Adresse nicht mit dem Standard-Passwort f

- **iPhone.** Öffne `pluck://signin?server=https://your.address` auf dem Handy. Die App meldet sich dann bei deinem Server an.
- **Chrome.** Die Erweiterung aus dem Store spricht nur mit getpluck.io. Bau deine eigene mit `PLUCK_SERVER=https://your.address pnpm --filter @pluck/extension build` und lade sie mit „Entpackte Erweiterung laden“.
- **Deine KI.** Verbinde sie mit `https://your.address/mcp`. Wenn der Server keine öffentliche Adresse hat, leg in den Einstellungen einen API-Schlüssel an und nutze `npx @pluck/mcp --server https://your.address --key pk_live_…`.
- **Deine KI.** Verbinde sie mit `https://your.address/mcp`. Wenn der Server keine öffentliche Adresse hat, leg in den Einstellungen einen API-Schlüssel an und nutze `npx @getpluck/mcp --server https://your.address --key pk_live_…`.

## Die unbequemen Teile

Expand Down
2 changes: 1 addition & 1 deletion apps/web/content/blog/en/ask-your-ai-what-you-plucked.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Settings, then AI tools, then Disconnect. It stops straight away, not at the end
Self-hosted without a public address? Make an API key in Settings and bridge it locally:

```
npx @pluck/mcp --server https://pluck.your.host --key pk_live_…
npx @getpluck/mcp --server https://pluck.your.host --key pk_live_…
```

You get the same tools and the same prompts, pointed at your server.
Expand Down
2 changes: 1 addition & 1 deletion apps/web/content/blog/en/run-your-own-pluck.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Pluck won't start on a public address with the default storage password. That's

- **iPhone.** Open `pluck://signin?server=https://your.address` on the phone. The app signs in to your server instead.
- **Chrome.** The store extension only talks to getpluck.io. Build your own with `PLUCK_SERVER=https://your.address pnpm --filter @pluck/extension build` and load it unpacked.
- **Your AI.** Connect it to `https://your.address/mcp`. If the server has no public address, make an API key in Settings and use `npx @pluck/mcp --server https://your.address --key pk_live_…`.
- **Your AI.** Connect it to `https://your.address/mcp`. If the server has no public address, make an API key in Settings and use `npx @getpluck/mcp --server https://your.address --key pk_live_…`.

## The awkward parts

Expand Down
2 changes: 1 addition & 1 deletion apps/web/content/blog/es/ask-your-ai-what-you-plucked.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Ajustes, luego Herramientas de IA y luego Desconectar. Se corta al instante, no
¿Lo tienes autoalojado y sin dirección pública? Crea una clave de API en Ajustes y conéctalo en local:

```
npx @pluck/mcp --server https://pluck.your.host --key pk_live_…
npx @getpluck/mcp --server https://pluck.your.host --key pk_live_…
```

Tienes las mismas herramientas y los mismos prompts, apuntando a tu servidor.
Expand Down
2 changes: 1 addition & 1 deletion apps/web/content/blog/es/run-your-own-pluck.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Pluck no arranca en una dirección pública con la contraseña de almacenamiento

- **iPhone.** Abre `pluck://signin?server=https://your.address` en el teléfono. La app inicia sesión en tu servidor.
- **Chrome.** La extensión de la tienda solo habla con getpluck.io. Compila la tuya con `PLUCK_SERVER=https://your.address pnpm --filter @pluck/extension build` y cárgala con “Cargar descomprimida”.
- **Tu IA.** Conéctala a `https://your.address/mcp`. Si el servidor no tiene dirección pública, crea una clave de API en Ajustes y usa `npx @pluck/mcp --server https://your.address --key pk_live_…`.
- **Tu IA.** Conéctala a `https://your.address/mcp`. Si el servidor no tiene dirección pública, crea una clave de API en Ajustes y usa `npx @getpluck/mcp --server https://your.address --key pk_live_…`.

## Las partes incómodas

Expand Down
2 changes: 1 addition & 1 deletion apps/web/content/blog/fr/ask-your-ai-what-you-plucked.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Réglages, puis Outils d’IA, puis Déconnecter. Elle s’arrête aussitôt, pa
Auto-hébergé, sans adresse publique ? Créez une clé d’API dans les Réglages et faites le pont en local :

```
npx @pluck/mcp --server https://pluck.your.host --key pk_live_…
npx @getpluck/mcp --server https://pluck.your.host --key pk_live_…
```

Vous avez les mêmes outils et les mêmes prompts, pointés vers votre serveur.
Expand Down
2 changes: 1 addition & 1 deletion apps/web/content/blog/fr/run-your-own-pluck.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Pluck refuse de démarrer sur une adresse publique avec le mot de passe de stock

- **iPhone.** Ouvrez `pluck://signin?server=https://your.address` sur le téléphone. L’app se connecte alors à votre serveur.
- **Chrome.** L’extension du store ne parle qu’à getpluck.io. Compilez la vôtre avec `PLUCK_SERVER=https://your.address pnpm --filter @pluck/extension build` et chargez-la avec « Charger l’extension non empaquetée ».
- **Votre IA.** Connectez-la à `https://your.address/mcp`. Si le serveur n’a pas d’adresse publique, créez une clé d’API dans les Réglages et utilisez `npx @pluck/mcp --server https://your.address --key pk_live_…`.
- **Votre IA.** Connectez-la à `https://your.address/mcp`. Si le serveur n’a pas d’adresse publique, créez une clé d’API dans les Réglages et utilisez `npx @getpluck/mcp --server https://your.address --key pk_live_…`.

## Les parties pénibles

Expand Down
2 changes: 1 addition & 1 deletion apps/web/content/blog/it/ask-your-ai-what-you-plucked.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Impostazioni, poi Strumenti di IA, poi Scollega. Si ferma subito, non alla fine
Self-hosting senza un indirizzo pubblico? Crea una chiave API in Impostazioni e fai da ponte in locale:

```
npx @pluck/mcp --server https://pluck.your.host --key pk_live_…
npx @getpluck/mcp --server https://pluck.your.host --key pk_live_…
```

Hai gli stessi strumenti e gli stessi prompt, puntati sul tuo server.
Expand Down
2 changes: 1 addition & 1 deletion apps/web/content/blog/it/run-your-own-pluck.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Pluck non parte su un indirizzo pubblico con la password di storage predefinita.

- **iPhone.** Apri `pluck://signin?server=https://your.address` sul telefono. L'app accede al tuo server.
- **Chrome.** L'estensione dello store parla solo con getpluck.io. Compila la tua con `PLUCK_SERVER=https://your.address pnpm --filter @pluck/extension build` e caricala con "Carica estensione non pacchettizzata".
- **La tua IA.** Collegala a `https://your.address/mcp`. Se il server non ha un indirizzo pubblico, crea una chiave API in Impostazioni e usa `npx @pluck/mcp --server https://your.address --key pk_live_…`.
- **La tua IA.** Collegala a `https://your.address/mcp`. Se il server non ha un indirizzo pubblico, crea una chiave API in Impostazioni e usa `npx @getpluck/mcp --server https://your.address --key pk_live_…`.

## Le parti scomode

Expand Down
2 changes: 1 addition & 1 deletion apps/web/content/blog/ja/ask-your-ai-what-you-plucked.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ AIが作ったタグとリストには、すべて「AIによる」の印が付
公開アドレスのないセルフホスト環境なら、設定でAPIキーを作り、ローカルでつなぎます:

```
npx @pluck/mcp --server https://pluck.your.host --key pk_live_…
npx @getpluck/mcp --server https://pluck.your.host --key pk_live_…
```

同じツールと同じプロンプトが、自分のサーバーに向けて使えます。
Expand Down
2 changes: 1 addition & 1 deletion apps/web/content/blog/ja/run-your-own-pluck.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ HTTPS対応のリバースプロキシを前に置き、composeファイルの

- **iPhone**:iPhoneで `pluck://signin?server=https://your.address` を開きます。アプリは代わりに、自分のサーバーにサインインします。
- **Chrome**:ストア版の拡張機能は、getpluck.ioとしか通信しません。`PLUCK_SERVER=https://your.address pnpm --filter @pluck/extension build` で自分用をビルドし、「パッケージ化されていない拡張機能を読み込む」から読み込みます。
- **お使いのAI**:`https://your.address/mcp` に接続します。サーバーに公開アドレスがなければ、設定でAPIキーを作り、`npx @pluck/mcp --server https://your.address --key pk_live_…` を使います。
- **お使いのAI**:`https://your.address/mcp` に接続します。サーバーに公開アドレスがなければ、設定でAPIキーを作り、`npx @getpluck/mcp --server https://your.address --key pk_live_…` を使います。

## 面倒なところ

Expand Down
2 changes: 1 addition & 1 deletion apps/web/content/blog/ko/ask-your-ai-what-you-plucked.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ AI가 만든 태그와 리스트에는 모두 “AI” 표시가 붙어요. 일
공개 주소 없이 직접 호스팅하고 있나요? 설정에서 API 키를 만들고 로컬로 연결하세요.

```
npx @pluck/mcp --server https://pluck.your.host --key pk_live_…
npx @getpluck/mcp --server https://pluck.your.host --key pk_live_…
```

같은 도구, 같은 프롬프트가 내 서버를 향해 작동해요.
Expand Down
2 changes: 1 addition & 1 deletion apps/web/content/blog/ko/run-your-own-pluck.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Docker 이미지 하나를 두 번 띄워요. 하나는 앱을 제공해요. 다

- **iPhone.** 휴대폰에서 `pluck://signin?server=https://your.address` 를 여세요. 앱이 대신 내 서버에 로그인해요.
- **Chrome.** 스토어의 확장 프로그램은 getpluck.io하고만 통신해요. `PLUCK_SERVER=https://your.address pnpm --filter @pluck/extension build` 로 직접 빌드하고, “압축해제된 확장 프로그램 로드”로 불러오세요.
- **내 AI.** `https://your.address/mcp` 에 연결하세요. 서버에 공개 주소가 없다면 설정에서 API 키를 만들고 `npx @pluck/mcp --server https://your.address --key pk_live_…` 를 쓰세요.
- **내 AI.** `https://your.address/mcp` 에 연결하세요. 서버에 공개 주소가 없다면 설정에서 API 키를 만들고 `npx @getpluck/mcp --server https://your.address --key pk_live_…` 를 쓰세요.

## 귀찮은 부분

Expand Down
2 changes: 1 addition & 1 deletion apps/web/content/blog/nl/ask-your-ai-what-you-plucked.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Instellingen, dan AI-tools, dan Loskoppelen. Hij stopt meteen, niet pas aan het
Zelf gehost zonder openbaar adres? Maak een API-sleutel in Instellingen en verbind die lokaal:

```
npx @pluck/mcp --server https://pluck.your.host --key pk_live_…
npx @getpluck/mcp --server https://pluck.your.host --key pk_live_…
```

Je krijgt dezelfde tools en dezelfde prompts, gericht op je eigen server.
Expand Down
2 changes: 1 addition & 1 deletion apps/web/content/blog/nl/run-your-own-pluck.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Pluck start niet op een openbaar adres met het standaardwachtwoord voor de opsla

- **iPhone.** Open `pluck://signin?server=https://your.address` op de telefoon. De app logt dan in bij jouw server.
- **Chrome.** De extensie uit de store praat alleen met getpluck.io. Bouw je eigen met `PLUCK_SERVER=https://your.address pnpm --filter @pluck/extension build` en laad hem met “Uitgepakte extensie laden”.
- **Je AI.** Verbind hem met `https://your.address/mcp`. Heeft de server geen openbaar adres, maak dan een API-sleutel in Instellingen en gebruik `npx @pluck/mcp --server https://your.address --key pk_live_…`.
- **Je AI.** Verbind hem met `https://your.address/mcp`. Heeft de server geen openbaar adres, maak dan een API-sleutel in Instellingen en gebruik `npx @getpluck/mcp --server https://your.address --key pk_live_…`.

## De lastige stukken

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Configurações, depois Ferramentas de IA, depois Desconectar. Para na hora, nã
Hospeda o seu e não tem endereço público? Crie uma chave de API nas Configurações e faça a ponte localmente:

```
npx @pluck/mcp --server https://pluck.your.host --key pk_live_…
npx @getpluck/mcp --server https://pluck.your.host --key pk_live_…
```

Você tem as mesmas ferramentas e os mesmos prompts, apontados para o seu servidor.
Expand Down
2 changes: 1 addition & 1 deletion apps/web/content/blog/pt-BR/run-your-own-pluck.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ O Pluck não inicia num endereço público com a senha padrão do armazenamento.

- **iPhone.** Abra `pluck://signin?server=https://your.address` no celular. O app passa a entrar no seu servidor.
- **Chrome.** A extensão da loja só fala com getpluck.io. Compile a sua com `PLUCK_SERVER=https://your.address pnpm --filter @pluck/extension build` e carregue com “Carregar sem compactação”.
- **Sua IA.** Conecte em `https://your.address/mcp`. Se o servidor não tiver endereço público, crie uma chave de API nas Configurações e use `npx @pluck/mcp --server https://your.address --key pk_live_…`.
- **Sua IA.** Conecte em `https://your.address/mcp`. Se o servidor não tiver endereço público, crie uma chave de API nas Configurações e use `npx @getpluck/mcp --server https://your.address --key pk_live_…`.

## As partes chatas

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ claude mcp add --transport http pluck https://getpluck.io/mcp
自托管,但没有公网地址?在设置里生成一个 API 密钥,在本地做桥接:

```
npx @pluck/mcp --server https://pluck.your.host --key pk_live_…
npx @getpluck/mcp --server https://pluck.your.host --key pk_live_…
```

你会得到同样的工具和同样的提示词,只是指向你的服务器。
Expand Down
2 changes: 1 addition & 1 deletion apps/web/content/blog/zh-Hans/run-your-own-pluck.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ docker compose up -d

- **iPhone。** 在手机上打开 `pluck://signin?server=https://your.address`。App 就会改为登录到你的服务器。
- **Chrome。** 商店里的扩展只连 getpluck.io。用 `PLUCK_SERVER=https://your.address pnpm --filter @pluck/extension build` 构建你自己的版本,再用“加载未打包的扩展程序”加载它。
- **你的 AI。** 把它连接到 `https://your.address/mcp`。如果服务器没有公网地址,在设置里生成一个 API 密钥,然后用 `npx @pluck/mcp --server https://your.address --key pk_live_…`。
- **你的 AI。** 把它连接到 `https://your.address/mcp`。如果服务器没有公网地址,在设置里生成一个 API 密钥,然后用 `npx @getpluck/mcp --server https://your.address --key pk_live_…`。

## 麻烦的部分

Expand Down
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ One Next.js app (`apps/web`) is the website, the signed-in app, the REST API for
| `apps/web/lib/email.ts`, `emails.ts`, `digest-email.ts` | `sendEmail` (SMTP to Mailpit locally, SES in production) and the email templates. |
| `packages/db` | Every collection, index and query (`collections.ts` defines them all). Every query is scoped by `userId`; `public.ts` is the only reader for public Lists. |
| `packages/mcp` | The connector's tools, resources and prompts (package `@pluck/mcp-server`). It sees the library only through `PluckLibrary`. |
| `packages/mcp-stdio` | The `npx @pluck/mcp` bridge (package `@pluck/mcp`, the one published to npm): stdio to the hosted connector with an API key. |
| `packages/mcp-stdio` | The `npx @getpluck/mcp` bridge (package `@getpluck/mcp`, the one published to npm): stdio to the hosted connector with an API key. |
| `packages/extract` | Guarded fetch (`fetch.ts`), page and PDF reading (`extract.ts`, Defuddle then Readability), email (`email.ts`) and imports. Its fixtures are served by `pnpm stack` so tests never touch the internet. |
| `packages/blob` | S3 through the AWS SDK; MinIO locally and for self-hosting. |
| `packages/shared-schemas` | Every type as a Zod schema, used by the server and every client. |
Expand Down
3 changes: 1 addition & 2 deletions docs/launch-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ Everything between the code in this repo and Pluck being live, in order. Each li

## AI tools

- [ ] Check the `@pluck` scope on npm is yours (`npm org ls pluck` signed in). It exists already; if it is not yours, rename the package (and `npx @pluck/mcp` in Settings, Connect, docs and the blog) before anyone copies the command.
- [ ] Publish the stdio bridge: `pnpm --filter @pluck/mcp build`, then `npm publish --access public` from `packages/mcp-stdio` (package `@pluck/mcp`).
- [ ] Publish the stdio bridge under the `@getpluck` scope: `npm login`, then `pnpm publish --access public` from `packages/mcp-stdio` (it builds first). Use pnpm, not npm: only pnpm applies `publishConfig.exports`, so the package points at `dist`, not `src`.
- [ ] Add `https://getpluck.io/mcp` in Claude (web and desktop), ChatGPT, Claude Code and Cursor, and run each of the four prompts once.

## Day one
Expand Down
Loading
Loading