🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@pasteapp/mcp

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@pasteapp/mcp - npm Package Compare versions

Comparing version
0.1.0
to
0.1.1
+77
dist/client-name.js
// Identify which AI tool spawned the bridge so Paste's `Client.Kind.inferred`
// can pick the right icon and label in the MCP & AI Tools list. Walks the
// parent-process tree via `ps`, stepping past shell/node/npx wrappers, and
// matches the first ancestor whose argv mentions a known AI tool. Falls back
// to the npm package slug when nothing matches.
//
// The returned name MUST contain a substring that Paste's Swift
// `Client.Kind.inferred(fromClientName:)` recognizes — "claude code",
// "claude", "cursor", "codex", "windsurf", "vscode"/"vs code" — otherwise
// the client lands as `.custom` with the slug below as its display name.
// (OpenCode is detected here so it shows up labeled, but Paste still maps
// it to `.custom` until the Swift side gains a case for it.)
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
const execFileAsync = promisify(execFile);
const DEFAULT_NAME = '@pasteapp/mcp';
// More specific first — `Claude Code` must be tested before `Claude Desktop`
// because the Code CLI's argv also contains the substring "claude".
const CLIENT_PATTERNS = [
{ pattern: /@anthropic-ai\/claude-code|\.claude\/local\/.*\bclaude\b|\bclaude\b[^ ]*cli/i, name: 'Claude Code' },
{ pattern: /Claude\.app\b/, name: 'Claude Desktop' },
{ pattern: /Cursor\.app\b/, name: 'Cursor' },
{ pattern: /Windsurf\.app\b/i, name: 'Windsurf' },
{ pattern: /Visual Studio Code\.app\b|\/Code\.app\b/i, name: 'VS Code' },
{ pattern: /@openai\/codex|\bcodex\b/i, name: 'Codex' },
{ pattern: /\bopencode\b/i, name: 'OpenCode' },
];
// Processes we step past when walking up — they're shell/runtime wrappers,
// not the actual host. Matched only AFTER the client patterns fail.
const WRAPPER_PATTERNS = [
/\bnpx\b/,
/\bnode\b/,
/\bsh\b|\bbash\b|\bzsh\b|\bfish\b/,
];
async function defaultReadProcessArgs(pid) {
try {
const { stdout } = await execFileAsync('/bin/ps', ['-p', String(pid), '-o', 'ppid=,args='], { timeout: 500 });
const match = stdout.trim().match(/^\s*(\d+)\s+(.+)$/);
if (!match)
return null;
return { ppid: Number.parseInt(match[1], 10), args: match[2] };
}
catch {
return null;
}
}
function matchClient(args) {
for (const { pattern, name } of CLIENT_PATTERNS) {
if (pattern.test(args))
return name;
}
return null;
}
function isWrapper(args) {
return WRAPPER_PATTERNS.some((p) => p.test(args));
}
export async function detectClientName(opts = {}) {
const read = opts.readProcessArgs ?? defaultReadProcessArgs;
let pid = opts.startPid ?? process.ppid;
for (let i = 0; i < 8; i++) {
const result = await read(pid);
if (!result)
break;
const matched = matchClient(result.args);
if (matched)
return matched;
// Stop the moment we hit a non-wrapper we don't recognize — going past it
// would just walk into the user's shell / WindowServer / launchd.
if (!isWrapper(result.args))
break;
if (result.ppid <= 1 || result.ppid === pid)
break;
pid = result.ppid;
}
return DEFAULT_NAME;
}
//# sourceMappingURL=client-name.js.map
{"version":3,"file":"client-name.js","sourceRoot":"","sources":["../src/client-name.ts"],"names":[],"mappings":"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"}
+4
-1

@@ -11,4 +11,7 @@ // Local HTTP listener that catches the OAuth authorization-code redirect.

// embed it in the `/authorize` request.
import { randomBytes } from 'node:crypto';
import { createServer } from 'node:http';
import { generateState } from './pkce.js';
function generateState() {
return randomBytes(16).toString('base64url');
}
const PAGE_HTML = '<!doctype html>'

@@ -15,0 +18,0 @@ + '<html lang="en"><head><meta charset="utf-8"><title>Paste connected</title>'

+1
-1

@@ -1,1 +0,1 @@

{"version":3,"file":"callback.js","sourceRoot":"","sources":["../../src/oauth/callback.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"callback.js","sourceRoot":"","sources":["../../src/oauth/callback.ts"],"names":[],"mappings":"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"}

@@ -1,64 +0,73 @@

// OAuth client for Paste's loopback MCP server. Implements the canonical MCP
// authorization dance: RFC 9728 protected-resource metadata → RFC 8414 auth
// server metadata → RFC 7591 dynamic client registration → authorization code
// + PKCE → token exchange. Tokens cached on disk between invocations.
// OAuth client for Paste's loopback MCP server, built on the official
// `@modelcontextprotocol/sdk` `auth()` function. The SDK handles metadata
// discovery (RFC 9728 protected-resource + RFC 8414 + OIDC fallback),
// dynamic client registration (RFC 7591), PKCE generation/verification,
// the `resource` indicator (RFC 8707), token exchange, and refresh-token
// rotation. We provide the storage backing and the side effects (open
// browser, wait on the loopback callback).
import { spawn } from 'node:child_process';
import { auth, } from '@modelcontextprotocol/sdk/client/auth.js';
import { detectClientName } from '../client-name.js';
import { startCallbackServer } from './callback.js';
import { generatePKCE } from './pkce.js';
import { TokenStore } from './store.js';
const CLIENT_NAME = 'Paste MCP Bridge';
const TOKEN_ERROR_BODY_CAP = 500;
export class OAuthClient {
serverURL;
store;
opts;
fetchImpl;
openBrowserImpl;
startCallbackServerImpl;
nowImpl;
constructor(serverURL, store = new TokenStore(), opts = {}) {
this.serverURL = serverURL;
this.store = store;
this.opts = opts;
this.fetchImpl = opts.fetch ?? fetch;
this.openBrowserImpl = opts.openBrowser ?? defaultOpenBrowser;
this.startCallbackServerImpl = opts.startCallbackServer ?? startCallbackServer;
this.nowImpl = opts.now ?? (() => new Date());
}
async accessToken() {
const cached = await this.store.load();
if (cached && cached.accessToken && cached.serverURL === this.serverURL.toString() && !this.isExpired(cached)) {
return cached.accessToken;
if (cached && cached.serverURL === this.serverURL.toString() && cached.tokens?.access_token) {
// Short-circuit: Paste issues long-lived access tokens without
// refresh_tokens, so SDK's `auth()` would always fall through to a
// fresh authorization. The bridge's transport will call `invalidate()`
// on 401 if the token actually went stale.
return cached.tokens.access_token;
}
return await this.runFlow();
}
async invalidate() {
await this.store.clear();
}
isExpired(token) {
if (token.expiresAt === null)
return false;
const expiresAt = Date.parse(token.expiresAt);
if (!Number.isFinite(expiresAt))
return false;
// 30-second skew so we don't hand out a token that's about to die in flight.
return expiresAt <= this.nowImpl().getTime() + 30_000;
}
async runFlow() {
const metadata = await discoverAuthServer(this.serverURL, this.fetchImpl);
// Different server URL (port changed, channel switched) → drop the cache.
if (cached && cached.serverURL !== this.serverURL.toString()) {
await this.store.clear();
}
const callback = await this.startCallbackServerImpl();
const redirectUri = `http://127.0.0.1:${callback.port}/cb`;
const provider = new BridgeProvider({
serverURL: this.serverURL.toString(),
redirectUrl: `http://127.0.0.1:${callback.port}/cb`,
state: callback.state,
store: this.store,
openBrowser: this.openBrowserImpl,
clientName: await this.resolveClientName(),
});
try {
const clientId = await registerClient(metadata, redirectUri, this.fetchImpl);
const { accessToken, expiresIn } = await this.authorize(metadata, clientId, redirectUri, callback);
const expiresAt = expiresIn != null
? new Date(this.nowImpl().getTime() + expiresIn * 1_000).toISOString()
: null;
const stored = {
serverURL: this.serverURL.toString(),
clientId,
accessToken,
expiresAt,
createdAt: this.nowImpl().toISOString(),
};
await this.store.save(stored);
return accessToken;
const first = await auth(provider, {
serverUrl: this.serverURL,
fetchFn: this.fetchImpl,
});
if (first === 'AUTHORIZED')
return await readToken(provider);
const cb = await callback.waitForCallback();
if (cb.error) {
const detail = cb.errorDescription ? ` — ${cb.errorDescription}` : '';
throw new Error(`OAuth error: ${cb.error}${detail}`);
}
if (!cb.code)
throw new Error('OAuth callback missing `code`');
const second = await auth(provider, {
serverUrl: this.serverURL,
authorizationCode: cb.code,
fetchFn: this.fetchImpl,
});
if (second !== 'AUTHORIZED') {
throw new Error(`OAuth handshake did not authorize (returned ${second})`);
}
return await readToken(provider);
}

@@ -69,101 +78,111 @@ finally {

}
async authorize(metadata, clientId, redirectUri, callback) {
const pkce = generatePKCE();
await this.openBrowserImpl(buildAuthURL(metadata, clientId, redirectUri, pkce.challenge, callback.state));
const result = await callback.waitForCallback();
if (result.error) {
const detail = result.errorDescription ? ` — ${result.errorDescription}` : '';
throw new Error(`OAuth error: ${result.error}${detail}`);
}
if (!result.code)
throw new Error('OAuth callback missing `code`');
// Belt-and-braces: CallbackServer enforces state too, but a mismatch here
// means the callback contract drifted — fail loud rather than proceed.
if (result.state !== callback.state)
throw new Error('OAuth state mismatch');
return await exchangeCode(metadata, clientId, result.code, redirectUri, pkce.verifier, this.fetchImpl);
async invalidate() {
await this.store.clear();
}
async resolveClientName() {
const override = this.opts.clientName;
if (typeof override === 'string')
return override;
if (typeof override === 'function')
return await override();
return await detectClientName();
}
}
async function discoverAuthServer(serverURL, fetchImpl) {
const origin = serverURL.origin;
let authBase = origin;
try {
const meta = await fetchJSON(`${origin}/.well-known/oauth-protected-resource`, fetchImpl);
const first = meta.authorization_servers?.[0];
if (first)
authBase = first.replace(/\/$/, '');
async function readToken(provider) {
const tokens = await provider.tokens();
if (!tokens?.access_token)
throw new Error('OAuth flow completed but no access token was returned');
return tokens.access_token;
}
class BridgeProvider {
opts;
constructor(opts) {
this.opts = opts;
}
catch {
// Resource metadata is optional per the spec — fall back to assuming the
// server is its own authorization server (Paste's setup).
get redirectUrl() {
return this.opts.redirectUrl;
}
const metadata = await fetchJSON(`${authBase}/.well-known/oauth-authorization-server`, fetchImpl);
if (typeof metadata.authorization_endpoint !== 'string'
|| typeof metadata.token_endpoint !== 'string'
|| typeof metadata.registration_endpoint !== 'string') {
throw new Error('Authorization server metadata is missing required endpoints');
}
return metadata;
}
async function registerClient(metadata, redirectUri, fetchImpl) {
const response = await fetchImpl(metadata.registration_endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
body: JSON.stringify({
client_name: CLIENT_NAME,
redirect_uris: [redirectUri],
get clientMetadata() {
return {
client_name: this.opts.clientName,
redirect_uris: [this.opts.redirectUrl],
token_endpoint_auth_method: 'none',
grant_types: ['authorization_code'],
grant_types: ['authorization_code', 'refresh_token'],
response_types: ['code'],
}),
});
if (!response.ok) {
throw new Error(`Dynamic client registration failed: HTTP ${response.status}`);
};
}
const data = (await response.json());
if (typeof data.client_id !== 'string' || data.client_id.length === 0) {
throw new Error('Dynamic client registration response missing `client_id`');
// Per-flow state for CSRF defense. Our callback server validates this on
// its side too — defense in depth.
state() {
return this.opts.state;
}
return data.client_id;
}
async function exchangeCode(metadata, clientId, code, redirectUri, verifier, fetchImpl) {
const body = new URLSearchParams({
grant_type: 'authorization_code',
code,
redirect_uri: redirectUri,
client_id: clientId,
code_verifier: verifier,
}).toString();
const response = await fetchImpl(metadata.token_endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded', Accept: 'application/json' },
body,
});
if (!response.ok) {
// Capping the error body keeps verifier/code material out of stderr if
// the AS ever echoes them back in a regression.
const detail = (await response.text()).slice(0, TOKEN_ERROR_BODY_CAP);
throw new Error(`Token exchange failed: HTTP ${response.status}: ${detail}`);
async clientInformation() {
return (await this.loadCache()).clientInformation;
}
const data = (await response.json());
if (typeof data.access_token !== 'string' || data.access_token.length === 0) {
throw new Error('Token response missing `access_token`');
async saveClientInformation(info) {
await this.mergeCache({ clientInformation: info });
}
return {
accessToken: data.access_token,
...(typeof data.expires_in === 'number' && data.expires_in > 0
? { expiresIn: data.expires_in }
: {}),
};
async tokens() {
return (await this.loadCache()).tokens;
}
async saveTokens(tokens) {
// The verifier is single-use; once tokens land we don't need it on disk.
const cached = await this.loadCache();
const next = {
serverURL: this.opts.serverURL,
tokens,
...(cached.clientInformation ? { clientInformation: cached.clientInformation } : {}),
};
await this.opts.store.save(next);
}
async saveCodeVerifier(verifier) {
await this.mergeCache({ codeVerifier: verifier });
}
async codeVerifier() {
const cached = await this.loadCache();
if (!cached.codeVerifier) {
throw new Error('No PKCE code verifier in cache — OAuth state was cleared between auth() calls');
}
return cached.codeVerifier;
}
async redirectToAuthorization(authorizationUrl) {
// Enforced here (not just in defaultOpenBrowser) so an injected opener
// can't bypass the guard. The AS-supplied `authorization_endpoint` is
// attacker-influenceable if the discovered port has been hijacked.
assertLoopbackHTTPURL(authorizationUrl.toString());
await this.opts.openBrowser(authorizationUrl.toString());
}
async invalidateCredentials(scope) {
if (scope === 'all') {
await this.opts.store.clear();
return;
}
const cached = await this.opts.store.load();
if (!cached)
return;
const next = { ...cached };
if (scope === 'client')
delete next.clientInformation;
if (scope === 'tokens')
delete next.tokens;
if (scope === 'verifier')
delete next.codeVerifier;
// 'discovery' — we don't cache discovery state, nothing to do.
await this.opts.store.save(next);
}
async loadCache() {
const stored = await this.opts.store.load();
// Cache must belong to the server we were constructed for. A stale entry
// for a different server gets dropped here rather than overwritten — the
// alternative (always stamping `serverURL: this.opts.serverURL` on save)
// would silently graft another server's tokens onto our cache.
if (stored && stored.serverURL === this.opts.serverURL)
return stored;
return { serverURL: this.opts.serverURL };
}
async mergeCache(patch) {
const cached = await this.loadCache();
await this.opts.store.save({ ...cached, ...patch, serverURL: this.opts.serverURL });
}
}
function buildAuthURL(metadata, clientId, redirectUri, challenge, state) {
const url = new URL(metadata.authorization_endpoint);
url.searchParams.set('response_type', 'code');
url.searchParams.set('client_id', clientId);
url.searchParams.set('redirect_uri', redirectUri);
url.searchParams.set('code_challenge', challenge);
url.searchParams.set('code_challenge_method', 'S256');
url.searchParams.set('state', state);
return url.toString();
}
// Refuse to launch anything but an HTTP(S) URL pointing at loopback. An

@@ -184,3 +203,4 @@ // attacker who took over the discovered port could otherwise feed us an

function defaultOpenBrowser(url) {
assertLoopbackHTTPURL(url);
// URL guard lives in BridgeProvider.redirectToAuthorization so an injected
// opener can't bypass it; here we just spawn `/usr/bin/open`.
const child = spawn('/usr/bin/open', [url], { stdio: 'ignore', detached: true });

@@ -193,8 +213,2 @@ // Without this listener, a missing `/usr/bin/open` (non-macOS) would crash

}
async function fetchJSON(url, fetchImpl, init) {
const response = await fetchImpl(url, init);
if (!response.ok)
throw new Error(`HTTP ${response.status} fetching ${url}`);
return (await response.json());
}
//# sourceMappingURL=client.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/oauth/client.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,4EAA4E;AAC5E,8EAA8E;AAC9E,sEAAsE;AAEtE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAuB,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,UAAU,EAAoB,MAAM,YAAY,CAAC;AAqB1D,MAAM,WAAW,GAAG,kBAAkB,CAAC;AACvC,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAYjC,MAAM,OAAO,WAAW;IAOJ;IACC;IAPF,SAAS,CAAe;IACxB,eAAe,CAAc;IAC7B,uBAAuB,CAAsB;IAC7C,OAAO,CAAa;IAErC,YACkB,SAAc,EACb,QAAoB,IAAI,UAAU,EAAE,EACrD,OAA2B,EAAE;QAFb,cAAS,GAAT,SAAS,CAAK;QACb,UAAK,GAAL,KAAK,CAA+B;QAGrD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC;QACrC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,WAAW,IAAI,kBAAkB,CAAC;QAC9D,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,mBAAmB,IAAI,mBAAmB,CAAC;QAC/E,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACvC,IAAI,MAAM,IAAI,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9G,OAAO,MAAM,CAAC,WAAW,CAAC;QAC5B,CAAC;QACD,OAAO,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,UAAU;QACd,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;IAEO,SAAS,CAAC,KAAkB;QAClC,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,OAAO,KAAK,CAAC;QAC9C,6EAA6E;QAC7E,OAAO,SAAS,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC;IACxD,CAAC;IAEO,KAAK,CAAC,OAAO;QACnB,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1E,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,uBAAuB,EAAE,CAAC;QACtD,MAAM,WAAW,GAAG,oBAAoB,QAAQ,CAAC,IAAI,KAAK,CAAC;QAC3D,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC7E,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;YACnG,MAAM,SAAS,GAAG,SAAS,IAAI,IAAI;gBACjC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,SAAS,GAAG,KAAK,CAAC,CAAC,WAAW,EAAE;gBACtE,CAAC,CAAC,IAAI,CAAC;YACT,MAAM,MAAM,GAAgB;gBAC1B,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE;gBACpC,QAAQ;gBACR,WAAW;gBACX,SAAS;gBACT,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,WAAW,EAAE;aACxC,CAAC;YACF,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC9B,OAAO,WAAW,CAAC;QACrB,CAAC;gBAAS,CAAC;YACT,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,SAAS,CACrB,QAA4B,EAC5B,QAAgB,EAChB,WAAmB,EACnB,QAAwB;QAExB,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;QAC5B,MAAM,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QAE1G,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;QAChD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,MAAM,MAAM,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9E,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,CAAC,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnE,0EAA0E;QAC1E,uEAAuE;QACvE,IAAI,MAAM,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAE7E,OAAO,MAAM,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACzG,CAAC;CACF;AAED,KAAK,UAAU,kBAAkB,CAAC,SAAc,EAAE,SAAuB;IACvE,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;IAChC,IAAI,QAAQ,GAAG,MAAM,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,SAAS,CAC1B,GAAG,MAAM,uCAAuC,EAChD,SAAS,CACV,CAAC;QACF,MAAM,KAAK,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,KAAK;YAAE,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,yEAAyE;QACzE,0DAA0D;IAC5D,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,SAAS,CAC9B,GAAG,QAAQ,yCAAyC,EACpD,SAAS,CACV,CAAC;IACF,IACE,OAAO,QAAQ,CAAC,sBAAsB,KAAK,QAAQ;WAChD,OAAO,QAAQ,CAAC,cAAc,KAAK,QAAQ;WAC3C,OAAO,QAAQ,CAAC,qBAAqB,KAAK,QAAQ,EACrD,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IACjF,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,QAA4B,EAC5B,WAAmB,EACnB,SAAuB;IAEvB,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,qBAAqB,EAAE;QAC/D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,EAAE,kBAAkB,EAAE;QAC3E,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,WAAW,EAAE,WAAW;YACxB,aAAa,EAAE,CAAC,WAAW,CAAC;YAC5B,0BAA0B,EAAE,MAAM;YAClC,WAAW,EAAE,CAAC,oBAAoB,CAAC;YACnC,cAAc,EAAE,CAAC,MAAM,CAAC;SACzB,CAAC;KACH,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,4CAA4C,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACjF,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAyB,CAAC;IAC7D,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtE,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC;AACxB,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,QAA4B,EAC5B,QAAgB,EAChB,IAAY,EACZ,WAAmB,EACnB,QAAgB,EAChB,SAAuB;IAEvB,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC;QAC/B,UAAU,EAAE,oBAAoB;QAChC,IAAI;QACJ,YAAY,EAAE,WAAW;QACzB,SAAS,EAAE,QAAQ;QACnB,aAAa,EAAE,QAAQ;KACxB,CAAC,CAAC,QAAQ,EAAE,CAAC;IACd,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE;QACxD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE,MAAM,EAAE,kBAAkB,EAAE;QAC5F,IAAI;KACL,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,uEAAuE;QACvE,gDAAgD;QAChD,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;QACtE,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAkB,CAAC;IACtD,IAAI,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5E,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO;QACL,WAAW,EAAE,IAAI,CAAC,YAAY;QAC9B,GAAG,CAAC,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU,GAAG,CAAC;YAC5D,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE;YAChC,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CACnB,QAA4B,EAC5B,QAAgB,EAChB,WAAmB,EACnB,SAAiB,EACjB,KAAa;IAEb,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC;IACrD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IAC9C,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAC5C,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;IAClD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;IAClD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC;IACtD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC;AAED,wEAAwE;AACxE,wEAAwE;AACxE,uEAAuE;AACvE,yEAAyE;AACzE,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAC/C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,qCAAqC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,WAAW,IAAI,MAAM,CAAC,QAAQ,KAAK,WAAW,IAAI,MAAM,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;QACpG,MAAM,IAAI,KAAK,CAAC,sCAAsC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAW;IACrC,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,eAAe,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACjF,2EAA2E;IAC3E,uEAAuE;IACvE,oDAAoD;IACpD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAiB,CAAC,CAAC,CAAC;IAC3C,KAAK,CAAC,KAAK,EAAE,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,SAAS,CAAI,GAAW,EAAE,SAAuB,EAAE,IAAkB;IAClF,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC5C,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,aAAa,GAAG,EAAE,CAAC,CAAC;IAC7E,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAC;AACtC,CAAC"}
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/oauth/client.ts"],"names":[],"mappings":"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"}

@@ -1,3 +0,4 @@

// On-disk cache of an OAuth client_id + access token, keyed implicitly to the
// server URL it was issued for. Mode 0600 — same convention as ~/.pgpass,
// On-disk cache of an OAuth flow's state — client registration (DCR), the
// access/refresh tokens, and the transient PKCE code verifier the SDK needs
// to bridge two `auth()` calls. Mode 0600 — same convention as ~/.pgpass,
// ~/.aws/credentials, mcp-remote's ~/.mcp-auth, and ssh keys.

@@ -32,16 +33,12 @@ import { promises as fs } from 'node:fs';

}
if (typeof parsed.serverURL !== 'string'
|| typeof parsed.clientId !== 'string'
|| typeof parsed.accessToken !== 'string') {
if (typeof parsed.serverURL !== 'string')
return null;
}
return {
serverURL: parsed.serverURL,
clientId: parsed.clientId,
accessToken: parsed.accessToken,
expiresAt: typeof parsed.expiresAt === 'string' ? parsed.expiresAt : null,
createdAt: typeof parsed.createdAt === 'string' ? parsed.createdAt : new Date().toISOString(),
...(parsed.clientInformation ? { clientInformation: parsed.clientInformation } : {}),
...(parsed.tokens ? { tokens: parsed.tokens } : {}),
...(parsed.codeVerifier ? { codeVerifier: parsed.codeVerifier } : {}),
};
}
async save(token) {
async save(state) {
await fs.mkdir(dirname(this.path), { recursive: true });

@@ -54,3 +51,3 @@ // Atomic write: stage to a unique temp file then rename. POSIX rename is

try {
await fs.writeFile(tmp, JSON.stringify(token, null, 2), { mode: 0o600 });
await fs.writeFile(tmp, JSON.stringify(state, null, 2), { mode: 0o600 });
await fs.chmod(tmp, 0o600); // umask-resistant

@@ -57,0 +54,0 @@ await fs.rename(tmp, this.path);

@@ -1,1 +0,1 @@

{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/oauth/store.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/oauth/store.ts"],"names":[],"mappings":"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"}
{
"name": "@pasteapp/mcp",
"version": "0.1.0",
"version": "0.1.1",
"description": "Local MCP server bridge for Paste — give Claude Desktop, Claude Code, Cursor, Codex, and other AI tools access to your Mac clipboard history and pinboards.",

@@ -42,3 +42,18 @@ "keywords": [

"node": ">=18"
},
"scripts": {
"build": "rm -rf dist && tsc && chmod +x dist/index.js",
"test": "vitest run",
"dev": "tsx src/index.ts",
"prepublishOnly": "npm run build && npm test"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.21.0"
},
"devDependencies": {
"@types/node": "^22.10.0",
"tsx": "^4.19.0",
"typescript": "^5.7.0",
"vitest": "^4.1.0"
}
}
import { createHash, randomBytes } from 'node:crypto';
function base64URL(buf) {
return buf.toString('base64url');
}
export function generatePKCE() {
const verifier = base64URL(randomBytes(32));
const challenge = base64URL(createHash('sha256').update(verifier).digest());
return { verifier, challenge };
}
export function generateState() {
return base64URL(randomBytes(16));
}
//# sourceMappingURL=pkce.js.map
{"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../src/oauth/pkce.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAOtD,SAAS,SAAS,CAAC,GAAW;IAC5B,OAAO,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,MAAM,QAAQ,GAAG,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5E,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;AACpC,CAAC"}