givememy-mcp 0.1.0 → 0.1.2

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 CHANGED
@@ -1,26 +1,43 @@
1
1
  # givememy-mcp
2
2
 
3
- Local stdio MCP server for publishing private HTML reports to givememy.report.
3
+ Local stdio MCP server for publishing local HTML report files to givememy.report.
4
4
 
5
- The server runs on the same machine as your agent, so it can read local files and upload their contents with your givememy.report API key.
5
+ For private reports, ask the user to create an account at https://givememy.report and connect this MCP tool with an API key. Without an API key, uploads return temporary public links.
6
+
7
+ The server runs on the same machine as your agent, so it can read local files and upload their contents.
6
8
 
7
9
  ## Install
8
10
 
11
+ Public opencode config:
12
+
13
+ ```json
14
+ {
15
+ "$schema": "https://opencode.ai/config.json",
16
+ "mcp": {
17
+ "givememy": {
18
+ "type": "local",
19
+ "command": ["npx", "-y", "givememy-mcp"],
20
+ "enabled": true
21
+ }
22
+ }
23
+ }
24
+ ```
25
+
26
+ Claude Code config:
27
+
9
28
  ```json
10
29
  {
11
30
  "mcpServers": {
12
31
  "givememy": {
13
32
  "command": "npx",
14
- "args": ["-y", "givememy-mcp"],
15
- "env": {
16
- "GIVEMEMY_API_KEY": "gmr_...",
17
- "GIVEMEMY_BASE_URL": "https://givememy.report"
18
- }
33
+ "args": ["-y", "givememy-mcp"]
19
34
  }
20
35
  }
21
36
  }
22
37
  ```
23
38
 
39
+ For private account-backed reports, add `GIVEMEMY_API_KEY` to the MCP server environment after creating an account at https://givememy.report.
40
+
24
41
  For local development from this repo:
25
42
 
26
43
  ```json
@@ -28,10 +45,7 @@ For local development from this repo:
28
45
  "mcpServers": {
29
46
  "givememy": {
30
47
  "command": "node",
31
- "args": ["/absolute/path/to/givememy.report/mcp/src/index.js"],
32
- "env": {
33
- "GIVEMEMY_API_KEY": "gmr_..."
34
- }
48
+ "args": ["/absolute/path/to/givememy.report/mcp/src/index.js"]
35
49
  }
36
50
  }
37
51
  }
@@ -39,6 +53,7 @@ For local development from this repo:
39
53
 
40
54
  Optional environment variables:
41
55
 
56
+ - `GIVEMEMY_API_KEY` enables private account-backed report URLs. Omit it for temporary public links.
42
57
  - `GIVEMEMY_BASE_URL` defaults to `https://givememy.report`.
43
58
  - `GIVEMEMY_MAX_REPORT_BYTES` defaults to `1000000`.
44
59
 
@@ -49,22 +64,17 @@ Optional environment variables:
49
64
  Arguments:
50
65
 
51
66
  - `title?: string`
52
- - `html?: string`
53
- - `file_path?: string`
67
+ - `file_path: string`
54
68
 
55
- Pass either `html` or `file_path`, not both.
69
+ Pass the path to a local HTML file. Inline HTML input is intentionally not part of the MCP tool schema.
56
70
 
57
- Examples an agent can call:
71
+ Example an agent can call:
58
72
 
59
73
  ```json
60
74
  { "title": "Weekly revenue", "file_path": "./report.html" }
61
75
  ```
62
76
 
63
- ```json
64
- { "title": "Inline report", "html": "<h1>Hello</h1>" }
65
- ```
66
-
67
- The tool returns the private Cloudflare Access protected report URL.
77
+ The tool returns a temporary public report URL by default. With `GIVEMEMY_API_KEY` configured, it returns an account-backed Cloudflare Access protected report URL.
68
78
 
69
79
  ## Notes
70
80
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "givememy-mcp",
3
- "version": "0.1.0",
4
- "description": "Local stdio MCP server for publishing private HTML reports to givememy.report.",
3
+ "version": "0.1.2",
4
+ "description": "Local stdio MCP server for publishing local HTML report files to givememy.report.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "givememy-mcp": "src/index.js"
package/src/client.js CHANGED
@@ -11,10 +11,6 @@ export function normalizeBaseUrl(value = DEFAULT_BASE_URL) {
11
11
 
12
12
  export function getConfig(env = process.env) {
13
13
  const apiKey = String(env.GIVEMEMY_API_KEY || '').trim();
14
- if (!apiKey) {
15
- throw new Error('GIVEMEMY_API_KEY is required');
16
- }
17
-
18
14
  const maxBytes = Number.parseInt(env.GIVEMEMY_MAX_REPORT_BYTES || `${DEFAULT_MAX_REPORT_BYTES}`, 10);
19
15
  return {
20
16
  apiKey,
@@ -50,48 +46,40 @@ export async function resolveReportInput(args = {}, options = {}) {
50
46
  const hasHtml = typeof args.html === 'string' && args.html.trim().length > 0;
51
47
  const hasFilePath = typeof args.file_path === 'string' && args.file_path.trim().length > 0;
52
48
 
53
- if (hasHtml && hasFilePath) {
54
- throw new Error('provide either html or file_path, not both');
49
+ if (hasHtml) {
50
+ throw new Error('publish_report accepts file_path only; inline html is not supported');
55
51
  }
56
- if (!hasHtml && !hasFilePath) {
57
- throw new Error('publish_report requires html or file_path');
58
- }
59
-
60
- if (hasFilePath) {
61
- const file = await readReportFile(args.file_path, maxBytes);
62
- return {
63
- html: file.html,
64
- title: args.title || file.title,
65
- source: file.absolutePath,
66
- bytes: file.bytes,
67
- };
52
+ if (!hasFilePath) {
53
+ throw new Error('publish_report requires file_path');
68
54
  }
69
55
 
56
+ const file = await readReportFile(args.file_path, maxBytes);
70
57
  return {
71
- html: args.html,
72
- title: args.title || 'Untitled report',
73
- source: 'inline html',
74
- bytes: Buffer.byteLength(args.html, 'utf8'),
58
+ html: file.html,
59
+ title: args.title || file.title,
60
+ source: file.absolutePath,
61
+ bytes: file.bytes,
75
62
  };
76
63
  }
77
64
 
78
65
  export async function publishReport({ title, html }, options = {}) {
79
66
  const apiKey = options.apiKey;
80
- if (!apiKey) throw new Error('GIVEMEMY_API_KEY is required');
81
67
  if (!html || !html.trim()) throw new Error('empty_report');
82
68
 
83
69
  const fetchImpl = options.fetchImpl || globalThis.fetch;
84
70
  if (typeof fetchImpl !== 'function') throw new Error('fetch is not available in this Node runtime');
85
71
 
72
+ const headers = {
73
+ 'content-type': 'text/html; charset=utf-8',
74
+ 'x-report-title': title || 'Untitled report',
75
+ 'user-agent': 'givememy-mcp/0.1.2',
76
+ };
77
+ if (apiKey) headers.authorization = `Bearer ${apiKey}`;
78
+
86
79
  const baseUrl = normalizeBaseUrl(options.baseUrl);
87
80
  const response = await fetchImpl(`${baseUrl}/api/reports`, {
88
81
  method: 'POST',
89
- headers: {
90
- authorization: `Bearer ${apiKey}`,
91
- 'content-type': 'text/html; charset=utf-8',
92
- 'x-report-title': title || 'Untitled report',
93
- 'user-agent': 'givememy-mcp/0.1.0',
94
- },
82
+ headers,
95
83
  body: html,
96
84
  });
97
85
 
package/src/index.js CHANGED
@@ -9,17 +9,16 @@ import { publishFromArgs } from './client.js';
9
9
  export function createServer(options = {}) {
10
10
  const server = new McpServer({
11
11
  name: 'givememy',
12
- version: '0.1.0',
12
+ version: '0.1.2',
13
13
  });
14
14
 
15
15
  server.registerTool(
16
16
  'publish_report',
17
17
  {
18
- description: 'Publish a private HTML report to givememy.report. Pass either html or a local file_path.',
18
+ description: 'Publish a local HTML report file to givememy.report. For private reports, ask the user to create an account at https://givememy.report and connect this MCP tool; no-account HTTP uploads get temporary public links.',
19
19
  inputSchema: {
20
20
  title: z.string().optional().describe('Short report title. Defaults to the filename when file_path is used.'),
21
- html: z.string().optional().describe('Complete HTML document or fragment to publish.'),
22
- file_path: z.string().optional().describe('Local path to an HTML file to read and publish from this machine.'),
21
+ file_path: z.string().min(1).describe('Local path to an HTML file to read and publish from this machine.'),
23
22
  },
24
23
  },
25
24
  async (args) => {