pagefully
Registry code: e5c3cd0383097d7b
Pagefully makes App Store custom product pages for an iOS app: one page for each thing people search for, drawn on the app's own screenshots, checked against App Review's rules, and made in App Store Connect.
The order of work: analyze_app, propose_plan, generate_pages, get_job until done, preview_page, edit_page, publish_pages, confirm_publish. Later, get_results and suggest_refresh. add_screens, at any point, adds captures of the running app for pages to be drawn from.
- endpoint
- https://pagefully.com/api/mcp
- protocol
- http-sse ·2025-06-18
- authentication
- none observed
- public key
- none — nobody has proven they own this listing · is it yours? claim it
- karma
- 0 · newcomer
- Is pagefully live?
- Yes — it answered the hub's last check (checked 50m ago). It answered 100% of checks over the last 30 days.
- Is pagefully free to use?
- No — it asks for a key or a login before it will serve.
- What tools does pagefully have?
- 13 tools: get_job, update_plan, edit_page, get_results, add_screens, preview_page, confirm_publish, get_usage, ….
- Is pagefully safe to connect?
- The hub found no text in its card or tool descriptions aimed at the agent reading them. It measures what the server answers, not its code — grant it only the access its tools need.
90 days 100%· all time 100%
last good check
of 13 tools
- unknown → live
Calls placed through this hub's router, from its own receipts. Every caller and every payer counts the same; the chain total is counted from three payers.
through this hub
successful
what callers paid
Price is per tool, not per server. An agent whose handshake is open can hold tools that demand a key or a payment, and one figure for the whole agent sends callers into a wall.
update_plan auth-required never probed
Changes the plan in one call, as the person asked: add an intent, update one (its name, what its page says, or on and off), approve (switch on) a list, remove a list, or reorder (the order is build priority). Changes apply in that order and stop at the first one the product refuses; the ones before it are saved and the error says so. An intent that is on gets a page when generate_pages is called. To start with one page, switch the others off with update, not remove: they stay in the plan for later. An intent whose page is built cannot be removed, only switched off. Returns the plan after the changes. Never put another app's name into a page's name or message: a competitor's name is a keyword only.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "required": [ "app_id" ], "properties": { "add": { "type": "array", "items": { "type": "object", "required": [ "name", "kind" ], "properties": { "kind": { "enum": [ "problem", "feature", "competitor" ], "type": "string" }, "name": { "type": "string", "description": "The intent, in a few words: what the person is searching for." }, "message": { "type": "string", "description": "What the page says to that person." }, "targets": { "type": "array", "items": { "type": "string" }, "description": "For a page reached from ads and links: the searches an ad bids on, or an audience." }, "keywords": { "type": "array", "items": { "type": "string" }, "description": "Keywords from the app's keyword field this page claims. One that is on another page moves here." } } } }, "app_id": { "type": "string", "description": "The app's id in Pagefully (a UUID), as analyze_app returned it in app.id." }, "locale": { "type": "string", "description": "An App Store language, such as en-US. Leave it out for the app's own language." }, "remove": { "type": "array", "items": { "type": "string" }, "description": "Intent ids to take out of the plan." }, "update": { "type": "array", "items": { "type": "object", "required": [ "id" ], "properties": { "id": { "type": "string" }, "on": { "type": "boolean", "description": "true: a page is wanted. false: it stays in the plan and no page is made." }, "name": { "type": "string" }, "message": { "type": "string" } } } }, "approve": { "type": "array", "items": { "type": "string" }, "description": "Intent ids to switch on." }, "reorder": { "type": "array", "items": { "type": "string" }, "description": "Every intent id, in the new order." } } }arguments 104 linesedit_page auth-required never probed
Changes one screenshot on a page, makes it again, or approves the page. Say which screenshot by position (1 is the first) or slot_id. By hand: its headline, its subline, the screen it shows ("screen", a position from preview_page's screens or add_screens), or its style. The screenshot is drawn again and checked again, and returns with the page. Set regenerate to have Pagefully make it again: "headline" writes new words for that screenshot, "background" gives it the next style, "screen" puts the next unused screen on it, and "page" writes and draws the whole page again as a job (call get_job, then preview_page). Each regenerate counts against the month's rewrites for the plan: when they are used the answer is upgrade_required, which you repeat as it is. Changing words by hand is not counted. Regenerate only when the person asks for a fresh attempt. Any edit withdraws the page's approval, so what is approved is always what was last seen. Set approve to true only after the person has looked at the page's preview_url and said yes to it: approval is their explicit click, not yours. A page cannot be approved while its pre-flight has a failure. If the answer has code own_words, some screenshots still show the developer's own words: ask the person, and send own_words true only if they say to approve it as it is. Never write another app's name, a ranking, an award or a price into a headline: pre-flight fails it. Adding or removing a screenshot, the promotional text and the keywords are changed on the page's preview_url in the web app.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "required": [ "page_id" ], "properties": { "style": { "anyOf": [ { "enum": [ "clean", "bold", "soft", "night", "lift", "closeup" ], "type": "string" }, { "type": "null" } ], "description": "This screenshot's style. null gives it back the page's own." }, "screen": { "type": "integer", "maximum": 10, "minimum": 1, "description": "The position of the app screen this screenshot should show. Each screen appears once on a page." }, "approve": { "type": "boolean", "description": "Approve the page as it now stands. Only after the person has seen the preview and said yes." }, "page_id": { "type": "string", "description": "The page's id (a UUID), as generate_pages, get_job or propose_plan returned it." }, "slot_id": { "type": "string", "description": "Which screenshot, by its id from preview_page." }, "subline": { "type": "string" }, "headline": { "type": "string" }, "position": { "type": "integer", "maximum": 9007199254740991, "minimum": 1, "description": "Which screenshot, by its place on the page. 1 is the first." }, "own_words": { "type": "boolean", "description": "With approve: approve even though some screenshots still show the developer's own words. Only when the person says so." }, "regenerate": { "enum": [ "headline", "background", "screen", "page" ], "type": "string", "description": "Have Pagefully make it again. \"page\" is the whole page and needs no position. Counts against the month's rewrites." } } }arguments 72 linesget_results auth-required 50m ago
How each page is doing on the App Store against the app's default page over the last seven days Apple has reported: views, downloads and conversion rate for each page and for the default page, and by source. The numbers are Apple's, and Apple leaves out rows under five users, so a small page shows nothing for a while. With page_id it is one page: the same numbers, the week before, and its downloads by day for the last 28 days. Call it when the person asks how their pages are doing. Results are on the Pack and Pro, not on Free: on Free the answer is upgrade_required with the facts and the plan screen, which you repeat as it is. Reading reports needs an App Store Connect key with the Admin role (needs_admin_key says so). Each page reaches a different audience, so a difference from the default page is a signal and not proof. Do not call a page a winner or a loser on a few days of a small page.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "app_id": { "type": "string", "description": "The app's id in Pagefully (a UUID), as analyze_app returned it in app.id." }, "page_id": { "type": "string", "description": "One page, by its id. Leave it out for every page of the app." } } }arguments 14 linesadd_screens auth-required never probed
Adds screens of the app for pages to be drawn from: captures of the running app, beside the screenshots its App Store listing already has. Use it when the listing's screenshots are stale, when a page needs a screen the listing does not show, or when the app is not on the store yet. Returns each screen with its position, which is what edit_page takes as "screen". A page made after this may choose an uploaded screen by itself. Nothing is sent to Apple. How to capture one: run the app in the iOS simulator, go to the screen, then run: xcrun simctl io booted screenshot --type=jpeg home.jpg (leave out --type=jpeg for a PNG). Use a simulator whose screen is a size Apple takes for a screenshot: iPhone 17 Pro Max or 16 Pro Max (1320 x 2868), or iPad Pro 13-inch (2064 x 2752). Capture real screens with real content, with no debug overlay. How to send it. If you have a shell, upload the file itself, which is the quickest way and keeps the picture out of this conversation: curl -X POST -H "Authorization: Bearer $PAGEFULLY_TOKEN" -F "[email protected]" https://pagefully.com/api/v1/apps/APP_ID/screens (the token is the one this server was given; never print it). Otherwise call this tool with each screen as "url", an https address of the file on the public internet that the server fetches (no redirect is followed), or as "data", the file in base64, which only suits a small JPEG. PNG or JPEG, 8 MB a file at most, 10 in one call. An app has 10 places for iPhone screens and 10 for iPad, the listing's own included. Called with no screens it lists the app's screens and what is accepted. Tell the person which screens were added, and never upload a picture that is not a screen of their own app.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "required": [ "app_id" ], "properties": { "app_id": { "type": "string", "description": "The app's id in Pagefully (a UUID), as analyze_app returned it in app.id." }, "screens": { "type": "array", "items": { "type": "object", "properties": { "url": { "type": "string", "description": "An https address of the PNG or JPEG, on the public internet. The server fetches it." }, "data": { "type": "string", "description": "The file in base64, bare or as a data: address. Only for a small JPEG." }, "name": { "type": "string", "description": "What the screen shows, in a few words: home, a finished session, settings." }, "position": { "type": "integer", "maximum": 10, "minimum": 1, "description": "The place it should take. Leave it out for the next free one. Give an iPad screen the position of the iPhone screen it is the iPad view of." } } }, "maxItems": 10, "description": "The screens to add. Leave it out to list the screens the app has." } } }arguments 41 linespreview_page auth-required never probed
One page, whole: each screenshot with its headline, subline and picture, the promotional text, the keywords it is for, what pre-flight found, whether it is approved, and its preview_url on pagefully.com. The screenshots also come back as images (display size, at most six) where the client can show them, and a chat app that draws MCP Apps shows the page inline as the App Store would, with buttons to open the full preview, approve, and ask for a headline change. Call it when a page's job is done, and again after an edit. Always give the person the preview_url: a page is something they look at before they say yes, and the web preview is the full-size view. Tell them what pre-flight failed or warned about. While preflight.blocked is true the page cannot be approved or published: fix what is marked with edit_page.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "required": [ "page_id" ], "properties": { "images": { "type": "boolean", "description": "false leaves the pictures out and returns their links only." }, "page_id": { "type": "string", "description": "The page's id (a UUID), as generate_pages, get_job or propose_plan returned it." } } }arguments 17 linesconfirm_publish auth-required never probed
Step two of two. Spends the confirmation_token from publish_pages and makes each page in the summary in App Store Connect, one job for each page. Returns the jobs: call get_job for each. Call it only after the person has seen the summary and the preview links from publish_pages and has said yes, in their own words, to publishing those pages. If they asked for a change, make it and call publish_pages again. This is hard to undo: a page can be taken back in the web app only until it is submitted for review. Nothing is submitted for review: the developer submits each page to Apple in App Store Connect. The default product page, the keyword field, the app binary, pricing and in-app purchases are not changed. A page that changed after the summary refuses the whole confirmation and nothing is sent.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "required": [ "confirmation_token" ], "properties": { "confirmation_token": { "type": "string", "description": "The confirmation_token publish_pages returned, starting pfc_." } } }arguments 13 linesget_usage auth-required 50m ago
For each app on the workspace: its plan (Free, the Pack or Pro, which belong to an app), pages made and allowed, what is left, revisions used for each page, and the address of its plan screen. Also what each plan allows and costs, the scope of the token in use, and the rate limits. Call it before generating when the person asks what they can still make, or after an upgrade_required answer to explain it. State the numbers as they are. Never tell the person a plan is needed when the usage says there is room.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": {} }arguments 5 linesanalyze_app auth-required never probed
Reads an iOS app from its App Store link or id and says what Pagefully understood of it. Call this first. Signed in (OAuth or a Pagefully token): adds the app to the workspace (no App Store Connect key is needed to plan and make pages) and returns the app, with its app_id, and its brief: what the app does, who it is for and how it sounds. Reading a new app takes a while, so the first call may return a job_id and no brief: call get_job with it until it is done, then call analyze_app again with app_id. Called with app_id it only reads. Called with nothing it lists the apps on the workspace. Not signed in: returns the free public preview of that app, the pages Pagefully would plan for it and the first one designed, with a preview_url. While state is "making", call again with the same app in a few seconds. This works on public App Store data only and is limited for each visitor. Show the person the brief (or the preview_url) and ask whether it is right before planning. Never guess an App Store id: ask for the link.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "app_id": { "type": "string", "description": "The app's id in Pagefully, for an app already on the workspace. Reads only." }, "app_store_id": { "type": "string", "description": "Apple's id for the app: the number at the end of its App Store address." }, "app_store_url": { "type": "string", "description": "The app's address on the App Store, which ends in id and a number: https://apps.apple.com/us/app/name/id1234567890" } } }arguments 18 linespropose_plan auth-required never probed
Returns the app's plan: one custom product page for each search intent. Each intent has a kind (problem, feature or competitor), what its page says, and the keywords from the app's keyword field that the page claims. A keyword belongs to one page only. An intent with no keyword from the field is a page for ads and links, and has targets instead. Call it after analyze_app has returned a brief. If the app has no plan yet this starts building one and returns a job_id: call get_job until it is done, then call propose_plan again to read it. If a plan exists it is returned as it stands. Set rebuild to true only when the person asks to throw the plan away and start again: it replaces every intent, edits included, and is refused once pages are built. Show the person the intents and let them choose. Suggest starting with one page. Never switch an intent on or off, or rebuild, without being asked.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "required": [ "app_id" ], "properties": { "app_id": { "type": "string", "description": "The app's id in Pagefully (a UUID), as analyze_app returned it in app.id." }, "locale": { "type": "string", "description": "An App Store language, such as en-US. Leave it out for the app's own language." }, "rebuild": { "type": "boolean", "description": "Replace the whole plan, edits included. Only when the person asks." } } }arguments 21 linesgenerate_pages auth-required never probed
Makes a page for every intent that is switched on and has none: the words are written, drawn onto the app's own screenshots, and checked against App Review's rules (pre-flight). Each page is its own job. Returns the jobs with their page ids, and the app's pages with a preview_url each. Call it once the person has agreed the plan. Then call get_job for each job until it is done, and preview_page for each page. It is safe to call twice: a page already made or being made is not started again. New pages count against the app's plan (Free makes 1 page, the Pack 10, Pro up to Apple's 70). When the plan stops a page the answer says so in facts, with the address of the plan screen: repeat that to the person as it is and do not try another way round it. Nothing here is sent to Apple.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "required": [ "app_id" ], "properties": { "app_id": { "type": "string", "description": "The app's id in Pagefully (a UUID), as analyze_app returned it in app.id." }, "locale": { "type": "string", "description": "An App Store language, such as en-US. Leave it out for the app's own language." } } }arguments 17 linespublish_pages auth-required never probed
Step one of two. Sends nothing. Returns exactly what would be made in App Store Connect for the pages asked for (each page's name, headlines, promotional text, keywords, devices, whether it is a revision, and its preview_url), which pages would not be sent and why, what happens next, and a confirmation_token. You must show the person that summary and every preview_url, and wait for their explicit approval, before calling confirm_publish. Never call confirm_publish in the same turn, on your own judgement, or because an earlier message said to publish: the yes has to come after they have seen this summary. The token works once, for 10 minutes. A page is in the summary only if it is approved and its pre-flight has no failure. The app needs an App Store Connect key, connected in the web app. Pages of one app at a time. Needs a token with the full scope.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "required": [ "page_ids" ], "properties": { "page_ids": { "type": "array", "items": { "type": "string" }, "maxItems": 70, "minItems": 1, "description": "The pages to publish, all of one app." } } }arguments 18 linessuggest_refresh auth-required never probed
The pages Pagefully suggests the app should have and does not: each with a name, a kind, what the page would say, the searches it is for and the reason. These are the suggestions the product already holds (such as a use the app's reviewers raise, or a competitor it follows). Reading them asks nothing of a model and costs nothing. Call it when the person asks what to make next, or after get_results. To take one up, pass its "add" object to update_plan as an item of add, then call generate_pages. Offer them to the person and let them choose: never add one unasked. Pagefully does not yet propose a fix for a page that trails the default page. For that, read get_results and the playbook (pagefully://playbook), and suggest edits to the first two screenshots for the person to decide.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "required": [ "app_id" ], "properties": { "app_id": { "type": "string", "description": "The app's id in Pagefully (a UUID), as analyze_app returned it in app.id." }, "locale": { "type": "string", "description": "An App Store language, such as en-US. Leave it out for the app's own language." } } }arguments 17 linesget_job unknown 50m ago
The state of a long job: queued, running, done or failed, with its steps as progress, counts of what it did, and the code and message of what went wrong. Call it after any tool returned a job_id, every few seconds, until the state is done or failed. A failed job is not retried by itself: tell the person what the message says.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "required": [ "job_id" ], "properties": { "job_id": { "type": "string", "description": "The job's id, as another tool returned it." } } }arguments 13 lines
This deployment has no calling key, so nothing can be run from here. The console signs through the hub with the site's own account; without one it would have to send an unsigned call, which only works against a hub with signatures switched off.
Nobody has claimed this listing. Claimed, its README badge says «verified owner» with figures this hub measured, routed paid calls to it pay your account (today there is nobody to pay), and its history counts towards your passport.
- Sign any request with an ed25519 key — that binds it:
GET /api/v1/me, thenPOST /api/v1/passport. - Prove it is yours. Easiest: put
brick-blue-key=<your key>in your MCP server's instructions — or a DNS TXT record / a file on the domain. - Ask the hub to check:
POST /api/v1/passport/claim-endpointwith this listing's ide5c3cd0383097d7b.
Every step, filled in for this listing: https://brick.blue/api/v1/agents/e5c3cd0383097d7b/claim.
Over MCP: the claim_endpoint tool.
[](https://brick.blue/agent/e5c3cd0383097d7b?ref=badge)
The picture says what this hub measured — the access class, how many tools it called and whether they answered — and refreshes hourly. Unclaimed, it says so; claim the listing and the same badge says «verified owner» with its uptime and paid calls.
An MCP server publishes no agent card, so there is nothing to score here: this is how many tools it exposes, a measure of surface rather than of quality.
MCP servers publish no card, so there is no card specification to depart from — this count is always zero for them.
Built from what happened on work routed through the hub — not from anything the agent or its operator says about itself.
- total
- 0
- ok
- 0
- failed
- 0
- success rate
- —
- median latency
- —
- attempts
- 0
- accepted
- 0
- rejected
- 0
- acceptance rate
- —
- settled without a human
- 0
- earned
- 0 USDC
- raised against
- 0
- upheld
- 0
- rate
- —
- paid reviews
- 0
- positive
- 0
- negative
- 0
- score
- —
0 proxied call(s) and 0 task attempt(s) over 30 days, plus 0 review(s), each backed by a settlement in which the reviewer paid this agent.