
Team feedback and insights
Browse, summarize, and act on WorkStory feedback, performance reviews, and review cycles directly from your AI. Make WorkStory a native part of your AI workflow— so you can understand how your team is doing without leaving the conversation.
Example path
https://app.workstory.team/mcp{"title":"WorkStory MCP Instructions","purpose":["These instructions describe what the WorkStory MCP server exposes: read access to the company, its questions, accounts, feedback, goals, performance reviews, and review cycles, plus the ability to request and give feedback and to create goals, for the authenticated caller's company. It also exposes search over WorkStory's public help articles."],"notes":["Entity relationships are not derivable from tool or field names alone; describes them."],"toolInstructions":{"general":["Every tool except is scoped to the authenticated viewer's company, applying WorkStory's existing access rules. All are read-only except , , and , which write data.","options.include requests related objects, where a tool supports them.","options.page and options.sort control pagination and ordering, where a tool supports them.","On , and , filters.status and options.page both apply to the rows the tool returns. The one exception is the categories section options.include.categories adds to , which is neither status-filtered nor paged."],"tools":{"":{"purpose":"Returns WorkStory's public help articles matching a product-help question, with their titles, links and full text.","usage":["Use this for questions about the WorkStory product itself - what a feature does, what a term means, how to do something in the app - as opposed to questions about the caller's own company, people, feedback or reviews.","It reads the query string on its own, with no conversation around it, so resolve what 'it' or 'that' refers to before calling.","It returns nothing when the FAQ does not cover the question. Say so rather than answering from outside knowledge."]},"":{"purpose":"Returns a description of the entities these tools expose — company, companyQuestions, account, feedback, performanceReview, reviewCycle — their fields, enum values, relations, and which filter or include traverses each relation.","usage":["Useful when a question depends on how entities relate, or on which filter reaches a relation. Several relations are derived rather than stored and have no matching filter.","Pass entities to narrow the response. It returns metadata only, no row data."]},"":{"purpose":"Returns the authenticated caller's own identity: accountId, email, companyid.","usage":["This is the only way to resolve who 'me'/'my' refers to (e.g. my feedback, my reviews) when the caller's account ID is not already known.","The accountId it returns identifies the caller specifically. Every other tool accepts any account ID in the company, not just this one."]},"":{"purpose":"Returns your authenticated caller's company's setup, including its name, status, feedback settings, groups, schedule, and connected apps.","usage":["This is what resolves the group ids on an account to group names.","It does not return the company's roles, categories or questions; , and serve those.","It takes no arguments and returns configuration, not people or feedback."]},"":{"purpose":"Returns the company's roles, which is how the roleId on a feedback row or an account becomes a name.","usage":["Pass no filters to list every role; filters.roleIds narrows to specific ones, up to 5 ids per call. For more roles than that, list them all and match the ids client-side. Role ids for a person come from (account.roles).","options.include.categories adds the categories those roles are asked about, as a union across the roles on the current page, deduplicated, so a category shared by two roles appears once. Each one carries questionIds — pass those to for the wording.","This is also how you find the categoryId needs: for the reviewee's roles, then this tool with those roleIds and options.include.categories, keeping only the categories whose status is Active.","Archived roles, categories and questions all come back by default, since feedback still refers to them. Read status on each row before using an id to request or give feedback — rejects the whole call if any role/category/question triple is inactive."]},"":{"purpose":"Returns the company's categories, which is how the categoryId on a feedback row becomes a name.","usage":["Pass no filters to list every category, or filters.categoryIds for specific ones, up to 100 ids per call. Category ids come from feedback rows, from grouped by categoryId, and from roles[].categoryIds on .","There is no filters.roleIds here. For the categories a role is asked about, call with options.include.categories.","Each row carries questionIds. There is no include for them — pass the ids to , which is the only tool that returns question wording.","Several categories can share a name across roles, so match on id when the label repeats."]},"":{"purpose":"Returns the company's questions by ID, which is how the questionId on a feedback row becomes wording, along with the answers each question offers.","usage":["filters.questionIds is required — up to 100 ids. There is no way to list every question, because the set runs to hundreds of rows, and there is no filters.categoryIds.","The ids come from a feedback row, or from categories[].questionIds — on , or on the categories section adds. No tool expands questions in place, so reaching wording from a role takes two calls and from a category one."]},"":{"purpose":"Returns one WorkStory account by account ID.","usage":["Use this when you already know the account ID and need details."]},"":{"purpose":"Returns multiple WorkStory accounts using account filters and pagination.","usage":["Use this to find people using filters."]},"":{"purpose":"Returns multiple feedback rows from the WorkStory feedback data.","usage":["Use this for feedback history, reviewer/reviewee activity, scheduled feedback information or other feedback-related queries.","Rows returned by this tool are called feedback in WorkStory; the underlying legacy table is named Reviews."]},"":{"purpose":"Returns aggregated feedback stats: counts (and optionally bundled feedback rows) grouped by a column such as reviewee, reviewer, or categoryId.","usage":["Returns counts computed server-side (e.g. how many feedback rows per reviewee or category), so the totals are complete regardless of page size.","options.by names the column to group by (e.g. 'reviewee', 'categoryId'). options.bundleFeedbacks:true also returns the raw feedback rows per group."]},"":{"purpose":"Asks people (reviewers) to give feedback about other people (reviewees). This writes data and delivers messages to the reviewers.","usage":["reviewerIds and revieweeIds are WorkStory account IDs - reviewers are the people who will answer, reviewees are the people the feedback is about.","feedbackType 'General Feedback' with requestText asks a single open question, worded by the caller.","feedbackType 'Category Feedback' with roleId and questions asks the company's own configured questions. The role's categories and questions come from the reviewee's account and the company questions, and a questionId is only valid alongside the categoryId it belongs to.","Omitting scheduling delivers immediately. One request is created per reviewer/reviewee pair, so the number of messages sent is the product of the two lists."]},"":{"purpose":"Returns multiple WorkStory goals using goal filters and pagination.","usage":["Use this for goal ownership, progress, deadlines, subgoal trees, or the goals a review cycle covered.","Goals form trees: filters.isTopLevel returns only goals with no parent, filters.parentId returns one goal's direct subgoals, and filters.treeId returns every goal in a tree. Rows come back flat - there is no include that nests subgoals.","A goal's live status is the status of its newest updates[] entry; the status column is only the fallback for a goal with no updates. Read lastUpdate.status, which the endpoint computes for each row.","filters.assignees takes account IDs, and null for unassigned goals. filters.teamId (an account ID) and filters.groupId resolve into assignee IDs too, so passing several of them widens the result rather than narrowing it.","filters.reviewCycleIds needs options.useDuplicate: true alongside it - only the review-cycle snapshot of goals carries a reviewCycleId.","Update history is withheld on goals whose assignee the caller cannot manage: updates[] comes back empty unless the caller is an Admin.","filters.baseId and options.lookup are shared with WorkStory's internal goal-tree lookup and do nothing here. Use filters.parentId, filters.treeId or filters.isTopLevel instead."]},"":{"purpose":"Creates one WorkStory goal, authored by the authenticated caller. This writes data.","usage":["The caller has to be allowed to manage the assignee's goals - an Admin, someone who manages them, or someone above them in the org tree. Anything else is refused.","Fields left out are stored with their defaults, so read the created goal back to the user and name what defaulted.","A new goal starts with no progress updates, and there is no tool to add one or to change a goal afterwards. Say so rather than creating a second goal to stand in for an edit."]},"":{"purpose":"Writes one general feedback comment about one person, authored by the authenticated caller. This writes data and notifies the reviewee.","usage":["The reviewer is always the authenticated caller and is not a parameter, so feedback cannot be given as someone else. Covering several people takes one call each.","Do not give the same feedback twice. If the user is rewording, correcting or re-scoping feedback they already gave, or changing who can read it, call on that row instead - find it with filtered to the caller as the reviewer. Give feedback again only when the user asks for a new, separate piece of feedback.","Set feedbackType to \"General Feedback\", the only value this tool accepts. Answering one of the company's own questions is not supported over MCP, so questionId and answer are refused before the call is made.","A score can never be sent, by this tool or any other caller: it is the score the company gave that answer in the question, so the server takes it from the answer. Feedback written here carries no score at all, because it answers no question.","Set categoryId to the category the comment is about. Resolve it from for the reviewee's roles, then with those roleIds and options.include.categories. Ask the user which category they mean whenever more than one plausibly fits the comment - do not guess, and do not take the first in the list. Prefer a category whose status is Active: this tool accepts an archived one without an error, so nothing downstream will catch that choice. Names repeat across roles, so match on id.","Ask the user which visibility they want before calling this tool, and wait for their answer - do not submit on an assumption. Offer only the ones this company allows: read settings.reviewVisibilityOptions from and offer the values it has switched on, naming each by its label and saying in a few words who can read the feedback under it.","Where a label contains \"@revieweeName\", say the reviewee's name instead of the placeholder.","If the user has no preference, leave commentVisible out - the company default applies. Either way, tell them afterwards which visibility the created row came back with, and that can change it if they want something else.","When offering 'use the company default' as a choice, read settings.reviewVisibilityDefaultOption from and name that value by its label - the user should never have to ask what the default resolves to.","A self-review allows fewer values than that map, and the difference is published nowhere: WITH_REVIEWEE, WITH_REVIEWEE_MANAGER and ANONYMOUS are never allowed when the reviewee is the caller, so do not offer them for one.","A commentVisible the company has switched off is rejected, and the error lists the ones it allows.","The created row is returned, including its id, a status of Reviewed, the category it was filed under and the visibility that was applied. Name the category back to the user, so they can say if the comment belongs somewhere else. Its comments come back as HTML, so strip the tags before quoting it back. Feedback created this way is a new row; it does not answer a feedback request already pending for the caller.","Rows created here record a source of \"mcp\", which distinguishes them from feedback entered on the website. The server sets it, so anything passed for source is ignored."]},"":{"purpose":"Rewrites the comment on one existing feedback, or changes who can read it. This writes data.","usage":["Prefer this over whenever the feedback already exists. A reworded comment, a correction, or a different visibility is an update to that row, not a second row about the same thing - giving it again leaves the original standing and the reviewee sees both.","Editing feedback follows the same rules as the website: the reviewer can edit their own, and an Admin or the reviewee's manager can edit feedback somebody else wrote. An edit the caller is not allowed to make comes back as a refusal.","Find the feedbackId with .","comments replaces the whole comment rather than adding to it, so send the full rewritten text. The stored comment comes back as HTML, so strip the tags before quoting it and send plain text back.","Change one of them or both - either on its own is a valid call. A field left out is left as it is; only a call carrying neither is refused.","Read settings.reviewVisibilityOptions from before changing commentVisible - a value the company has switched off is rejected, and the error lists the ones it allows.","Nothing else about the feedback can be changed here: not the reviewee, not the question it answers, not its status, not whether it is enabled.","Every edit made through MCP is recorded with a reason of \"MCP Operation\", which the app shows in the feedback's edit history. The server sets it.","The updated row is returned. Tell the user what the comment now says and which visibility it carries."]},"":{"purpose":"Returns one WorkStory performance review by performance review ID.","usage":["Use this when you already know the performance review ID and need details.","A performance review belongs to a review cycle and a reviewee, and holds scores, comments, and submissions."]},"":{"purpose":"Returns multiple WorkStory performance reviews using filters and pagination.","usage":["Use this to find performance reviews by review cycle, reviewee, manager, status, or other filters."]},"":{"purpose":"Returns one WorkStory review cycle by review cycle ID.","usage":["Use this when you already know the review cycle ID and need details.","A review cycle is the configuration/container that performance reviews are generated from."]},"":{"purpose":"Returns multiple WorkStory review cycles using filters and pagination.","usage":["Use this to find review cycles by status, date range, or other filters."]}}}}
None in the store listings or on the server