{"_id":"@planifyapps/mcp","_rev":"3-73a616b60ed6f979aa4d4bb920ee0313","name":"@planifyapps/mcp","dist-tags":{"latest":"0.4.0"},"versions":{"0.1.0":{"name":"@planifyapps/mcp","version":"0.1.0","keywords":["mcp","model-context-protocol","planify","social-media","scheduling","twitter","instagram","pinterest","bluesky","claude"],"license":"MIT","_id":"@planifyapps/mcp@0.1.0","maintainers":[{"name":"gsrathoreniks","email":"niks.gajsa@gmail.com"}],"homepage":"https://planifyapps.com/docs/api","bugs":{"url":"https://github.com/gsrathoreniks/planifyWeb/issues"},"bin":{"planify-mcp":"dist/index.js"},"dist":{"shasum":"e1eae835c973a9ee8f13b54b58d3d9e14c8718cf","tarball":"https://registry.npmjs.org/@planifyapps/mcp/-/mcp-0.1.0.tgz","fileCount":4,"integrity":"sha512-lAWt0AvlI0EXiezFDA3qdO4tzJAsJJNo1/mRwxKEYChuCR1e5hczB7mASVktI4HHuDCHmn2K3SI8EOAnPofBGA==","signatures":[{"sig":"MEUCIDYhMAVPlndjy/q1y0aVXkmySXYRnHbkF9gPWVoiTrd9AiEAiCGYdgngeUdo5dPuWyzcFCZ2JNaBSmh8Bk0Ci/C6LQ0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":19629},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"scripts":{"build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"gsrathoreniks","email":"niks.gajsa@gmail.com"},"repository":{"url":"git+https://github.com/gsrathoreniks/planifyWeb.git","type":"git","directory":"packages/mcp"},"_npmVersion":"11.15.0","description":"Model Context Protocol server for Planify — let an AI assistant schedule and publish social posts.","directories":{},"_nodeVersion":"23.6.0","dependencies":{"zod":"^3.25.0","@modelcontextprotocol/sdk":"^1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.1.0_1785484620981_0.5786925020016869","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@planifyapps/mcp","version":"0.2.0","keywords":["mcp","model-context-protocol","planify","social-media","scheduling","twitter","instagram","pinterest","bluesky","claude"],"license":"MIT","_id":"@planifyapps/mcp@0.2.0","maintainers":[{"name":"gsrathoreniks","email":"niks.gajsa@gmail.com"}],"homepage":"https://planifyapps.com/docs/api","bugs":{"url":"https://github.com/gsrathoreniks/planifyWeb/issues"},"//":"mcpName is how the MCP Registry proves this npm package belongs to the server it lists. It must stay identical to `name` in server.json.","bin":{"planify-mcp":"dist/index.js"},"dist":{"shasum":"485029ba45ba9050c5a11aec718fde478eabfaa3","tarball":"https://registry.npmjs.org/@planifyapps/mcp/-/mcp-0.2.0.tgz","fileCount":4,"integrity":"sha512-fjjHNTYRIUTGpLmrJpeCENdpCc5tRSGXW94st15sD2Wj6CmoDre6iSA307AG/ia1Z7ypLQ/ThH63mPfb0j2FSg==","signatures":[{"sig":"MEUCIQD+mUp0RMWwg6zaaDsl58RcWGLI6w5CGkmQ0leXqxKEGAIgbmnNvIDiwqgJIjhTWtb0K8TETwRNnpkNxrI2x+390No=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":22474},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"gitHead":"d15eb8b30a032e2ba42e8cc69d60a42a41d4af19","mcpName":"com.planifyapps/planify","scripts":{"build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"gsrathoreniks","email":"niks.gajsa@gmail.com"},"repository":{"url":"git+https://github.com/gsrathoreniks/planifyWeb.git","type":"git","directory":"packages/mcp"},"_npmVersion":"11.15.0","description":"Model Context Protocol server for Planify — let an AI assistant schedule and publish social posts.","directories":{},"_nodeVersion":"23.6.0","dependencies":{"zod":"^3.25.0","@modelcontextprotocol/sdk":"^1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp_0.2.0_1786043045278_0.16348965500611978","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@planifyapps/mcp","version":"0.4.0","description":"Model Context Protocol server for Planify — let an AI assistant schedule and publish social posts.","//":"mcpName is how the MCP Registry proves this npm package belongs to the server it lists. It must stay identical to `name` in server.json.","mcpName":"com.planifyapps/planify","keywords":["mcp","model-context-protocol","planify","social-media","scheduling","twitter","instagram","pinterest","bluesky","claude"],"homepage":"https://planifyapps.com/docs/api","repository":{"type":"git","url":"git+https://github.com/gsrathoreniks/planifyWeb.git","directory":"packages/mcp"},"license":"MIT","type":"module","bin":{"planify-mcp":"dist/index.js"},"main":"dist/index.js","engines":{"node":">=18"},"scripts":{"build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"dependencies":{"@modelcontextprotocol/sdk":"^1.30.0","zod":"^3.25.0"},"devDependencies":{"@types/node":"^22.0.0","typescript":"^5.6.0"},"_id":"@planifyapps/mcp@0.4.0","gitHead":"895b35bd6cf5c61a60c1f55b98b1d36138996ace","types":"./dist/index.d.ts","bugs":{"url":"https://github.com/gsrathoreniks/planifyWeb/issues"},"_nodeVersion":"22.21.1","_npmVersion":"10.9.4","dist":{"integrity":"sha512-0Iv6jNA/ftWSkOgyMcI8eX/7U/ohqiVz1H30vsikgeio7l+YrMjizGmWIoRSoNuqQ9wxPuoA8hz/NuJ7ZO4FXg==","shasum":"1026e5c2dda74c66964270c59afc2f14c22b16b5","tarball":"https://registry.npmjs.org/@planifyapps/mcp/-/mcp-0.4.0.tgz","fileCount":4,"unpackedSize":47880,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFuZKtuvia662oD7nJx+b9JuH/aA6FZygSB2/21lY1OZAiAtiIFNH3+xxqJDJOruCJiRh8uu6SQjeADcoW6Sad764g=="}]},"_npmUser":{"name":"gsrathoreniks","email":"niks.gajsa@gmail.com"},"directories":{},"maintainers":[{"name":"gsrathoreniks","email":"niks.gajsa@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp_0.4.0_1787640336225_0.48283375969013886"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-31T07:57:00.649Z","modified":"2026-08-25T06:45:36.491Z","0.1.0":"2026-07-31T07:57:01.116Z","0.2.0":"2026-08-06T19:04:05.426Z","0.4.0":"2026-08-25T06:45:36.352Z"},"bugs":{"url":"https://github.com/gsrathoreniks/planifyWeb/issues"},"license":"MIT","homepage":"https://planifyapps.com/docs/api","keywords":["mcp","model-context-protocol","planify","social-media","scheduling","twitter","instagram","pinterest","bluesky","claude"],"repository":{"type":"git","url":"git+https://github.com/gsrathoreniks/planifyWeb.git","directory":"packages/mcp"},"description":"Model Context Protocol server for Planify — let an AI assistant schedule and publish social posts.","maintainers":[{"name":"gsrathoreniks","email":"niks.gajsa@gmail.com"}],"readme":"# @planifyapps/mcp\n\nModel Context Protocol server for [Planify](https://planifyapps.com). Lets an AI assistant schedule and publish social posts — Twitter/X, Facebook, Instagram, Bluesky, Pinterest, Threads, LinkedIn, Mastodon, YouTube — on your behalf.\n\n## Setup\n\nYou need a Planify API key. Create one in the dashboard under **Settings → API**. It is shown once.\n\n### Claude Desktop\n\nAdd to `claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"planify\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@planifyapps/mcp\"],\n      \"env\": { \"PLANIFY_API_KEY\": \"plfy_live_...\" }\n    }\n  }\n}\n```\n\n### Claude Code\n\n```bash\nclaude mcp add planify --env PLANIFY_API_KEY=plfy_live_... -- npx -y @planifyapps/mcp\n```\n\n### Anything else that speaks MCP\n\nRun `npx -y @planifyapps/mcp` with `PLANIFY_API_KEY` in the environment. It communicates over stdio.\n\n## Tools\n\n**Discovery**\n\n| Tool | What it does |\n|---|---|\n| `planify_me` | Plan, scopes the key holds, quota remaining, and which endpoints those scopes can reach |\n| `planify_list_channels` | Connected accounts and their channel ids |\n| `planify_channel_settings` | **Read this before writing a post** — character limit, media rules, alt-text support, settings schema, available lookups |\n| `planify_channel_trigger` | Fetch values you can't guess (Pinterest boards, Twitter communities) |\n\n**Media**\n\n| Tool | What it does |\n|---|---|\n| `planify_upload_media` | Upload files from this machine — a path, or base64 bytes |\n| `planify_upload_media_from_url` | Hand over a public URL; Planify downloads it |\n| `planify_list_media` | What's already uploaded, including files added through the web app |\n\n**Posts**\n\n| Tool | What it does |\n|---|---|\n| `planify_validate_post` | Would this post be accepted? Creates nothing |\n| `planify_create_post` | Create a draft, schedule it, or publish now |\n| `planify_list_posts` | The queue: drafts, scheduled and published, with permalinks |\n| `planify_get_post` | One post in full, including whether it published and where |\n| `planify_update_post` | Edit a draft or scheduled post |\n| `planify_delete_post` | Remove a post |\n| `planify_publish_post` | Publish an existing post now |\n\n**Scheduling**\n\n| Tool | What it does |\n|---|---|\n| `planify_next_slot` | Next free slot from the user's own weekly schedule |\n| `planify_get_schedule` | The weekly slots and the timezone they're in |\n| `planify_set_schedule` | Set that schedule |\n\n### Alt text\n\nPass attachments as `media: [{ url, alt }]` rather than `media_urls` when the images\ncarry information. Order is the post's order — `media[0]` is the first image, and for\nan Instagram carousel that's the first slide.\n\nAlt text reaches Twitter/X, Bluesky, Mastodon, Instagram and Pinterest. Facebook,\nThreads, LinkedIn and YouTube have no alt-text field in their publishing APIs, so it's\nstored on the post and not sent. `limits.supports_alt_text` on `planify_channel_settings`\nsays which you're dealing with, per channel, rather than leaving you to guess.\n\n### Why it's shaped this way\n\nThe obvious design is one `post_to_social` tool. That fails, because every platform has different rules — 280 characters on Twitter, media required on Instagram, an unguessable board id on Pinterest — and a single tool either ignores them or restates them in a description that goes stale.\n\nSo these tools mirror the API's own discovery path. `planify_channel_settings` returns the real limits, prose rules, and a JSON Schema for that *specific* channel, generated server-side from the types the publishing code actually reads. The assistant is told the constraints before it writes, instead of learning them by being rejected.\n\n## Publishing safety\n\n`planify_create_post` **defaults to a draft.**\n\nPublishing immediately requires all three of:\n\n1. `type: \"now\"` — never the default\n2. a key holding the `posts:publish` scope — not granted by default\n3. your confirmation — the server's instructions tell the assistant to ask\n\nPublishing is irreversible and public. An assistant acting on a misread instruction should not be one call away from a bad post on a real audience. If you want an assistant that can never publish, create a key without `posts:publish` — everything else still works, and it can prepare drafts for you to approve.\n\n`planify_publish_post` is gated the same way, and it's the tool that makes that\narrangement useful: the agent prepares, a human approves, and the approval is a\nseparate call the agent's key cannot make. `planify_delete_post` is marked\ndestructive for the same reason — a scheduled post it removes is not going out, and\nnothing puts it back.\n\n## Configuration\n\n| Variable | Default | Purpose |\n|---|---|---|\n| `PLANIFY_API_KEY` | — | Required. From Settings → API. |\n| `PLANIFY_API_URL` | `https://planifyapps.com/api/v1` | Override for self-hosted or staging. |\n\nWithout a key the server still starts and every tool explains what's missing rather than failing opaquely.\n\n## Releasing\n\nTwo places have to move together. The registry lists metadata only — it fetches the\nnpm package and checks that its `package.json` carries an `mcpName` matching the\n`name` in `server.json`. Publish to the registry before npm and it fails validation.\n\nBump the version in three places (`package.json`, `VERSION` in `src/index.ts`, and\nboth `version` fields in `server.json`), then:\n\n```bash\nnpm publish --access public          # npm first, always\nmcp-publisher login http --domain planifyapps.com \\\n  --private-key \"$(openssl pkey -in .mcp-registry-key.pem -noout -text | grep -A3 'priv:' | tail -n +2 | tr -d ' :\\n')\"\nmcp-publisher publish\n```\n\nDomain authentication is what lets the server be named `com.planifyapps/planify`\nrather than sitting under a personal GitHub namespace. The proof is the public key\nat `/.well-known/mcp-registry-auth`, served from `public/` in the web app; the\nmatching private key is `.mcp-registry-key.pem`, gitignored and kept out of the\nrepo. Lose it and you regenerate the pair and redeploy the proof file.\n\n## Links\n\n- API reference — https://planifyapps.com/docs/api\n- OpenAPI spec — https://planifyapps.com/openapi.json\n\n## License\n\nMIT\n","readmeFilename":"README.md"}