@markmnl/fmsg-mcp 1.0.0 → 1.1.1

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.
@@ -31,7 +31,7 @@ Save this as `Caddyfile`:
31
31
 
32
32
  ```caddyfile
33
33
  mcp.example.com {
34
- @fmsg path /mcp /mcp/attachments/* /.well-known/oauth-protected-resource /.well-known/oauth-protected-resource/*
34
+ @fmsg path /mcp /mcp/* /.well-known/oauth-protected-resource /.well-known/oauth-protected-resource/*
35
35
  handle @fmsg {
36
36
  reverse_proxy 127.0.0.1:8765 {
37
37
  transport http {
@@ -85,7 +85,7 @@ Set `FMSG_MCP_PUBLIC_URL` to the exact external MCP endpoint when using API keys
85
85
  to `FMSG_MCP_OAUTH_RESOURCE_URL`; if both are set, they must match. These URLs require HTTPS outside
86
86
  loopback and cannot contain credentials, queries or fragments. Request Host and forwarded headers
87
87
  never select the download URL. If the proxy exposes MCP under a different public path, map that
88
- path and its `/attachments/*` suffix to `/mcp` and `/mcp/attachments/*` respectively.
88
+ path and everything under it to `/mcp` and `/mcp/*` respectively.
89
89
 
90
90
  Downloads use the original MIME type, `Content-Disposition: attachment`, Unicode filename encoding,
91
91
  `Cache-Control: no-store` and `X-Content-Type-Options: nosniff`. The body streams with backpressure;
@@ -94,7 +94,40 @@ truncated file. No temporary server files, signed URLs or tokens in query string
94
94
  Range/resume requests are not implemented: GET returns the full file. Treat a failed transfer as
95
95
  incomplete and discard its partial local output before retrying.
96
96
 
97
- Host and Origin validation applies to downloads too. Allowed browser clients can preflight GET
97
+ ## Attachment uploads
98
+
99
+ `create_draft` returns an upload URL template such as
100
+ `https://mcp.example.com/mcp/drafts/123/attachments/{filename}`. A host that can send the MCP
101
+ connection's Authorization header PUTs the raw file bytes there, then calls `send_draft`:
102
+
103
+ ```sh
104
+ curl -X PUT -H "Authorization: Bearer $TOKEN" \
105
+ -H "x-content-sha256: $(sha256sum report.pdf | cut -c1-64)" \
106
+ --data-binary @report.pdf https://mcp.example.com/mcp/drafts/123/attachments/report.pdf
107
+ ```
108
+
109
+ The server streams the body straight into the fmsg draft (`POST /fmsg/:id/attach`) without
110
+ storing it, so the draft and its attachments are visible in the user's other fmsg clients and the
111
+ fmsg host's own size limits apply; its refusal comes back with its status and text. OAuth requires
112
+ `fmsg:write`. The response is `201` with `filename`, `size`, `sha256` and `type`. The fmsg host may
113
+ rename a duplicate filename; the response gives the stored name. Errors are JSON `{"error": "..."}`,
114
+ and the fmsg host's own reason is passed through when it gives one.
115
+
116
+ - `x-content-sha256` (optional, hex): a mismatch answers `422`, and the attachment is removed again.
117
+ - `Content-Encoding: gzip` or `deflate` (optional): the server decodes the body while streaming, so
118
+ fmsg stores the original file; `size` and `sha256` describe the decoded bytes. Other encodings
119
+ answer `415`; corrupt or truncated compressed data answers `400` and nothing is kept.
120
+ - The file's type comes from `Content-Type`, except that `application/x-www-form-urlencoded`
121
+ (curl's default for `--data-binary`) and `application/octet-stream` are replaced by the type the
122
+ filename implies.
123
+
124
+ Uploads have no total time limit: each chunk resets a 60-second idle timeout, as for downloads.
125
+ Other requests must arrive in full within 60 seconds. Upload connections close after the response.
126
+ The server does the proxying to the fmsg host itself: a TLS proxy that forwards `/mcp/*`, like the
127
+ Caddy example above, needs no upload-specific settings. Proxies that cap request bodies by default
128
+ (nginx's `client_max_body_size` is 1 MB) should not cap them below the fmsg host's attachment limit.
129
+
130
+ Host and Origin validation applies to downloads and uploads too. Allowed browser clients can preflight GET
98
131
  with Authorization and read Content-Disposition. Hosts must attach the connection credential
99
132
  themselves; never ask the model to locate or copy tokens. Clients that cannot fetch authenticated
100
133
  links can still use `download_attachment` inline. Compatibility of authenticated links with each
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@markmnl/fmsg-mcp",
3
3
  "mcpName": "io.github.markmnl/fmsg-mcp",
4
- "version": "1.0.0",
4
+ "version": "1.1.1",
5
5
  "description": "MCP server for fmsg: send and receive federated messages from any AI agent via a deployed fmsg Web API",
6
6
  "type": "module",
7
7
  "license": "MIT",
package/server.json CHANGED
@@ -8,13 +8,13 @@
8
8
  "url": "https://github.com/markmnl/fmsg-mcp",
9
9
  "source": "github"
10
10
  },
11
- "version": "1.0.0",
11
+ "version": "1.1.1",
12
12
  "packages": [
13
13
  {
14
14
  "registryType": "npm",
15
15
  "registryBaseUrl": "https://registry.npmjs.org",
16
16
  "identifier": "@markmnl/fmsg-mcp",
17
- "version": "1.0.0",
17
+ "version": "1.1.1",
18
18
  "transport": {
19
19
  "type": "stdio"
20
20
  },