[{"data":1,"prerenderedAt":1352},["ShallowReactive",2],{"navigation":3,"page:\u002Fai-tools":45},{"title":4,"links":5},"API reference",[6,9,12,15,18,21,24,27,30,33,36,39,42],{"title":7,"href":8},"Accounts","\u002Freference\u002Faccounts",{"title":10,"href":11},"Connect","\u002Freference\u002Fconnect",{"title":13,"href":14},"Calendars","\u002Freference\u002Fcalendars",{"title":16,"href":17},"Events","\u002Freference\u002Fevents",{"title":19,"href":20},"Availability","\u002Freference\u002Favailability",{"title":22,"href":23},"Meetings","\u002Freference\u002Fmeetings",{"title":25,"href":26},"Invitations","\u002Freference\u002Finvitations",{"title":28,"href":29},"Webhooks","\u002Freference\u002Fwebhooks",{"title":31,"href":32},"Metadata","\u002Freference\u002Fmetadata",{"title":34,"href":35},"Keys","\u002Freference\u002Fkeys",{"title":37,"href":38},"Sandbox","\u002Freference\u002Fsandbox",{"title":40,"href":41},"Usage","\u002Freference\u002Fusage",{"title":43,"href":44},"Logs","\u002Freference\u002Flogs",{"kind":46,"title":47,"description":48,"sections":49,"doc":68},"guide","AI tools","Add the Pyas MCP server to ChatGPT, Claude, Cursor, VS Code, Claude Code, or Codex by its address, sign in, and let the tool set up your app and work in its sandbox or on live calendars.",[50,53,56,59,62,65],{"id":51,"title":52},"add-the-server","Add the server",{"id":54,"title":55},"sign-in","Sign in",{"id":57,"title":58},"what-the-tool-can-do","What the tool can do",{"id":60,"title":61},"live-calendars","Live calendars",{"id":63,"title":64},"disconnect-a-tool","Disconnect a tool",{"id":66,"title":67},"the-setup-endpoints","The setup endpoints",{"id":69,"title":47,"body":70,"description":48,"extension":1343,"hero":1344,"meta":1345,"navigation":1346,"path":1347,"rawbody":1348,"sections":49,"seo":1349,"stem":76,"v1":1350,"__hash__":1351},"docs\u002Fai-tools.md",{"type":71,"value":72,"toc":1333},"minimark",[73,77,84,87,128,136,139,142,195,201,203,206,227,235,238,299,301,319,322,406,409,412,414,417,464,474,477,480,485,488,511,514,521,536,538,548,555,558,564,566,583,589,726,740,792,795,820,1329],[74,75,47],"h1",{"id":76},"ai-tools",[78,79,80],"lead",{},[81,82,83],"p",{},"The Pyas MCP server lets an AI tool set up your app and work in its sandbox or on live calendars. You add it to the tool by its address and sign in to Pyas from the tool. There is nothing to install and no key to copy.",[81,85,86],{},"The server has two addresses, as a key is a test key or a live key:",[88,89,90,103],"table",{},[91,92,93],"thead",{},[94,95,96,100],"tr",{},[97,98,99],"th",{},"Address",[97,101,102],{},"What the tool works on",[104,105,106,118],"tbody",{},[94,107,108,115],{},[109,110,111],"td",{},[112,113,114],"code",{},"https:\u002F\u002Fmcp.pyas.io\u002Fsandbox",[109,116,117],{},"The app's sandbox: test people, calendars and events",[94,119,120,125],{},[109,121,122],{},[112,123,124],{},"https:\u002F\u002Fmcp.pyas.io",[109,126,127],{},"The live calendars that people connected to the app",[81,129,130,131,135],{},"Start with the sandbox. To use both, add each as its own server (see ",[132,133,61],"a",{"href":134},"#live-calendars",").",[137,138,52],"h2",{"id":51},[81,140,141],{},"Each tool has its own guide, from adding the server to your first request:",[88,143,144,154],{},[91,145,146],{},[94,147,148,151],{},[97,149,150],{},"Where you work",[97,152,153],{},"Guide",[104,155,156,172],{},[94,157,158,161],{},[109,159,160],{},"A chat",[109,162,163,167,168],{},[132,164,166],{"href":165},"\u002Fchatgpt","ChatGPT",", ",[132,169,171],{"href":170},"\u002Fclaude","Claude",[94,173,174,177],{},[109,175,176],{},"Your code editor or terminal",[109,178,179,167,183,167,187,167,191],{},[132,180,182],{"href":181},"\u002Fcursor","Cursor",[132,184,186],{"href":185},"\u002Fvs-code","VS Code",[132,188,190],{"href":189},"\u002Fclaude-code","Claude Code",[132,192,194],{"href":193},"\u002Fcodex","Codex",[81,196,197,198,200],{},"Any other tool that adds an MCP server by its address and signs in with OAuth works the same way: enter ",[112,199,114],{}," and sign in when it asks.",[137,202,55],{"id":54},[81,204,205],{},"When the tool connects, your browser opens the Pyas dashboard:",[207,208,209,213,216,219],"ol",{},[210,211,212],"li",{},"Sign in, or create an account.",[210,214,215],{},"Choose the app the tool works with. A tool works with one app. To use it with another app, disconnect it and connect it again.",[210,217,218],{},"Check what the tool asks for. On the live address, choose whether it may only read live calendars or change them too.",[210,220,221,222,226],{},"Select ",[223,224,225],"strong",{},"Allow",".",[228,229],"screenshot",{"alt":230,"caption":231,"height":232,"src":233,"width":234},"The Pyas page that asks: Allow Claude Code to use Acme Calendar Sync? It shows the tool, the app with a Change link, the sandbox as the calendars, and what the tool will be able to do, with Allow and Deny buttons.","Signing in on the sandbox address. The page names the tool, the app and the calendars, and lists what the tool will be able to do.",921,"\u002Fimages\u002Fsign-in-sandbox.png",551,[81,236,237],{},"A tool can ask for these permissions:",[88,239,240,249],{},[91,241,242],{},[94,243,244,247],{},[97,245,246],{},"Permission",[97,248,58],{},[104,250,251,259,267,275,283,291],{},[94,252,253,256],{},[109,254,255],{},"Use this app's sandbox",[109,257,258],{},"Read and change the sandbox's test people, calendars and events",[94,260,261,264],{},[109,262,263],{},"Set up this app",[109,265,266],{},"Change the app's settings and allowed origins, and add sandbox webhooks",[94,268,269,272],{},[109,270,271],{},"Create test keys",[109,273,274],{},"Create test keys, which work only in the sandbox",[94,276,277,280],{},[109,278,279],{},"Read live calendars",[109,281,282],{},"Read the accounts and events that people connected to the app",[94,284,285,288],{},[109,286,287],{},"Change live calendars",[109,289,290],{},"Create, update and delete events and reply to invitations, each change confirmed by you",[94,292,293,296],{},[109,294,295],{},"Stay connected",[109,297,298],{},"Stay connected until you disconnect it",[137,300,58],{"id":57},[81,302,303,304,310,311,314,315,318],{},"On the sandbox address, the tool has the calendar tools of ",[132,305,307],{"href":306},"\u002Fsdks#mcp-server",[112,308,309],{},"@pyas\u002Fmcp",": list accounts and events, find a time when everyone is free, and create, update and delete events. It also has the tools for debugging your integration, such as ",[112,312,313],{},"explain_error"," and ",[112,316,317],{},"get_request",". Every request works only in the sandbox and doesn't affect real calendars.",[81,320,321],{},"With the setup permissions, the tool can set up the app:",[88,323,324,334],{},[91,325,326],{},[94,327,328,331],{},[97,329,330],{},"Tool",[97,332,333],{},"What it does",[104,335,336,346,356,366,376,386,396],{},[94,337,338,343],{},[109,339,340],{},[112,341,342],{},"setup_status",[109,344,345],{},"Shows what is done in the app's setup, what is left, and the next step",[94,347,348,353],{},[109,349,350],{},[112,351,352],{},"update_app",[109,354,355],{},"Adds the address your app runs at, such as a preview URL, to its allowed origins",[94,357,358,363],{},[109,359,360],{},[112,361,362],{},"get_test_key",[109,364,365],{},"Creates a test key, and tells you where to store it as a secret",[94,367,368,373],{},[109,369,370],{},[112,371,372],{},"create_webhook",[109,374,375],{},"Adds a sandbox webhook endpoint, returns its signing secret and sends a test delivery",[94,377,378,383],{},[109,379,380],{},[112,381,382],{},"create_app",[109,384,385],{},"Creates another app",[94,387,388,393],{},[109,389,390],{},[112,391,392],{},"go_live_checklist",[109,394,395],{},"Lists what is left before the app works with real calendars",[94,397,398,403],{},[109,399,400],{},[112,401,402],{},"get_recipe",[109,404,405],{},"Returns the code for a task on your platform, with where each file goes and the secret to set",[81,407,408],{},"Some things are always done by you, in the dashboard: choosing a plan, creating live keys and adding live webhooks. The tool gives you the link when it gets there.",[81,410,411],{},"Event titles, descriptions and attendees are written by other people. The server marks that text as data in every response, so the tool doesn't follow instructions that someone puts in an invitation.",[137,413,61],{"id":60},[81,415,416],{},"A tool can also work on the live calendars that people connected to your app, for example to find out why a booking didn't show up. Add a second server with the live address:",[207,418,419,433],{},[210,420,421,422,424,425,428,429,432],{},"Add ",[112,423,124],{}," the same way as the sandbox, under its own name, such as ",[112,426,427],{},"pyas-live"," or ",[112,430,431],{},"Pyas live",". Each tool's guide shows how.",[210,434,435,438,439,442,443,458],{},[132,436,55],{"href":437},"#sign-in",". The page asks ",[223,440,441],{},"What may it do with live calendars?",":",[444,445,446,452],"ul",{},[210,447,448,451],{},[223,449,450],{},"Read only",": the tool can list accounts and events, but can't change anything, including the app's setup.",[210,453,454,457],{},[223,455,456],{},"Read and change",": the tool can also create, update and delete events and reply to invitations.",[228,459],{"alt":460,"caption":461,"height":462,"src":463,"width":234},"The Pyas sign-in page on the live address, with live calendars as the calendars and the question What may it do with live calendars?, with Read and change chosen.","On the live address, you choose what the tool may do with live calendars. Allow stays off until you choose.",1127,"\u002Fimages\u002Fsign-in-live.png",[81,465,466,467,428,470,473],{},"Each address works on its own calendars: the sandbox address works only in the sandbox, and the live address only on live calendars. The description of every tool starts with ",[223,468,469],{},"Sandbox:",[223,471,472],{},"Live calendars:",", so the AI can tell the two servers apart, and it asks you when it isn't clear which one you mean.",[81,475,476],{},"While you work in the sandbox, turn the live server off, so the tool can't mix up the two. Each tool's guide shows how.",[81,478,479],{},"Requests on live calendars count toward your plan's monthly requests, as a live key's do. Changing live calendars needs the owner, admin or developer role in the organization.",[481,482,484],"h3",{"id":483},"confirm-each-change","Confirm each change",[81,486,487],{},"Before a tool changes a live calendar, you confirm the change in Pyas:",[207,489,490,493,508],{},[210,491,492],{},"The tool asks to make the change and gives you a link. Some tools open the page for you.",[210,494,495,496,428,499,226,502],{},"The page shows the app, the calendar and what would change. Select ",[223,497,498],{},"Confirm",[223,500,501],{},"Decline",[228,503],{"alt":504,"caption":505,"height":506,"src":507,"width":234},"The Pyas page Claude Code asks to create an event, showing the app, the calendar, the title and the start and end times, with Confirm and Decline buttons.","A change waiting for you. It shows the calendar it acts on and exactly what would change.",894,"\u002Fimages\u002Fconfirm-change.png",[210,509,510],{},"Go back to the tool and let it carry on. It makes the change when it tries again.",[81,512,513],{},"Only the person who connected the tool can confirm its changes. A link works for 15 minutes.",[81,515,516,517,520],{},"Changes to the app are confirmed the same way. On the live address, you confirm every change to the app. On either address, you confirm each new allowed origin, because live calendars use the same list. ",[223,518,519],{},"Don't ask again"," doesn't cover changes to the app.",[81,522,523,524,527,528,531,532,535],{},"To stop being asked for a while, select ",[223,525,526],{},"Don't ask again for this tool for the next hour"," before you confirm. ",[223,529,530],{},"Connected tools"," on your profile shows when the hour ends, and ",[223,533,534],{},"Ask each time"," ends it early.",[137,537,64],{"id":63},[81,539,540,541,543,544,547],{},"Your connected tools are listed on your profile in the dashboard, under ",[223,542,530],{},", with when each was last used. Select ",[223,545,546],{},"Disconnect"," to stop a tool immediately.",[228,549],{"alt":550,"caption":551,"height":552,"src":553,"width":554},"The Connected tools card on the profile page, listing Claude Code with its app, its access (App setup, Live calendars, Live changes), when it connected and was used, and a Disconnect button.","Connected tools on your profile. Access shows what each tool may do.",259,"\u002Fimages\u002Fconnected-tools.png",768,[81,556,557],{},"Test keys and sandbox webhooks that the tool made keep working, so anything it built keeps running. You can revoke them on the app's pages. To use it again, connect it again from the tool.",[81,559,560,561,563],{},"The ",[223,562,43],{}," page in the dashboard shows which tool made each request, such as \"By Claude (AI tool)\".",[137,565,67],{"id":66},[81,567,568,569,572,573,575,576,579,580,582],{},"The MCP server and the CLI's ",[112,570,571],{},"pyas login"," set up apps through these endpoints. You can call them yourself with a ",[112,574,571],{}," token, or with the SDK's ",[112,577,578],{},"pyas.manage",". A connected tool's own token doesn't work here: it works only through the MCP server. Once an app has connected calendars, change its allowed origins in the dashboard, not with a ",[112,581,571],{}," token.",[81,584,585,586,442],{},"Every path starts with ",[112,587,588],{},"\u002Fv2\u002Fmanage\u002Fapps",[88,590,591,603],{},[91,592,593],{},[94,594,595,598,601],{},[97,596,597],{},"Method",[97,599,600],{},"Path",[97,602,333],{},[104,604,605,617,629,643,657,671,684,698,712],{},[94,606,607,612,614],{},[109,608,609],{},[112,610,611],{},"GET",[109,613],{},[109,615,616],{},"Lists the apps you can set up",[94,618,619,624,626],{},[109,620,621],{},[112,622,623],{},"POST",[109,625],{},[109,627,628],{},"Creates an app",[94,630,631,635,640],{},[109,632,633],{},[112,634,611],{},[109,636,637],{},[112,638,639],{},"\u002F{appId}",[109,641,642],{},"Returns the app, its setup checklist and the next step",[94,644,645,650,654],{},[109,646,647],{},[112,648,649],{},"PATCH",[109,651,652],{},[112,653,639],{},[109,655,656],{},"Updates the app's name, description, website and allowed origins",[94,658,659,663,668],{},[109,660,661],{},[112,662,611],{},[109,664,665],{},[112,666,667],{},"\u002F{appId}\u002Fwebhooks",[109,669,670],{},"Lists the app's sandbox webhook endpoints",[94,672,673,677,681],{},[109,674,675],{},[112,676,623],{},[109,678,679],{},[112,680,667],{},[109,682,683],{},"Adds a sandbox webhook endpoint and returns its signing secret",[94,685,686,690,695],{},[109,687,688],{},[112,689,623],{},[109,691,692],{},[112,693,694],{},"\u002F{appId}\u002Fwebhooks\u002F{webhookId}\u002Ftest",[109,696,697],{},"Sends a test delivery",[94,699,700,704,709],{},[109,701,702],{},[112,703,611],{},[109,705,706],{},[112,707,708],{},"\u002F{appId}\u002Fkeys",[109,710,711],{},"Lists the app's keys, without their values",[94,713,714,718,723],{},[109,715,716],{},[112,717,623],{},[109,719,720],{},[112,721,722],{},"\u002F{appId}\u002Fkeys\u002Ftest",[109,724,725],{},"Creates a test key and returns its value",[81,727,728,729,732,733,735,736,739],{},"To create or change anything, send a person's access token: ",[112,730,731],{},"Authorization: Bearer \u003Ctoken>",". ",[112,734,571],{}," gets one for you. An API key in ",[112,737,738],{},"x-api-key"," can only read its own app's setup.",[741,742,747],"pre",{"className":743,"code":744,"language":745,"meta":746,"style":746},"language-bash shiki shiki-themes css-variables","npx @pyas\u002Fcli login\nnpx @pyas\u002Fcli apps show \u003CappId>\n","bash","",[112,748,749,765],{"__ignoreMap":746},[750,751,754,758,762],"span",{"class":752,"line":753},"line",1,[750,755,757],{"class":756},"s1IGz","npx",[750,759,761],{"class":760},"sTB4W"," @pyas\u002Fcli",[750,763,764],{"class":760}," login\n",[750,766,768,770,772,775,778,782,785,789],{"class":752,"line":767},2,[750,769,757],{"class":756},[750,771,761],{"class":760},[750,773,774],{"class":760}," apps",[750,776,777],{"class":760}," show",[750,779,781],{"class":780},"sag7P"," \u003C",[750,783,784],{"class":760},"appI",[750,786,788],{"class":787},"sqSWz","d",[750,790,791],{"class":780},">\n",[81,793,794],{},"For example, the setup of an app:",[741,796,800],{"className":797,"code":798,"language":799,"meta":746,"style":746},"language-http shiki shiki-themes css-variables","GET \u002Fv2\u002Fmanage\u002Fapps\u002F5c1e9a47-2d3b-4f86-a0e9-7b4c2d18f365\nAuthorization: Bearer \u003Ctoken>\n","http",[112,801,802,809],{"__ignoreMap":746},[750,803,804,806],{"class":752,"line":753},[750,805,611],{"class":780},[750,807,808],{"class":787}," \u002Fv2\u002Fmanage\u002Fapps\u002F5c1e9a47-2d3b-4f86-a0e9-7b4c2d18f365\n",[750,810,811,815,817],{"class":752,"line":767},[750,812,814],{"class":813},"sk1Au","Authorization",[750,816,442],{"class":780},[750,818,819],{"class":760}," Bearer \u003Ctoken>\n",[741,821,825],{"className":822,"code":823,"language":824,"meta":746,"style":746},"language-json shiki shiki-themes css-variables","{\n  \"success\": true,\n  \"data\": {\n    \"appId\": \"5c1e9a47-2d3b-4f86-a0e9-7b4c2d18f365\",\n    \"orgId\": \"a3d97f2c-6e41-4b8a-9c05-1f7e2b4d8a60\",\n    \"name\": \"Booking page\",\n    \"description\": \"\",\n    \"websiteUrl\": \"\",\n    \"allowedOrigins\": [\"https:\u002F\u002Fbooking.example.com\"],\n    \"signIn\": { \"google\": \"pyas\", \"microsoft\": \"pyas\", \"zoom\": \"pyas\" },\n    \"setup\": {\n      \"steps\": [\n        { \"id\": \"allowed_origins\", \"done\": true, \"text\": \"Add the address your app runs at (its preview or production URL) to the allowed origins, so PyasConnect opens there.\" },\n        { \"id\": \"first_call\", \"done\": false, \"text\": \"Make a first request against the sandbox with a test key.\" },\n        { \"id\": \"test_key\", \"done\": false, \"text\": \"Create a test key and store it as a secret in your project.\" },\n        { \"id\": \"webhook\", \"done\": false, \"text\": \"Add a webhook endpoint, so your app hears when calendars change.\" },\n        { \"id\": \"own_calendar\", \"done\": false, \"text\": \"Connect your own calendar in Live from the dashboard, and call the API on it.\" },\n        { \"id\": \"signin\", \"done\": true, \"text\": \"Google, Microsoft and Zoom use Pyas Auth.\" },\n        { \"id\": \"live\", \"done\": false, \"text\": \"Create a live key in the dashboard and store it as a secret where your server code runs, then connect a real calendar account.\" }\n      ],\n      \"nextStep\": \"Make a first request against the sandbox with a test key.\"\n    },\n    \"dashboardUrl\": \"https:\u002F\u002Fapp.pyas.io\u002Forg\u002Fapps\u002F5c1e9a47-2d3b-4f86-a0e9-7b4c2d18f365\"\n  },\n  \"provider\": null,\n  \"traceId\": \"trc_7f3a9c2e1b4d6a8f0c5e2b1d\",\n  \"meta\": {}\n}\n","json",[112,826,827,832,847,858,871,884,897,910,922,941,984,994,1005,1042,1076,1109,1142,1175,1208,1240,1248,1259,1267,1278,1286,1299,1312,1323],{"__ignoreMap":746},[750,828,829],{"class":752,"line":753},[750,830,831],{"class":787},"{\n",[750,833,834,837,840,844],{"class":752,"line":767},[750,835,836],{"class":780},"  \"success\"",[750,838,442],{"class":839},"sEEt9",[750,841,843],{"class":842},"sXULy"," true",[750,845,846],{"class":839},",\n",[750,848,850,853,855],{"class":752,"line":849},3,[750,851,852],{"class":780},"  \"data\"",[750,854,442],{"class":839},[750,856,857],{"class":787}," {\n",[750,859,861,864,866,869],{"class":752,"line":860},4,[750,862,863],{"class":780},"    \"appId\"",[750,865,442],{"class":839},[750,867,868],{"class":813}," \"5c1e9a47-2d3b-4f86-a0e9-7b4c2d18f365\"",[750,870,846],{"class":839},[750,872,874,877,879,882],{"class":752,"line":873},5,[750,875,876],{"class":780},"    \"orgId\"",[750,878,442],{"class":839},[750,880,881],{"class":813}," \"a3d97f2c-6e41-4b8a-9c05-1f7e2b4d8a60\"",[750,883,846],{"class":839},[750,885,887,890,892,895],{"class":752,"line":886},6,[750,888,889],{"class":780},"    \"name\"",[750,891,442],{"class":839},[750,893,894],{"class":813}," \"Booking page\"",[750,896,846],{"class":839},[750,898,900,903,905,908],{"class":752,"line":899},7,[750,901,902],{"class":780},"    \"description\"",[750,904,442],{"class":839},[750,906,907],{"class":813}," \"\"",[750,909,846],{"class":839},[750,911,913,916,918,920],{"class":752,"line":912},8,[750,914,915],{"class":780},"    \"websiteUrl\"",[750,917,442],{"class":839},[750,919,907],{"class":813},[750,921,846],{"class":839},[750,923,925,928,930,933,936,939],{"class":752,"line":924},9,[750,926,927],{"class":780},"    \"allowedOrigins\"",[750,929,442],{"class":839},[750,931,932],{"class":787}," [",[750,934,935],{"class":813},"\"https:\u002F\u002Fbooking.example.com\"",[750,937,938],{"class":787},"]",[750,940,846],{"class":839},[750,942,944,947,949,952,955,957,960,963,966,968,970,972,975,977,979,982],{"class":752,"line":943},10,[750,945,946],{"class":780},"    \"signIn\"",[750,948,442],{"class":839},[750,950,951],{"class":787}," { ",[750,953,954],{"class":780},"\"google\"",[750,956,442],{"class":839},[750,958,959],{"class":813}," \"pyas\"",[750,961,962],{"class":839},",",[750,964,965],{"class":780}," \"microsoft\"",[750,967,442],{"class":839},[750,969,959],{"class":813},[750,971,962],{"class":839},[750,973,974],{"class":780}," \"zoom\"",[750,976,442],{"class":839},[750,978,959],{"class":813},[750,980,981],{"class":787}," }",[750,983,846],{"class":839},[750,985,987,990,992],{"class":752,"line":986},11,[750,988,989],{"class":780},"    \"setup\"",[750,991,442],{"class":839},[750,993,857],{"class":787},[750,995,997,1000,1002],{"class":752,"line":996},12,[750,998,999],{"class":780},"      \"steps\"",[750,1001,442],{"class":839},[750,1003,1004],{"class":787}," [\n",[750,1006,1008,1011,1014,1016,1019,1021,1024,1026,1028,1030,1033,1035,1038,1040],{"class":752,"line":1007},13,[750,1009,1010],{"class":787},"        { ",[750,1012,1013],{"class":780},"\"id\"",[750,1015,442],{"class":839},[750,1017,1018],{"class":813}," \"allowed_origins\"",[750,1020,962],{"class":839},[750,1022,1023],{"class":780}," \"done\"",[750,1025,442],{"class":839},[750,1027,843],{"class":842},[750,1029,962],{"class":839},[750,1031,1032],{"class":780}," \"text\"",[750,1034,442],{"class":839},[750,1036,1037],{"class":813}," \"Add the address your app runs at (its preview or production URL) to the allowed origins, so PyasConnect opens there.\"",[750,1039,981],{"class":787},[750,1041,846],{"class":839},[750,1043,1045,1047,1049,1051,1054,1056,1058,1060,1063,1065,1067,1069,1072,1074],{"class":752,"line":1044},14,[750,1046,1010],{"class":787},[750,1048,1013],{"class":780},[750,1050,442],{"class":839},[750,1052,1053],{"class":813}," \"first_call\"",[750,1055,962],{"class":839},[750,1057,1023],{"class":780},[750,1059,442],{"class":839},[750,1061,1062],{"class":842}," false",[750,1064,962],{"class":839},[750,1066,1032],{"class":780},[750,1068,442],{"class":839},[750,1070,1071],{"class":813}," \"Make a first request against the sandbox with a test key.\"",[750,1073,981],{"class":787},[750,1075,846],{"class":839},[750,1077,1079,1081,1083,1085,1088,1090,1092,1094,1096,1098,1100,1102,1105,1107],{"class":752,"line":1078},15,[750,1080,1010],{"class":787},[750,1082,1013],{"class":780},[750,1084,442],{"class":839},[750,1086,1087],{"class":813}," \"test_key\"",[750,1089,962],{"class":839},[750,1091,1023],{"class":780},[750,1093,442],{"class":839},[750,1095,1062],{"class":842},[750,1097,962],{"class":839},[750,1099,1032],{"class":780},[750,1101,442],{"class":839},[750,1103,1104],{"class":813}," \"Create a test key and store it as a secret in your project.\"",[750,1106,981],{"class":787},[750,1108,846],{"class":839},[750,1110,1112,1114,1116,1118,1121,1123,1125,1127,1129,1131,1133,1135,1138,1140],{"class":752,"line":1111},16,[750,1113,1010],{"class":787},[750,1115,1013],{"class":780},[750,1117,442],{"class":839},[750,1119,1120],{"class":813}," \"webhook\"",[750,1122,962],{"class":839},[750,1124,1023],{"class":780},[750,1126,442],{"class":839},[750,1128,1062],{"class":842},[750,1130,962],{"class":839},[750,1132,1032],{"class":780},[750,1134,442],{"class":839},[750,1136,1137],{"class":813}," \"Add a webhook endpoint, so your app hears when calendars change.\"",[750,1139,981],{"class":787},[750,1141,846],{"class":839},[750,1143,1145,1147,1149,1151,1154,1156,1158,1160,1162,1164,1166,1168,1171,1173],{"class":752,"line":1144},17,[750,1146,1010],{"class":787},[750,1148,1013],{"class":780},[750,1150,442],{"class":839},[750,1152,1153],{"class":813}," \"own_calendar\"",[750,1155,962],{"class":839},[750,1157,1023],{"class":780},[750,1159,442],{"class":839},[750,1161,1062],{"class":842},[750,1163,962],{"class":839},[750,1165,1032],{"class":780},[750,1167,442],{"class":839},[750,1169,1170],{"class":813}," \"Connect your own calendar in Live from the dashboard, and call the API on it.\"",[750,1172,981],{"class":787},[750,1174,846],{"class":839},[750,1176,1178,1180,1182,1184,1187,1189,1191,1193,1195,1197,1199,1201,1204,1206],{"class":752,"line":1177},18,[750,1179,1010],{"class":787},[750,1181,1013],{"class":780},[750,1183,442],{"class":839},[750,1185,1186],{"class":813}," \"signin\"",[750,1188,962],{"class":839},[750,1190,1023],{"class":780},[750,1192,442],{"class":839},[750,1194,843],{"class":842},[750,1196,962],{"class":839},[750,1198,1032],{"class":780},[750,1200,442],{"class":839},[750,1202,1203],{"class":813}," \"Google, Microsoft and Zoom use Pyas Auth.\"",[750,1205,981],{"class":787},[750,1207,846],{"class":839},[750,1209,1211,1213,1215,1217,1220,1222,1224,1226,1228,1230,1232,1234,1237],{"class":752,"line":1210},19,[750,1212,1010],{"class":787},[750,1214,1013],{"class":780},[750,1216,442],{"class":839},[750,1218,1219],{"class":813}," \"live\"",[750,1221,962],{"class":839},[750,1223,1023],{"class":780},[750,1225,442],{"class":839},[750,1227,1062],{"class":842},[750,1229,962],{"class":839},[750,1231,1032],{"class":780},[750,1233,442],{"class":839},[750,1235,1236],{"class":813}," \"Create a live key in the dashboard and store it as a secret where your server code runs, then connect a real calendar account.\"",[750,1238,1239],{"class":787}," }\n",[750,1241,1243,1246],{"class":752,"line":1242},20,[750,1244,1245],{"class":787},"      ]",[750,1247,846],{"class":839},[750,1249,1251,1254,1256],{"class":752,"line":1250},21,[750,1252,1253],{"class":780},"      \"nextStep\"",[750,1255,442],{"class":839},[750,1257,1258],{"class":813}," \"Make a first request against the sandbox with a test key.\"\n",[750,1260,1262,1265],{"class":752,"line":1261},22,[750,1263,1264],{"class":787},"    }",[750,1266,846],{"class":839},[750,1268,1270,1273,1275],{"class":752,"line":1269},23,[750,1271,1272],{"class":780},"    \"dashboardUrl\"",[750,1274,442],{"class":839},[750,1276,1277],{"class":813}," \"https:\u002F\u002Fapp.pyas.io\u002Forg\u002Fapps\u002F5c1e9a47-2d3b-4f86-a0e9-7b4c2d18f365\"\n",[750,1279,1281,1284],{"class":752,"line":1280},24,[750,1282,1283],{"class":787},"  }",[750,1285,846],{"class":839},[750,1287,1289,1292,1294,1297],{"class":752,"line":1288},25,[750,1290,1291],{"class":780},"  \"provider\"",[750,1293,442],{"class":839},[750,1295,1296],{"class":842}," null",[750,1298,846],{"class":839},[750,1300,1302,1305,1307,1310],{"class":752,"line":1301},26,[750,1303,1304],{"class":780},"  \"traceId\"",[750,1306,442],{"class":839},[750,1308,1309],{"class":813}," \"trc_7f3a9c2e1b4d6a8f0c5e2b1d\"",[750,1311,846],{"class":839},[750,1313,1315,1318,1320],{"class":752,"line":1314},27,[750,1316,1317],{"class":780},"  \"meta\"",[750,1319,442],{"class":839},[750,1321,1322],{"class":787}," {}\n",[750,1324,1326],{"class":752,"line":1325},28,[750,1327,1328],{"class":787},"}\n",[1330,1331,1332],"style",{},"html pre.shiki code .s1IGz, html code.shiki .s1IGz{--shiki-default:var(--shiki-token-function)}html pre.shiki code .sTB4W, html code.shiki .sTB4W{--shiki-default:var(--shiki-token-string)}html pre.shiki code .sag7P, html code.shiki .sag7P{--shiki-default:var(--shiki-token-keyword)}html pre.shiki code .sqSWz, html code.shiki .sqSWz{--shiki-default:var(--shiki-foreground)}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sk1Au, html code.shiki .sk1Au{--shiki-default:var(--shiki-token-string-expression)}html pre.shiki code .sEEt9, html code.shiki .sEEt9{--shiki-default:var(--shiki-token-punctuation)}html pre.shiki code .sXULy, html code.shiki .sXULy{--shiki-default:var(--shiki-token-constant)}",{"title":746,"searchDepth":849,"depth":849,"links":1334},[1335,1336,1337,1338,1341,1342],{"id":51,"depth":767,"text":52},{"id":54,"depth":767,"text":55},{"id":57,"depth":767,"text":58},{"id":60,"depth":767,"text":61,"children":1339},[1340],{"id":483,"depth":849,"text":484},{"id":63,"depth":767,"text":64},{"id":66,"depth":767,"text":67},"md",false,{},true,"\u002Fai-tools","---\ntitle: AI tools\ndescription: Add the Pyas MCP server to ChatGPT, Claude, Cursor, VS Code, Claude Code, or Codex by its address, sign in, and let the tool set up your app and work in its sandbox or on live calendars.\nsections:\n  - { id: add-the-server, title: Add the server }\n  - { id: sign-in, title: Sign in }\n  - { id: what-the-tool-can-do, title: What the tool can do }\n  - { id: live-calendars, title: Live calendars }\n  - { id: disconnect-a-tool, title: Disconnect a tool }\n  - { id: the-setup-endpoints, title: The setup endpoints }\n---\n\n# AI tools\n\n::lead\nThe Pyas MCP server lets an AI tool set up your app and work in its sandbox or on live calendars. You add it to the tool by its address and sign in to Pyas from the tool. There is nothing to install and no key to copy.\n::\n\nThe server has two addresses, as a key is a test key or a live key:\n\n| Address | What the tool works on |\n|---|---|\n| `https:\u002F\u002Fmcp.pyas.io\u002Fsandbox` | The app's sandbox: test people, calendars and events |\n| `https:\u002F\u002Fmcp.pyas.io` | The live calendars that people connected to the app |\n\nStart with the sandbox. To use both, add each as its own server (see [Live calendars](#live-calendars)).\n\n## Add the server\n\nEach tool has its own guide, from adding the server to your first request:\n\n| Where you work | Guide |\n|---|---|\n| A chat | [ChatGPT](\u002Fchatgpt), [Claude](\u002Fclaude) |\n| Your code editor or terminal | [Cursor](\u002Fcursor), [VS Code](\u002Fvs-code), [Claude Code](\u002Fclaude-code), [Codex](\u002Fcodex) |\n\nAny other tool that adds an MCP server by its address and signs in with OAuth works the same way: enter `https:\u002F\u002Fmcp.pyas.io\u002Fsandbox` and sign in when it asks.\n\n## Sign in\n\nWhen the tool connects, your browser opens the Pyas dashboard:\n\n1. Sign in, or create an account.\n2. Choose the app the tool works with. A tool works with one app. To use it with another app, disconnect it and connect it again.\n3. Check what the tool asks for. On the live address, choose whether it may only read live calendars or change them too.\n4. Select **Allow**.\n\n::screenshot{src=\"\u002Fimages\u002Fsign-in-sandbox.png\" alt=\"The Pyas page that asks: Allow Claude Code to use Acme Calendar Sync? It shows the tool, the app with a Change link, the sandbox as the calendars, and what the tool will be able to do, with Allow and Deny buttons.\" width=\"551\" height=\"921\" caption=\"Signing in on the sandbox address. The page names the tool, the app and the calendars, and lists what the tool will be able to do.\"}\n::\n\nA tool can ask for these permissions:\n\n| Permission | What the tool can do |\n|---|---|\n| Use this app's sandbox | Read and change the sandbox's test people, calendars and events |\n| Set up this app | Change the app's settings and allowed origins, and add sandbox webhooks |\n| Create test keys | Create test keys, which work only in the sandbox |\n| Read live calendars | Read the accounts and events that people connected to the app |\n| Change live calendars | Create, update and delete events and reply to invitations, each change confirmed by you |\n| Stay connected | Stay connected until you disconnect it |\n\n## What the tool can do\n\nOn the sandbox address, the tool has the calendar tools of [`@pyas\u002Fmcp`](\u002Fsdks#mcp-server): list accounts and events, find a time when everyone is free, and create, update and delete events. It also has the tools for debugging your integration, such as `explain_error` and `get_request`. Every request works only in the sandbox and doesn't affect real calendars.\n\nWith the setup permissions, the tool can set up the app:\n\n| Tool | What it does |\n|---|---|\n| `setup_status` | Shows what is done in the app's setup, what is left, and the next step |\n| `update_app` | Adds the address your app runs at, such as a preview URL, to its allowed origins |\n| `get_test_key` | Creates a test key, and tells you where to store it as a secret |\n| `create_webhook` | Adds a sandbox webhook endpoint, returns its signing secret and sends a test delivery |\n| `create_app` | Creates another app |\n| `go_live_checklist` | Lists what is left before the app works with real calendars |\n| `get_recipe` | Returns the code for a task on your platform, with where each file goes and the secret to set |\n\nSome things are always done by you, in the dashboard: choosing a plan, creating live keys and adding live webhooks. The tool gives you the link when it gets there.\n\nEvent titles, descriptions and attendees are written by other people. The server marks that text as data in every response, so the tool doesn't follow instructions that someone puts in an invitation.\n\n## Live calendars\n\nA tool can also work on the live calendars that people connected to your app, for example to find out why a booking didn't show up. Add a second server with the live address:\n\n1. Add `https:\u002F\u002Fmcp.pyas.io` the same way as the sandbox, under its own name, such as `pyas-live` or `Pyas live`. Each tool's guide shows how.\n2. [Sign in](#sign-in). The page asks **What may it do with live calendars?**:\n   - **Read only**: the tool can list accounts and events, but can't change anything, including the app's setup.\n   - **Read and change**: the tool can also create, update and delete events and reply to invitations.\n\n   ::screenshot{src=\"\u002Fimages\u002Fsign-in-live.png\" alt=\"The Pyas sign-in page on the live address, with live calendars as the calendars and the question What may it do with live calendars?, with Read and change chosen.\" width=\"551\" height=\"1127\" caption=\"On the live address, you choose what the tool may do with live calendars. Allow stays off until you choose.\"}\n   ::\n\nEach address works on its own calendars: the sandbox address works only in the sandbox, and the live address only on live calendars. The description of every tool starts with **Sandbox:** or **Live calendars:**, so the AI can tell the two servers apart, and it asks you when it isn't clear which one you mean.\n\nWhile you work in the sandbox, turn the live server off, so the tool can't mix up the two. Each tool's guide shows how.\n\nRequests on live calendars count toward your plan's monthly requests, as a live key's do. Changing live calendars needs the owner, admin or developer role in the organization.\n\n### Confirm each change\n\nBefore a tool changes a live calendar, you confirm the change in Pyas:\n\n1. The tool asks to make the change and gives you a link. Some tools open the page for you.\n2. The page shows the app, the calendar and what would change. Select **Confirm** or **Decline**.\n\n   ::screenshot{src=\"\u002Fimages\u002Fconfirm-change.png\" alt=\"The Pyas page Claude Code asks to create an event, showing the app, the calendar, the title and the start and end times, with Confirm and Decline buttons.\" width=\"551\" height=\"894\" caption=\"A change waiting for you. It shows the calendar it acts on and exactly what would change.\"}\n   ::\n\n3. Go back to the tool and let it carry on. It makes the change when it tries again.\n\nOnly the person who connected the tool can confirm its changes. A link works for 15 minutes.\n\nChanges to the app are confirmed the same way. On the live address, you confirm every change to the app. On either address, you confirm each new allowed origin, because live calendars use the same list. **Don't ask again** doesn't cover changes to the app.\n\nTo stop being asked for a while, select **Don't ask again for this tool for the next hour** before you confirm. **Connected tools** on your profile shows when the hour ends, and **Ask each time** ends it early.\n\n## Disconnect a tool\n\nYour connected tools are listed on your profile in the dashboard, under **Connected tools**, with when each was last used. Select **Disconnect** to stop a tool immediately.\n\n::screenshot{src=\"\u002Fimages\u002Fconnected-tools.png\" alt=\"The Connected tools card on the profile page, listing Claude Code with its app, its access (App setup, Live calendars, Live changes), when it connected and was used, and a Disconnect button.\" width=\"768\" height=\"259\" caption=\"Connected tools on your profile. Access shows what each tool may do.\"}\n::\n Test keys and sandbox webhooks that the tool made keep working, so anything it built keeps running. You can revoke them on the app's pages. To use it again, connect it again from the tool.\n\nThe **Logs** page in the dashboard shows which tool made each request, such as \"By Claude (AI tool)\".\n\n## The setup endpoints\n\nThe MCP server and the CLI's `pyas login` set up apps through these endpoints. You can call them yourself with a `pyas login` token, or with the SDK's `pyas.manage`. A connected tool's own token doesn't work here: it works only through the MCP server. Once an app has connected calendars, change its allowed origins in the dashboard, not with a `pyas login` token.\n\nEvery path starts with `\u002Fv2\u002Fmanage\u002Fapps`:\n\n| Method | Path | What it does |\n|---|---|---|\n| `GET` | | Lists the apps you can set up |\n| `POST` | | Creates an app |\n| `GET` | `\u002F{appId}` | Returns the app, its setup checklist and the next step |\n| `PATCH` | `\u002F{appId}` | Updates the app's name, description, website and allowed origins |\n| `GET` | `\u002F{appId}\u002Fwebhooks` | Lists the app's sandbox webhook endpoints |\n| `POST` | `\u002F{appId}\u002Fwebhooks` | Adds a sandbox webhook endpoint and returns its signing secret |\n| `POST` | `\u002F{appId}\u002Fwebhooks\u002F{webhookId}\u002Ftest` | Sends a test delivery |\n| `GET` | `\u002F{appId}\u002Fkeys` | Lists the app's keys, without their values |\n| `POST` | `\u002F{appId}\u002Fkeys\u002Ftest` | Creates a test key and returns its value |\n\nTo create or change anything, send a person's access token: `Authorization: Bearer \u003Ctoken>`. `pyas login` gets one for you. An API key in `x-api-key` can only read its own app's setup.\n\n```bash\nnpx @pyas\u002Fcli login\nnpx @pyas\u002Fcli apps show \u003CappId>\n```\n\nFor example, the setup of an app:\n\n```http\nGET \u002Fv2\u002Fmanage\u002Fapps\u002F5c1e9a47-2d3b-4f86-a0e9-7b4c2d18f365\nAuthorization: Bearer \u003Ctoken>\n```\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"appId\": \"5c1e9a47-2d3b-4f86-a0e9-7b4c2d18f365\",\n    \"orgId\": \"a3d97f2c-6e41-4b8a-9c05-1f7e2b4d8a60\",\n    \"name\": \"Booking page\",\n    \"description\": \"\",\n    \"websiteUrl\": \"\",\n    \"allowedOrigins\": [\"https:\u002F\u002Fbooking.example.com\"],\n    \"signIn\": { \"google\": \"pyas\", \"microsoft\": \"pyas\", \"zoom\": \"pyas\" },\n    \"setup\": {\n      \"steps\": [\n        { \"id\": \"allowed_origins\", \"done\": true, \"text\": \"Add the address your app runs at (its preview or production URL) to the allowed origins, so PyasConnect opens there.\" },\n        { \"id\": \"first_call\", \"done\": false, \"text\": \"Make a first request against the sandbox with a test key.\" },\n        { \"id\": \"test_key\", \"done\": false, \"text\": \"Create a test key and store it as a secret in your project.\" },\n        { \"id\": \"webhook\", \"done\": false, \"text\": \"Add a webhook endpoint, so your app hears when calendars change.\" },\n        { \"id\": \"own_calendar\", \"done\": false, \"text\": \"Connect your own calendar in Live from the dashboard, and call the API on it.\" },\n        { \"id\": \"signin\", \"done\": true, \"text\": \"Google, Microsoft and Zoom use Pyas Auth.\" },\n        { \"id\": \"live\", \"done\": false, \"text\": \"Create a live key in the dashboard and store it as a secret where your server code runs, then connect a real calendar account.\" }\n      ],\n      \"nextStep\": \"Make a first request against the sandbox with a test key.\"\n    },\n    \"dashboardUrl\": \"https:\u002F\u002Fapp.pyas.io\u002Forg\u002Fapps\u002F5c1e9a47-2d3b-4f86-a0e9-7b4c2d18f365\"\n  },\n  \"provider\": null,\n  \"traceId\": \"trc_7f3a9c2e1b4d6a8f0c5e2b1d\",\n  \"meta\": {}\n}\n```\n",{"title":47,"description":48},null,"nwmr2QMDv7TJ6sxD3En8vV9gt0yyM8kcwOI4-I-8d5k",1794697270758]