rewind-mcp-server 0.1.0
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.
- package/README.md +140 -0
- package/dist/client.d.ts +21 -0
- package/dist/client.js +62 -0
- package/dist/client.js.map +1 -0
- package/dist/consent.d.ts +10 -0
- package/dist/consent.js +148 -0
- package/dist/consent.js.map +1 -0
- package/dist/github-auth.d.ts +21 -0
- package/dist/github-auth.js +60 -0
- package/dist/github-auth.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts.d.ts +2 -0
- package/dist/prompts.js +93 -0
- package/dist/prompts.js.map +1 -0
- package/dist/resources.d.ts +3 -0
- package/dist/resources.js +80 -0
- package/dist/resources.js.map +1 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.js +59 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/collecting.d.ts +3 -0
- package/dist/tools/collecting.js +92 -0
- package/dist/tools/collecting.js.map +1 -0
- package/dist/tools/cross-domain.d.ts +3 -0
- package/dist/tools/cross-domain.js +114 -0
- package/dist/tools/cross-domain.js.map +1 -0
- package/dist/tools/helpers.d.ts +32 -0
- package/dist/tools/helpers.js +69 -0
- package/dist/tools/helpers.js.map +1 -0
- package/dist/tools/listening.d.ts +3 -0
- package/dist/tools/listening.js +176 -0
- package/dist/tools/listening.js.map +1 -0
- package/dist/tools/reading.d.ts +3 -0
- package/dist/tools/reading.js +85 -0
- package/dist/tools/reading.js.map +1 -0
- package/dist/tools/running.d.ts +3 -0
- package/dist/tools/running.js +135 -0
- package/dist/tools/running.js.map +1 -0
- package/dist/tools/watching.d.ts +3 -0
- package/dist/tools/watching.js +138 -0
- package/dist/tools/watching.js.map +1 -0
- package/dist/worker.d.ts +20 -0
- package/dist/worker.js +173 -0
- package/dist/worker.js.map +1 -0
- package/package.json +59 -0
package/dist/worker.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare Worker entry point for remote MCP access (Claude iOS, claude.ai).
|
|
3
|
+
* Deployed at mcp.rewind.rest.
|
|
4
|
+
*
|
|
5
|
+
* Uses @cloudflare/workers-oauth-provider for OAuth 2.1 with GitHub as the
|
|
6
|
+
* upstream identity provider. The OAuth layer is only for the remote transport;
|
|
7
|
+
* local stdio transport (Claude Desktop, Claude Code) uses REWIND_API_KEY directly.
|
|
8
|
+
*/
|
|
9
|
+
import { OAuthProvider } from '@cloudflare/workers-oauth-provider';
|
|
10
|
+
import { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js';
|
|
11
|
+
import { RewindClient } from './client.js';
|
|
12
|
+
import { createServer } from './server.js';
|
|
13
|
+
import { renderConsentPage } from './consent.js';
|
|
14
|
+
import { getGitHubAuthorizeUrl, exchangeGitHubCode } from './github-auth.js';
|
|
15
|
+
// Per-isolate rate limiting
|
|
16
|
+
const rateLimitWindows = new Map();
|
|
17
|
+
const RATE_LIMIT_RPM = 120;
|
|
18
|
+
const RATE_LIMIT_WINDOW_MS = 60_000;
|
|
19
|
+
function checkRateLimit(key) {
|
|
20
|
+
const now = Date.now();
|
|
21
|
+
const entry = rateLimitWindows.get(key);
|
|
22
|
+
if (!entry || now >= entry.resetAt) {
|
|
23
|
+
rateLimitWindows.set(key, {
|
|
24
|
+
count: 1,
|
|
25
|
+
resetAt: now + RATE_LIMIT_WINDOW_MS,
|
|
26
|
+
});
|
|
27
|
+
return { allowed: true, remaining: RATE_LIMIT_RPM - 1 };
|
|
28
|
+
}
|
|
29
|
+
entry.count++;
|
|
30
|
+
if (entry.count > RATE_LIMIT_RPM) {
|
|
31
|
+
return { allowed: false, remaining: 0 };
|
|
32
|
+
}
|
|
33
|
+
return { allowed: true, remaining: RATE_LIMIT_RPM - entry.count };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* MCP API handler -- receives authenticated requests after OAuth.
|
|
37
|
+
* ctx.props contains the GrantProps set during authorization.
|
|
38
|
+
*/
|
|
39
|
+
const mcpHandler = {
|
|
40
|
+
async fetch(request, env, _ctx) {
|
|
41
|
+
// Rate limit by IP
|
|
42
|
+
const ip = request.headers.get('cf-connecting-ip') ?? 'unknown';
|
|
43
|
+
const rateResult = checkRateLimit(ip);
|
|
44
|
+
if (!rateResult.allowed) {
|
|
45
|
+
return Response.json({ error: 'Too Many Requests' }, { status: 429, headers: { 'Retry-After': '60' } });
|
|
46
|
+
}
|
|
47
|
+
// Get user props from OAuth context
|
|
48
|
+
const props = request.props;
|
|
49
|
+
if (!props?.rewindApiKey) {
|
|
50
|
+
return Response.json({ error: 'Unauthorized' }, { status: 401 });
|
|
51
|
+
}
|
|
52
|
+
const apiUrl = env.REWIND_API_URL || 'https://api.rewind.rest';
|
|
53
|
+
const client = new RewindClient(apiUrl, props.rewindApiKey);
|
|
54
|
+
const server = createServer(client);
|
|
55
|
+
const transport = new WebStandardStreamableHTTPServerTransport({
|
|
56
|
+
sessionIdGenerator: undefined,
|
|
57
|
+
enableJsonResponse: true,
|
|
58
|
+
});
|
|
59
|
+
await server.connect(transport);
|
|
60
|
+
return transport.handleRequest(request);
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Default handler -- serves the authorize page and GitHub callback.
|
|
65
|
+
* All non-API, non-OAuth-infrastructure requests go here.
|
|
66
|
+
*/
|
|
67
|
+
const defaultHandler = {
|
|
68
|
+
async fetch(request, env, _ctx) {
|
|
69
|
+
const url = new URL(request.url);
|
|
70
|
+
// Health check
|
|
71
|
+
if (url.pathname === '/' || url.pathname === '/health') {
|
|
72
|
+
return Response.json({ status: 'ok', service: 'rewind-mcp-server' });
|
|
73
|
+
}
|
|
74
|
+
// Authorization page -- user sees consent screen, clicks "Sign in with GitHub"
|
|
75
|
+
if (url.pathname === '/authorize') {
|
|
76
|
+
// Parse the MCP OAuth authorization request from query params
|
|
77
|
+
const clientName = url.searchParams.get('client_name') ?? 'Claude';
|
|
78
|
+
const scopes = (url.searchParams.get('scope') ?? 'read').split(' ');
|
|
79
|
+
const state = url.searchParams.get('state') ?? '';
|
|
80
|
+
// Store the original OAuth params in a short-lived KV key so we can
|
|
81
|
+
// retrieve them after GitHub redirects back
|
|
82
|
+
const oauthState = crypto.randomUUID();
|
|
83
|
+
await env.OAUTH_KV.put(`github_state:${oauthState}`, JSON.stringify({
|
|
84
|
+
originalUrl: request.url,
|
|
85
|
+
state,
|
|
86
|
+
}), { expirationTtl: 600 } // 10 minutes
|
|
87
|
+
);
|
|
88
|
+
const callbackUrl = `${url.origin}/callback`;
|
|
89
|
+
const gitHubUrl = getGitHubAuthorizeUrl(env.GITHUB_CLIENT_ID, callbackUrl, oauthState);
|
|
90
|
+
const html = renderConsentPage({
|
|
91
|
+
clientName,
|
|
92
|
+
scopes,
|
|
93
|
+
gitHubAuthorizeUrl: gitHubUrl,
|
|
94
|
+
});
|
|
95
|
+
return new Response(html, {
|
|
96
|
+
headers: { 'Content-Type': 'text/html' },
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
// GitHub OAuth callback -- user has authenticated with GitHub
|
|
100
|
+
if (url.pathname === '/callback') {
|
|
101
|
+
const code = url.searchParams.get('code');
|
|
102
|
+
const githubState = url.searchParams.get('state');
|
|
103
|
+
if (!code || !githubState) {
|
|
104
|
+
return Response.json({ error: 'Missing code or state from GitHub' }, { status: 400 });
|
|
105
|
+
}
|
|
106
|
+
// Retrieve the original OAuth params
|
|
107
|
+
const storedState = await env.OAUTH_KV.get(`github_state:${githubState}`);
|
|
108
|
+
if (!storedState) {
|
|
109
|
+
return Response.json({ error: 'Invalid or expired state. Please try connecting again.' }, { status: 400 });
|
|
110
|
+
}
|
|
111
|
+
// eslint-disable-next-line drizzle/enforce-delete-with-where -- KV.delete(), not Drizzle
|
|
112
|
+
await env.OAUTH_KV.delete(`github_state:${githubState}`);
|
|
113
|
+
const { originalUrl } = JSON.parse(storedState);
|
|
114
|
+
// Exchange GitHub code for user info
|
|
115
|
+
let gitHubUser;
|
|
116
|
+
try {
|
|
117
|
+
gitHubUser = await exchangeGitHubCode(code, env.GITHUB_CLIENT_ID, env.GITHUB_CLIENT_SECRET);
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
return Response.json({
|
|
121
|
+
error: `GitHub authentication failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
122
|
+
}, { status: 400 });
|
|
123
|
+
}
|
|
124
|
+
// Check if this GitHub user is in the allowlist
|
|
125
|
+
const allowlist = JSON.parse(env.USER_ALLOWLIST || '{}');
|
|
126
|
+
const rewindUserId = allowlist[String(gitHubUser.id)];
|
|
127
|
+
if (rewindUserId === undefined) {
|
|
128
|
+
return Response.json({
|
|
129
|
+
error: `GitHub user @${gitHubUser.login} is not authorized. Contact the Rewind admin to request access.`,
|
|
130
|
+
}, { status: 403 });
|
|
131
|
+
}
|
|
132
|
+
// Complete the OAuth authorization using the workers-oauth-provider helpers.
|
|
133
|
+
// We need to redirect back to the original authorize URL with the approval.
|
|
134
|
+
// The OAuthProvider handles the actual code generation and redirect.
|
|
135
|
+
// We pass the user info as props that will be available in the API handler.
|
|
136
|
+
// Redirect to the original authorize URL with an approval indicator
|
|
137
|
+
// The OAuthProvider's authorize flow will pick this up
|
|
138
|
+
const approveUrl = new URL(originalUrl);
|
|
139
|
+
approveUrl.searchParams.set('github_user_id', String(gitHubUser.id));
|
|
140
|
+
approveUrl.searchParams.set('github_login', gitHubUser.login);
|
|
141
|
+
approveUrl.searchParams.set('rewind_user_id', String(rewindUserId));
|
|
142
|
+
approveUrl.searchParams.set('approved', 'true');
|
|
143
|
+
return Response.redirect(approveUrl.toString(), 302);
|
|
144
|
+
}
|
|
145
|
+
return Response.json({ error: 'Not found', docs: 'https://docs.rewind.rest' }, { status: 404 });
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
// OAuth Provider configuration
|
|
149
|
+
const provider = new OAuthProvider({
|
|
150
|
+
apiRoute: '/mcp',
|
|
151
|
+
apiHandler: mcpHandler,
|
|
152
|
+
defaultHandler: defaultHandler,
|
|
153
|
+
authorizeEndpoint: '/authorize',
|
|
154
|
+
tokenEndpoint: '/token',
|
|
155
|
+
clientRegistrationEndpoint: '/register',
|
|
156
|
+
accessTokenTTL: 3600, // 1 hour
|
|
157
|
+
refreshTokenTTL: 7_776_000, // 90 days
|
|
158
|
+
scopesSupported: [
|
|
159
|
+
'read',
|
|
160
|
+
'read:listening',
|
|
161
|
+
'read:running',
|
|
162
|
+
'read:watching',
|
|
163
|
+
'read:collecting',
|
|
164
|
+
'read:reading',
|
|
165
|
+
'read:feed',
|
|
166
|
+
],
|
|
167
|
+
allowPlainPKCE: false, // S256 only per MCP spec
|
|
168
|
+
resourceMetadata: {
|
|
169
|
+
resource_name: 'Rewind Personal Data API',
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
export default provider;
|
|
173
|
+
//# sourceMappingURL=worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "rewind-mcp-server",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for the Rewind personal data API",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"rewind-mcp-server": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc",
|
|
18
|
+
"dev": "tsc --watch",
|
|
19
|
+
"start": "node dist/index.js",
|
|
20
|
+
"prepublishOnly": "npm run build"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"mcp",
|
|
24
|
+
"mcp-server",
|
|
25
|
+
"rewind",
|
|
26
|
+
"personal-data",
|
|
27
|
+
"lastfm",
|
|
28
|
+
"strava",
|
|
29
|
+
"plex",
|
|
30
|
+
"discogs",
|
|
31
|
+
"instapaper",
|
|
32
|
+
"claude",
|
|
33
|
+
"anthropic"
|
|
34
|
+
],
|
|
35
|
+
"author": "Patrick Dugan",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"homepage": "https://rewind.rest",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/pdugan20/rewind.git",
|
|
41
|
+
"directory": "mcp-server"
|
|
42
|
+
},
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/pdugan20/rewind/issues"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=18.0.0"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@cloudflare/workers-oauth-provider": "^0.4.0",
|
|
51
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
52
|
+
"zod": "^3.23.0"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@cloudflare/workers-types": "^4.20260403.1",
|
|
56
|
+
"@types/node": "^22.0.0",
|
|
57
|
+
"typescript": "^5.9.3"
|
|
58
|
+
}
|
|
59
|
+
}
|