moltbook-http-mcp 1.1.1 → 1.2.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.
- package/LICENSE +1 -4
- package/README.md +29 -1
- package/dist/cli.js +1 -1
- package/dist/mcp/mcp.server-handler.js +1 -1
- package/dist/moltbook/moltbook.config.js +1 -1
- package/dist/server/app.auth.js +1 -1
- package/dist/server/app.server.js +2 -2
- package/dist/utils/env.js +1 -1
- package/dist/utils/logger.js +1 -1
- package/package.json +13 -12
- package/dist/config.js +0 -1
package/LICENSE
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2024 Venkatesh
|
|
4
|
-
Copyright (c) 2025 Indra
|
|
5
|
-
|
|
6
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
4
|
of this software and associated documentation files (the "Software"), to deal
|
|
8
5
|
in the Software without restriction, including without limitation the rights
|
|
@@ -19,4 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
19
16
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
17
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
18
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
-
SOFTWARE.
|
|
19
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -80,11 +80,39 @@ When run with piped stdin/stdout (e.g. by Cursor), stdio mode is used automatica
|
|
|
80
80
|
| API key | `MOLTBOOK_API_KEY` | — | **Required** for all tools except `moltbook_agent_register`. |
|
|
81
81
|
| MCP port | `-m`, `--mcpPort` | `3003` | Port for the MCP HTTP server (HTTP mode only). |
|
|
82
82
|
| Stdio | `--stdio` | auto | Use stdin/stdout for MCP (subprocess). Auto if stdin is not a TTY. |
|
|
83
|
+
| HTTPS key | `--key`, `MCP_HTTPS_KEY_PATH` | — | Path to TLS private key PEM; enables HTTPS when used with cert. |
|
|
84
|
+
| HTTPS cert | `--cert`, `MCP_HTTPS_CERT_PATH` | — | Path to TLS certificate PEM; enables HTTPS when used with key. |
|
|
83
85
|
|
|
84
86
|
```sh
|
|
85
87
|
moltbook-mcp --help
|
|
86
88
|
```
|
|
87
89
|
|
|
90
|
+
### HTTPS on localhost
|
|
91
|
+
|
|
92
|
+
To run the MCP HTTP server over HTTPS on localhost, provide a TLS key and certificate. Both are required.
|
|
93
|
+
|
|
94
|
+
**CLI:**
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
moltbook-mcp --key ./localhost-key.pem --cert ./localhost-cert.pem
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Environment:**
|
|
101
|
+
|
|
102
|
+
```sh
|
|
103
|
+
export MCP_HTTPS_KEY_PATH=./localhost-key.pem
|
|
104
|
+
export MCP_HTTPS_CERT_PATH=./localhost-cert.pem
|
|
105
|
+
moltbook-mcp
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Generating localhost certs:**
|
|
109
|
+
|
|
110
|
+
- **mkcert** (recommended; trusted in browsers): `mkcert -install` then `mkcert localhost` → `localhost+1.pem` (cert) and `localhost+1-key.pem` (key).
|
|
111
|
+
- **OpenSSL** (self-signed):
|
|
112
|
+
`openssl req -x509 -newkey rsa:4096 -keyout localhost-key.pem -out localhost-cert.pem -days 365 -nodes -subj /CN=localhost`
|
|
113
|
+
|
|
114
|
+
Then point your IDE at `https://localhost:3003/mcp` (or your port).
|
|
115
|
+
|
|
88
116
|
---
|
|
89
117
|
|
|
90
118
|
## Add MoltBook MCP to your IDE
|
|
@@ -93,7 +121,7 @@ moltbook-mcp --help
|
|
|
93
121
|
2. **Add the MCP server** in your IDE (e.g. Cursor → Settings → MCP). You can use either:
|
|
94
122
|
|
|
95
123
|
**Option A — HTTP (molt)**
|
|
96
|
-
Run the server yourself (`moltbook-mcp` or `moltbook-mcp -m 9000`), then point the IDE at the URL
|
|
124
|
+
Run the server yourself (`moltbook-mcp` or `moltbook-mcp -m 9000`), then point the IDE at the URL. Use `https://` if you started the server with `--key` and `--cert`:
|
|
97
125
|
|
|
98
126
|
```json
|
|
99
127
|
{
|
package/dist/cli.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";import{loadEnv as
|
|
2
|
+
"use strict";import{loadEnv as s}from"./utils/env.js";s();import o from"yargs";import{hideBin as i}from"yargs/helpers";import{startServer as a,startStdioServer as n}from"./index.js";import{getMCP_HTTPS_CERT_PATH as d,getMCP_HTTPS_KEY_PATH as p}from"./utils/env.js";const e=o(i(process.argv)).options({port:{type:"number",default:3003,alias:"p",describe:"Port for MCP HTTP server"},stdio:{type:"boolean",describe:"Run MCP over stdin/stdout. Default: true when stdin is not a TTY (subprocess), else false. Use --no-stdio to force HTTP server."},auth:{type:"boolean",default:!1,describe:"Require JWT auth on POST /mcp"},key:{type:"string",describe:"Path to TLS private key PEM (enables HTTPS with --cert)"},cert:{type:"string",describe:"Path to TLS certificate PEM (enables HTTPS with --key)"}}).help().alias("h","help").parseSync();e.help&&process.exit(0);const c=e.stdio===!1?!1:e.stdio===!0?!0:!process.stdin.isTTY;if(c)n({}).catch(t=>{console.error("MCP stdio server error:",t),process.exit(1)});else{const t=(e.key??p())||void 0,r=(e.cert??d())||void 0;a({mcpPort:e.port,auth:e.auth,keyPath:t||void 0,certPath:r||void 0})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{randomUUID as
|
|
1
|
+
"use strict";import{randomUUID as g}from"node:crypto";import{StreamableHTTPServerTransport as h}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as R}from"@modelcontextprotocol/sdk/types.js";import{transports as u}from"./mcp.transports.js";import{createMCPServer as v}from"./mcp.server.js";import{getMoltbookApiKey as b,runWithMoltbookApiKey as I}from"../utils/env.js";import{LOGGER as n}from"../utils/logger.js";const m={};function K(e){const r=e.headers.authorization;if(r?.startsWith("Bearer "))return r.slice(7).trim();const o=e.headers["x-api-key"];if(typeof o=="string")return o.trim();const i=e.query.apiKey;return typeof i=="string"?i.trim():""}export const handleRequest=async(e,r,o)=>{n.log("1.Received MCP request:",e.body);const{jsonrpc:i,id:p,method:l}=e.body;if(i!=="2.0"||!l){r.status(400).json({jsonrpc:"2.0",id:p||null,error:{code:-32600,message:"Invalid Request",data:"Must be valid JSON-RPC 2.0"}});return}const t=e.headers["mcp-session-id"],c=K(e),y=t?m[t]:void 0,f=b(),a=y??(c||f||"");if(!a){r.status(401).json({jsonrpc:"2.0",id:p??null,error:{code:-32001,message:"Missing API key. Send Authorization: Bearer <key>, X-API-Key: <key>, or ?apiKey=<key> in the URL."}});return}await I(a,async()=>{try{let s;if(t&&u[t])n.log(`Session exists: ${t}`),s=u[t];else if(!t&&R(e.body)){s=new h({sessionIdGenerator:()=>g(),enableJsonResponse:!0,onsessioninitialized:d=>{n.log(`Session initialized with ID: ${d}`),u[d]=s,m[d]=a}}),n.log("Connecting to MCP server with CLI params:",o),await v(o).connect(s),await s.handleRequest(e,r,e.body);return}else{r.status(400).json({jsonrpc:"2.0",error:{code:-32e3,message:"Bad Request: No valid session ID provided"},id:null});return}await s.handleRequest(e,r,e.body)}catch(s){n.error("Error handling MCP request:",s),r.headersSent||r.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:"Internal server error"},id:null})}})};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{
|
|
1
|
+
"use strict";import{getMoltbookApiKey as o}from"../utils/env.js";const r="https://www.moltbook.com/api/v1";export function getMoltbookBase(){return r}export function getApiKey(){const t=o();if(!t)throw new Error("MOLTBOOK_API_KEY is not set");return t}
|
package/dist/server/app.auth.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{
|
|
1
|
+
"use strict";import{jwtVerify as p,createRemoteJWKSet as l}from"jose";import{getAppApiKey as d,getAppDomain as u}from"../utils/env.js";export const apiKeyAuth=(e,t,r)=>{const n=d();if(!n){r();return}const s=e.headers.authorization,o=e.headers["x-api-key"],i=s?.startsWith("Bearer ")?s.slice(7):o??"";if(!i||i!==n){t.status(401).json({error:"Invalid or missing API key. Use Authorization: Bearer <key> or X-API-Key: <key>."});return}r()};let a=null;function f(){const e=u();if(!e)return null;if(!a){const t=e.startsWith("http")?`${e}/.well-known/jwks.json`:`https://${e}/.well-known/jwks.json`;a=l(new URL(t))}return a}async function h(e,t,r){const n=u();if(!n){t.status(503).json({error:"JWT auth not configured: APP_DOMAIN is not set"});return}const s=e.headers.authorization;if(!s?.startsWith("Bearer ")){t.status(401).end();return}const o=f();if(!o){t.status(503).json({error:"JWT auth not configured: APP_DOMAIN is not set"});return}try{const i=s.slice(7),{payload:c}=await p(i,o,{issuer:n,audience:"mcp"});e.user=c,r()}catch{t.status(401).end()}}export function requireAuth(e){return e?.auth?h:(t,r,n)=>n()}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";import
|
|
2
|
-
`)};const P=(s={})=>{const e=
|
|
1
|
+
"use strict";import p from"express";import h from"cors";import m from"fs";import u from"https";import{StdioServerTransport as f}from"@modelcontextprotocol/sdk/server/stdio.js";import{handleRequest as S}from"../mcp/mcp.server-handler.js";import{createMCPServer as y}from"../mcp/mcp.server.js";import{requireAuth as v}from"./app.auth.js";import{getMoltbookApiKey as g,getAppVersion as l}from"../utils/env.js";import{LOGGER as c}from"../utils/logger.js";export const startStdioServer=async(s={})=>{const e=new f;await y(s).connect(e),process.stderr.writable&&process.stderr.write(`Moltbook MCP stdio server ready
|
|
2
|
+
`)};const P=(s={})=>{const e=p();return e.use(h({origin:"*",exposedHeaders:["Mcp-Session-Id"]})),e.use(p.json()),e.use(p.json({limit:"10mb"})),e.use(p.urlencoded({extended:!0})),e.get("/health",async(o,t)=>{try{const n=g();let a="disconnected",r="not authorized";if(n)try{(await fetch("https://www.moltbook.com/api/v1/agents/status",{headers:{Authorization:`Bearer ${n}`}})).ok&&(a="connected",r="authorized")}catch{}const i={status:"healthy",moltbook:a,auth:r,mcp:"ready",timestamp:new Date().toISOString(),version:l()||"1.0.0"};t.json(i)}catch(n){t.status(500).json({status:"unhealthy",error:n.message,timestamp:new Date().toISOString()})}}),e.post("/mcp",v(s),async(o,t)=>{await S(o,t,s)}),e.get("/mcp",async(o,t)=>{t.status(405).set("Allow","POST").send("Method Not Allowed")}),e.delete("/mcp",async(o,t)=>{c.log("Received DELETE MCP request"),t.writeHead(405).end(JSON.stringify({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}))}),e.get("/",(o,t)=>{t.json({name:"Moltbook MCP Gateway Server",description:"MCP server for Moltbook: the social network for AI agents. Post, comment, upvote, DMs, communities.",version:l()||"1.0.0",endpoints:{health:{method:"GET",path:"/health",description:"Health check for all services"},mcp:{method:"POST",path:"/mcp",description:"JSON-RPC endpoint for MCP calls"},mcpMethods:{method:"GET",path:"/mcp/methods",description:"List all available MCP methods"}},architecture:"MCP integration",timestamp:new Date().toISOString()})}),e};export const startServer=(s={})=>{const{mcpPort:e=3003,keyPath:o,certPath:t}=s||{},n=P(s),a=r=>{r&&(c.error("Failed to start server:",r),process.exit(1));const i=o&&t?"https":"http";c.log(`0. Moltbook MCP Server listening on ${i}://localhost:${e}`)};if(o&&t)try{const r=m.readFileSync(o,"utf8"),i=m.readFileSync(t,"utf8");u.createServer({key:r,cert:i},n).listen(e,()=>a())}catch(r){c.error("HTTPS: failed to read key or cert:",r?.message??r),process.exit(1)}else n.listen(e,a)};process.on("SIGINT",async()=>{c.log("Shutting down server..."),process.exit(0)});
|
package/dist/utils/env.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{config as
|
|
1
|
+
"use strict";import{AsyncLocalStorage as o}from"node:async_hooks";import{config as i}from"dotenv";let n=!1;export function loadEnv(){n||(i(),n=!0)}const r=new o;export function runWithMoltbookApiKey(e,t){return r.run(e,t)}export function getAppApiKey(){return loadEnv(),process.env.MCP_API_KEY??""}export function getMoltbookApiKey(){loadEnv();const e=r.getStore();return e!==void 0?e:process.env.MOLTBOOK_API_KEY??""}export function getMcpLogger(){return loadEnv(),!!process.env.MCP_LOGGER}export function getAppVersion(){return loadEnv(),process.env.npm_package_version??"1.0.0"}export function getMCP_HTTPS_KEY_PATH(){return loadEnv(),process.env.MCP_HTTPS_KEY_PATH??""}export function getMCP_HTTPS_CERT_PATH(){return loadEnv(),process.env.MCP_HTTPS_CERT_PATH??""}export function getAppDomain(){return loadEnv(),process.env.APP_DOMAIN??""}
|
package/dist/utils/logger.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";import{
|
|
1
|
+
"use strict";import{getMcpLogger as a}from"./env.js";const l=(n,t)=>`\x1B]8;;${t}\x07${n}\x1B]8;;\x07`;function o(){const c=(new Error().stack?.split(`
|
|
2
2
|
`)||[])[3]||"",e=c.match(/\(([^)]+)\)/),s=e?e[1]:c.trim(),i=s.split("/").pop()||"unknown";return l(`${i}`,`${s}`)}const r=a();export const LOGGER={log:(...n)=>{r&&console.log(`[${o()}]`,...n)},info:(...n)=>{r&&console.info(`[${o()}]`,...n)},warn:(...n)=>{r&&console.warn(`[${o()}]`,...n)},error:(...n)=>{r&&console.error(`[${o()}]`,...n)}};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "moltbook-http-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Moltbook MCP server: post, comment, upvote, DMs, communities. API key auth.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -32,22 +32,23 @@
|
|
|
32
32
|
"build": "npm run build:types && npm run build:ts",
|
|
33
33
|
"build:ts": "esbuild src/**/*.ts src/*.ts --outdir=dist --platform=node --minify",
|
|
34
34
|
"build:types": "tsc --emitDeclarationOnly",
|
|
35
|
-
"start": "node dist/cli.js"
|
|
35
|
+
"start": "node dist/cli.js --stdio=false"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@modelcontextprotocol/sdk": "
|
|
38
|
+
"@modelcontextprotocol/sdk": "1.25.3",
|
|
39
39
|
"cors": "^2.8.5",
|
|
40
|
-
"dotenv": "
|
|
41
|
-
"express": "
|
|
42
|
-
"
|
|
40
|
+
"dotenv": "17.2.3",
|
|
41
|
+
"express": "5.1.0",
|
|
42
|
+
"jose": "^6.1.3",
|
|
43
|
+
"yargs": "18.0.0"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
|
-
"@types/cors": "
|
|
46
|
-
"@types/express": "
|
|
47
|
-
"@types/node": "
|
|
48
|
-
"@types/yargs": "
|
|
49
|
-
"esbuild": "
|
|
50
|
-
"typescript": "
|
|
46
|
+
"@types/cors": "2.8.19",
|
|
47
|
+
"@types/express": "5.0.3",
|
|
48
|
+
"@types/node": "24.3.0",
|
|
49
|
+
"@types/yargs": "17.0.33",
|
|
50
|
+
"esbuild": "0.25.9",
|
|
51
|
+
"typescript": "5.9.2"
|
|
51
52
|
},
|
|
52
53
|
"type": "module"
|
|
53
54
|
}
|
package/dist/config.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";import{getAppVersion as O,getMOLTBOOK_API_KEY as o}from"./utils/env.js";export const config={APP_VERSION:O(),MOLTBOOK_API_KEY:o()};
|