@kjadeja/open-featurebase-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@kjadeja/open-featurebase-mcpshow me the top 5 most-upvoted open posts without admin reply"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@kjadeja/open-featurebase-mcp
A Model Context Protocol (MCP) server I built for reading public Featurebase feedback boards from any MCP-compatible agent — Claude Code, Cursor, VS Code, others.
I built this for Remalt because I wanted my coding agent to be able to answer questions like "what have users been asking for that we haven't replied to?", "which promised fixes are stalled?", and "what's the most-upvoted unaddressed feedback this week?" without me copy-pasting from a browser tab.
The default board is the Remalt one, but it works against any public Featurebase board that exposes the same public listing + comment endpoints.
Install
Quickest path — npx
npx -y @kjadeja/open-featurebase-mcpThis runs the server directly without installing anything. Use this for one-off testing or to confirm the package works on your machine.
To install globally:
npm install -g @kjadeja/open-featurebase-mcpThen point any MCP client at the binary it adds to your PATH:
which open-featurebase-mcp
# /usr/local/bin/open-featurebase-mcp (macOS/Linux)
// or on Windows:
where open-featurebase-mcpRelated MCP server: feedback-mcp
Connecting an MCP client
The setup file format differs across clients — pick the one that matches yours.
Claude Code
The simplest setup is the CLI:
# Use the default Remalt board
claude mcp add --transport stdio --scope user featurebase -- npx -y @kjadeja/open-featurebase-mcp
# Or point at a different board
claude mcp add --transport stdio --scope user --env FEATUREBASE_BOARD_URL=https://example.featurebase.app featurebase -- npx -y @kjadeja/open-featurebase-mcpNative Windows (not WSL)
On native Windows, Claude Code needs cmd /c around local npx MCP servers:
# Use the default Remalt board
claude mcp add --transport stdio --scope user featurebase -- cmd /c npx -y @kjadeja/open-featurebase-mcp
# Or point at a different board
claude mcp add --transport stdio --scope user --env FEATUREBASE_BOARD_URL=https://example.featurebase.app featurebase -- cmd /c npx -y @kjadeja/open-featurebase-mcpFor a project-root .mcp.json on native Windows:
{
"mcpServers": {
"featurebase": {
"command": "cmd",
"args": [
"/c",
"npx",
"-y",
"@kjadeja/open-featurebase-mcp"
],
"env": {
"FEATUREBASE_BOARD_URL": "https://itsremalt.featurebase.app"
}
}
}
}WSL uses the macOS/Linux form with command: "npx".
If you prefer to keep it in a file, use .mcp.json in the project root with the mcpServers (note the camelCase) key:
{
"mcpServers": {
"featurebase": {
"command": "npx",
"args": ["-y", "@kjadeja/open-featurebase-mcp"],
"env": {
"FEATUREBASE_BOARD_URL": "https://itsremalt.featurebase.app"
}
}
}
}Cursor
Cursor uses .cursor/mcp.json in the project root, with the mcpServers key:
{
"mcpServers": {
"featurebase": {
"command": "npx",
"args": ["-y", "@kjadeja/open-featurebase-mcp"],
"env": {
"FEATUREBASE_BOARD_URL": "https://itsremalt.featurebase.app"
}
}
}
}VS Code (GitHub Copilot Chat or other MCP-aware extensions)
VS Code uses .vscode/mcp.json, with a top-level servers (not mcpServers) key:
{
"servers": {
"featurebase": {
"command": "npx",
"args": ["-y", "@kjadeja/open-featurebase-mcp"],
"env": {
"FEATUREBASE_BOARD_URL": "https://itsremalt.featurebase.app"
}
}
}
}Note: The three file formats are NOT interchangeable.
.vscode/mcp.jsonusesservers; Claude Code and Cursor usemcpServers. Copy the exact form above for your editor.
After editing the file, reload the editor so it picks up the new server. The seven tools below will appear in the MCP tools list.
Configuration
Env var | Default | Purpose |
|
| The public Featurebase board to read from. Optional — set this only if you want a different board. |
| (unset) | Comma-separated Featurebase user IDs considered team. Used for admin/customer classification. Optional. |
When team IDs matter
Most tools work without any team configuration — they read posts, comments, search, stats, batch-fetch, and user lookup without knowing who's on the team. Team IDs are only needed when you want to classify authors or detect stalled follow-ups:
Tool | Without team IDs | With team IDs |
| ✅ Works | ✅ Same result |
| ✅ Works; | ✅ Authors classified; engagement fields populated |
| ✅ Works | ✅ Authors classified |
| ✅ Works | ✅ Authors classified |
| ✅ Works | ✅ Same result |
| ✅ Works; | ✅ Same result |
| ❌ Throws | ✅ Filters posts |
| ⚠️ Returns empty with a | ✅ Returns stalled promises |
When a tool requires a team identity and none is configured, it errors out rather than silently fabricate customer / admin assignments. To enable the team-aware tools, either set FEATUREBASE_TEAM_USER_IDS=id1,id2,… in the env, or call find_featurebase_user with your name to discover IDs and pass them as teamUserIds per-call.
Practical prompts
These are the workflows I actually run. Paste them into Claude Code / Cursor after the MCP server is connected.
Daily triage
Show me the top 10 most-upvoted open posts that don't yet have an admin reply. For each one, summarize the request and quote the highest-voted customer comment.
This uses list_featurebase_posts(hasAdminReply=false, status="open", sortBy="upvotes:desc", teamUserIds=[…]) followed by get_featurebase_post for the top entries.
Find stalled follow-ups
Which posts have I (the team) replied to, the customer replied after me, and I haven't said anything in over a week? Show the last 5 by staleness, with the customer's last message quoted.
This is exactly get_featurebase_stalled_promises({ minDaysSinceAdminReply: 7 }).
Detect duplicates
Search the board for "export to CSV" and "download as spreadsheet". Cluster the matches by similarity and tell me which ones look like duplicates I should merge.
This uses search_featurebase_posts for both queries and then a similarity grouping.
Create a GitHub issue from a feature request
Take post
more-byok-options, summarize it as a single-paragraph problem statement, and produce a GitHub-issue-formatted markdown block (title + body) that I can paste into our repo.
The agent reads the post body, formats it, and you paste the result into GitHub.
Voice-of-customer report
Read the 20 most-recent open posts. Group them by theme. For each theme, give me: how many users mentioned it, the total upvotes, and one representative quote.
This uses list_featurebase_posts(status="open", sortBy="date:desc", limit=20) plus per-post comment reads.
Find unanswered posts
List all posts with the
in_progressstatus that have zero admin replies. These are the ones we should respond to first.
This is list_featurebase_posts(hasAdminReply=false, status="in_progress").
Discover your team IDs
Find my user ID on this board. My name is "Krishna".
This uses find_featurebase_user({ name: "Krishna" }). Use the returned IDs as teamUserIds in subsequent calls — no env-var setup needed.
Tools
Seven read-only tools. Each one is designed to be cheap enough to chain — most listing calls don't fetch comments at all unless you ask for engagement.
list_featurebase_posts
Args:
status— one of the friendly names below; the server maps them to the underlyingpostStatus.typevalues returned by the public board:Friendly name
postStatus.typeopenopenin_reviewreviewingplannedunstartedin_progressactivecompletedcompletedThe default
allskips the filter and returns every status.sortBy—date:desc(default),date:asc, orupvotes:desc.limit— 1–200, default 50.hasAdminReply— optional boolean. Requires a team identity (env var orteamUserIdsoverride). If neither is set, the call throwsInvalidParams.teamUserIds— optional string[] override for the team.
Returns: { totalResults, availableResults, truncated, returned, posts: NormalizedPost[] }
Behavior:
A normal listing call (no
hasAdminReply) does not fetch comments and does not populate engagement metadata. It returns posts withauthor.role === "unknown"when no team is configured.When
hasAdminReplyis provided, comments are fetched for posts withcommentCount > 0and engagement is computed under the team. Posts withcommentCount === 0are treated ashasAdminReply: false(the team definitively has not replied) without a comment API request.
get_featurebase_post
Args:
slug— required (e.g.more-byok-options).include_comments— defaultfalse. Whentrue, inlines the full comment thread ascomments: NormalizedComment[].teamUserIds— optional string[] override.
Returns: { ...NormalizedPost, contentHtml, contentText, comments?, commentsError? }
contentHtml and contentText are always inlined. If the comments fetch fails, commentsError is set and the post is still returned.
When teamUserIds is supplied, both comment-author roles and engagement fields are reclassified against that team. A non-empty teamUserIds array replaces FEATUREBASE_TEAM_USER_IDS for that call only; an empty array [] is treated as absent (the env var is used if configured).
get_featurebase_posts (batch)
Args: slugs (1–20), include_content (default false).
Returns posts in the order requested; missing slugs go into notFound rather than throwing. Set include_content=true to inline full body on each entry.
search_featurebase_posts
Args: query (required), limit (1–50, default 10).
Returns posts ordered by relevance (title hit = 3 pts, body hit = 1 pt, per-token matches also weighted).
get_featurebase_stats
Args: topVotedLimit (1–50, default 5), recentLimit (1–50, default 5).
Returns: { totalResults, snapshotSize, truncated, snapshotWindow, statusCountsInSnapshot, categoryCountsInSnapshot, topVoted[N], recent[N] }
snapshotWindow is the actual date range currently in the in-memory snapshot — labels like *InSnapshot are explicit that these counts are over the snapshot, not over a complete board snapshot from a single source. The snapshot is built on demand from the public listing endpoint and is fresh as of the first fetch in the current process.
get_featurebase_stalled_promises
Args:
minDaysSinceAdminReply— 0–365, default 7.limit— 1–50, default 20.teamUserIds— optional string[] override.status— restrict candidates to one of these statuses.sortBy—staleness(default),freshness, orupvotes.
Returns: { minDaysSinceAdminReply, teamSource, warning?, unusedTeamUserIds?, unusedTeamUserIdsComplete?, totalCandidates, returned, promises: StalledPromise[] }
teamSource is "override" (per-call team), "default" (env-var team), or "none" (no team — returns empty with a warning).
unusedTeamUserIds lists IDs you supplied that didn't appear in any comment thread. unusedTeamUserIdsComplete: false signals that some comment fetches failed and we couldn't fully determine unused IDs.
find_featurebase_user
Args: name (≥2 chars, partial match), sampleSize (0–20, default 5).
Returns: { query, samplePostsScanned, commentsComplete, warning?, matches: UserMatch[] }
commentsComplete is true only when every comment fetch for the index build succeeded; false means totals may undercount.
Each UserMatch carries userId, name, postCount, commentCountInSampledPosts, totalCommentCount (board-wide), and guessedRole.
Known limitations
Reads only. Posting comments, voting, changing status all require authenticated access to Featurebase — out of scope.
Designed for public boards. Works on Remalt and on other public boards that expose the same public listing + comment endpoints. Boards with aggressive bot protection, sign-in walls, or non-standard layouts may not work.
No real-time updates. The in-memory snapshot is fresh on first fetch in a given process and cached for 5 minutes. Restart the server to flush.
Admin role tagging requires team IDs. Without
FEATUREBASE_TEAM_USER_IDS(or a per-callteamUserIds), author roles are"unknown"andhasAdminReplyfiltering is refused.
How it works (briefly)
The public board exposes
/api/v1/submission?…&page=N(the SPA's axiosbaseURLis/api). The server calls page 1 to learntotalPagesandtotalResults, then fetches pages 2..N concurrently. Listing pagination is atomic — if any required page fails, the entire tool call surfaces the failure and no partial listing is cached or returned./api/v1/comment?submissionId=<id>&page=Nreturns the comment thread. Comment pagination is also atomic — a single failed page throws and is never cached as a partial thread.Engagement fields (
hasAdminReply, counts, dates) are computed from the classified comment tree. The cache is role-neutral: roles are derived per request against the active team set, never stored on the cached tree.
Troubleshooting
Listing fails with Incomplete listing: failed pages N of M
The listing endpoint returned an error on one or more pages. The tool call surfaces this failure — no partial listing is returned or cached. Retry on the same client will refetch every listing page from scratch. This is by design (atomic contract).
engagementComplete: false in a list_featurebase_posts(hasAdminReply=…) response
Means one or more specific comment-thread fetches failed during engagement enrichment. The response includes failedPostSlugs listing which posts couldn't be classified. Posts that did succeed are still filtered correctly; only the affected posts get commentFetchFailed: true and are excluded from the filter result. Retry the request after a short delay.
commentsComplete: false in find_featurebase_user
At least one post's comments failed to fetch while building the board-wide user-count index. totalCommentCount for users who only appeared in failed threads may undercount. Retry after a short delay.
All author roles show "unknown"
No team is configured. Either set FEATUREBASE_TEAM_USER_IDS in the env, or use find_featurebase_user to discover IDs and pass them as teamUserIds per-call.
hasAdminReply filter throws InvalidParams
You asked for a team-based filter without providing a team. Set FEATUREBASE_TEAM_USER_IDS or pass teamUserIds to the call.
commentsError is set on a get_featurebase_post response
The post is still returned with its body and metadata; only the comments array is missing. Common causes: network error, rate limit, or the comment endpoint returning an unexpected shape.
For contributors
If you want to develop on this:
git clone https://github.com/K-Jadeja/open-featurebase-mcp
cd open-featurebase-mcp
npm ci
npm run build
npm test # 339 deterministic checks; no live network
npm start # launches the stdio serverThe default npm test is fully offline (mock fetcher fixtures). A separate npm run test:live runs against a live Featurebase endpoint and is opt-in.
License
MIT
Available Tools
6 toolsfind_featurebase_userB
Look up user IDs by partial name match.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Partial name to search for, case-insensitive. Minimum 2 characters to avoid matching everything on boards with common one-letter fragments (e.g. 'a' would otherwise surface every user with 'A' in their name). Scans post authors and the comment threads of the N most recent posts with comments. Example: 'Krishna' returns 'Krishna - Remalt Dev' if they've posted or commented on the board. | |
| sampleSize | No | How many recent posts with comments to scan for comment authors. Default 5 (cached comments make this cheap). Set to 0 to skip comment scanning — only post authors will be returned. Max 20. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It only states the basic function, omitting behavioral details like case-insensitivity, scanning scope, or what sampleSize does. The schema provides details, but the description itself is insufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, no fluff. It is appropriately sized for the tool's simplicity, though could slightly expand on behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Lacks return value information (no output schema). Given the tool's simplicity and sibling context, it is incomplete for an agent to fully understand the outcome.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline 3. The description does not add meaning beyond the schema; both parameters are fully described in the schema, so no extra value from the description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('look up') and resource ('user IDs') with a clear method ('partial name match'). It distinguishes itself from sibling tools, which all relate to posts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for user ID lookup without explicit guidance on when to use versus alternatives. Since all siblings are post-related, context is clear, but no exclusions or when-not-to-use are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_featurebase_postB
Get a single post by slug, optionally with full comment thread.
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes | The post slug (the URL path segment after /posts/). Example: 'more-byok-options' | |
| teamUserIds | No | Optional override for the team-user-id set. When provided as a NON-EMPTY array, comments (and engagement fields on the post) are re-classified using these IDs as the team — useful for drilling into a single thread after calling find_featurebase_user. A non-empty override REPLACES the FEATUREBASE_TEAM_USER_IDS env var for this call only. An EMPTY array ([]) is treated as ABSENT — the env var is used if configured. With no env var configured AND no teamUserIds passed, comment authors will show role='unknown' and engagement fields will be omitted. | |
| include_comments | No | If true, fetch and inline the full comment thread as a `comments` array on the response (nested with `replies`). Each comment carries author (name, userId, role='admin'|'customer'|'unknown'), bodyHtml, bodyText, createdAt, updatedAt, upvotes, parentId, and replies[]. On fetch failure the post is still returned with `commentsError` set. Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It only mentions the basic functionality and optional comment inclusion, omitting key behaviors like error handling (e.g., if slug is not found), authorization requirements, or whether it is a read-only operation. The parameter documentation provides some detail but the main description lacks transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence of 16 words, efficiently conveying the core purpose. It is front-loaded and lacks fluff, though it could benefit from an extra sentence about usage context without becoming verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is too minimal given the tool's complexity (3 parameters, no output schema). It does not outline the return structure of the post object or the comments data, leaving the agent to infer from the parameter descriptions. Crucial information like required authentication or possible error responses is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with detailed descriptions for all three parameters. The main description adds only the high-level idea of 'optionally with full comment thread,' which is already implied by the 'include_comments' parameter. Baseline 3 is appropriate as the description adds minimal value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'Get a single post by slug, optionally with full comment thread,' using a specific verb and resource. It clearly distinguishes from sibling tools like 'get_featurebase_posts' (plural) which would fetch multiple posts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for retrieving a specific post given a slug, but it does not explicitly state when to use this tool over alternatives like 'list_featurebase_posts' or 'search_featurebase_posts'. No exclusions or when-not-to-use guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_featurebase_postsA
Batch-fetch multiple posts by slug array.
| Name | Required | Description | Default |
|---|---|---|---|
| slugs | Yes | Array of post slugs to fetch. Returns posts in the order requested. Slugs not in the snapshot are returned in the `notFound` field rather than throwing. | |
| include_content | No | If true, attach full contentHtml + contentText to each post INLINE on posts[i] (mirrors the singular get_featurebase_post shape — same fields, just on each element). Off by default — the 800-char excerpt is usually enough for clustering/dedup work. Turn on only when you need the full body. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses that posts are returned in order requested and that missing slugs are returned in a 'notFound' field rather than throwing. No mention of auth, rate limits, or destructive behavior. Given read-like name, transparency is good but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The main description is a single sentence with no waste. Parameter descriptions are thorough yet concise. Every sentence adds value, effectively balancing brevity with necessary detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema. Description covers ordering and notFound behavior but does not detail the full return structure (e.g., which fields each post object contains). While sibling 'get_featurebase_post' may document shape, the tool alone leaves some gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the description adds significant meaning: for 'slugs', it explains ordering and error handling; for 'include_content', it clarifies when to enable and the trade-off with excerpt length. This exceeds baseline expectations.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states the action 'Batch-fetch', the resource 'posts', and the method 'by slug array'. It clearly distinguishes from sibling tools like 'get_featurebase_post' (singular) and 'list_featurebase_posts' (likely without slugs).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit when-to-use or alternatives mentioned for tool selection. The 'include_content' parameter provides usage guidance (e.g., 'Off by default — the 800-char excerpt is usually enough... Turn on only when you need the full body'), but overall guidance is minimal.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_featurebase_stalled_promisesC
Find posts where admin replied, customer spoke last, admin silent for N+ days.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of stalled promises to return (1-50). Default: 20. | |
| sortBy | No | Sort order for returned stalled promises. 'staleness' (default): customerLastReplyDate desc — most-recent stalled promises first. 'freshness': adminLastReplyDate desc — most-recent admin replies first (catch up on what you just said). 'upvotes': upvotes desc — focus on high-impact items regardless of staleness. | staleness |
| status | No | Restrict candidates to posts with these statuses (e.g. ['in_progress', 'in_review'] to exclude Completed and Planned). When omitted, all statuses are eligible. | |
| teamUserIds | No | Optional override for the team-user-id set. When provided as a NON-EMPTY array, these IDs REPLACE the FEATUREBASE_TEAM_USER_IDS env var for this call only — the env var is ignored. Use this together with find_featurebase_user to run a stalled-promise query without env-var configuration. An EMPTY array ([]) is treated as ABSENT — the env var team is used if configured; otherwise stalled-promises returns immediately with teamSource='none' and a warning. Engagement fields are re-computed on the fly from cached comments using this set. | |
| minDaysSinceAdminReply | No | Minimum number of days since the admin's last reply for a post to qualify as a stalled promise. Default: 7. Set to 0 to surface every post where the customer spoke last, regardless of age. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description must disclose behavioral traits. It only states the high-level purpose. It does not mention how teamUserIds override works, sorting behavior, or any side effects. The schema descriptions compensate, but the tool description itself is insufficient for behavioral transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that is easy to parse and front-loaded. It avoids unnecessary words. However, it could be slightly more structured (e.g., mentioning key parameters like default N days) without losing conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 5 parameters, no output schema, and moderate complexity (team override, sorting, status filter), the one-sentence description is too minimal. It does not explain output format, behavior of the 'N' parameter, or nuance like empty teamUserIds. The description is incomplete for an agent to fully understand the tool's capabilities.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with detailed parameter descriptions. The tool description adds no parameter info beyond what the schema provides. Per rubric, baseline 3 is appropriate since the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool finds posts where admin replied, customer spoke last, and admin is silent for N+ days. It identifies the specific resource (stalled promises) and verb (find). However, it does not explicitly differentiate from sibling tools like list_featurebase_posts or search_featurebase_posts, which could also retrieve posts with conditions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool vs alternatives. The description lacks information about prerequisites (e.g., need for FEATUREBASE_TEAM_USER_IDS env var) or scenarios where this tool is inappropriate. Sibling tool names are listed but not contrasted.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_featurebase_postsB
List posts on the configured Featurebase feedback board.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of posts to return (1-200). | |
| sortBy | No | Sort order for results. | date:desc |
| status | No | Filter by Featurebase status. Values map to underlying postStatus.type as: in_review → 'reviewing', planned → 'unstarted', in_progress → 'active', completed → 'completed', open → 'open'. | all |
| teamUserIds | No | Optional override for the team-user-id set. When provided as a NON-EMPTY array, this list of IDs is treated as the team for hasAdminReply classification, REPLACING the FEATUREBASE_TEAM_USER_IDS env var for this call only. An EMPTY array ([]) is treated as ABSENT — the env var is used if configured, otherwise the request still fails with InvalidParams for hasAdminReply. Useful after a find_featurebase_user drill-down — pass the returned userIds here to filter the listing by team engagement without re-reading the env. | |
| hasAdminReply | No | When true, restrict to posts where the team has authored at least one comment (hasAdminReply === true). When false, restrict to posts where the team has NOT commented. REQUIRES a team identity — if no team is available (FEATUREBASE_TEAM_USER_IDS unset AND no teamUserIds override supplied), the request FAILS with InvalidParams rather than silently returning an empty list. Fabricating hasAdminReply=false for every post would be a silent false-positive for callers asking for hasAdminReply:false, and a silent false-negative for callers asking for hasAdminReply:true. Call find_featurebase_user first to discover user IDs, then pass them as teamUserIds. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, and the description lacks details on behavioral traits such as rate limits, authentication requirements, or potential side effects. It assumes a 'configured' board without explaining setup.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The own description is concise, but extensive parameter details follow. The structure is front-loaded with the core purpose and then detailed parameter info, which is appropriate.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
While parameter documentation is thorough, the description omits output format, pagination details beyond limit, and error scenarios. Given the lack of output schema, more completeness on return values is needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers parameters fully (100% coverage). The description adds significant value by explaining complex behaviors of teamUserIds and hasAdminReply, especially the override logic and error handling.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it lists posts from the configured Featurebase board. However, it does not differentiate from sibling tools like get_featurebase_posts or search_featurebase_posts, which likely have similar listing capabilities.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives. The description does not mention prerequisites, when not to use, or any context for selection among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_featurebase_postsA
Search posts by keyword over title + body.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results to return (1-50). | |
| query | Yes | Keyword or phrase to search for. Matches against post titles (weighted 3x) and bodies (1x). Multi-word queries are tokenized. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the full burden of behavioral disclosure. It states the search scope (title + body), which is helpful, but does not explicitly indicate that the operation is read-only or describe any other behavioral traits. The weighting and tokenization details are in the schema parameter descriptions, but the tool description itself lacks transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence with no filler or extraneous information. Every word contributes to the tool's purpose, making it highly concise and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple search tool with a complete schema, the description covers the core purpose but omits contextual details like result format, sorting, or when to prefer this over other retrieval tools. It is minimally adequate but not fully comprehensive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The tool description adds minimal context ('by keyword over title + body') beyond what the schema already provides (weighting, tokenization). Thus, it meets the baseline but does not significantly enhance understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Search') and the resource ('posts'), and specifies the scope ('by keyword over title + body'). This effectively distinguishes it from sibling tools like list_featurebase_posts (which would list all) and get_featurebase_post (which retrieves by ID).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives (e.g., when to search vs list or get). There is no mention of prerequisites, context, or when not to use it, leaving the agent with insufficient decision-making information.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v1.0.2- First observed
find_featurebase_user - First observed
get_featurebase_post - First observed
get_featurebase_posts - First observed
get_featurebase_stalled_promises - First observed
list_featurebase_posts - First observed
search_featurebase_posts
TDQS
Scored across 6 tools
Each tool has a clearly distinct purpose: batch fetch by slugs, list all, get single, search, find stalled promises, and user lookup. No overlap in functionality.
All tools follow a verb_featurebase_noun pattern, but verbs like 'get' are used for multiple actions (batch, single, stalled promises) and 'find' vs 'search' introduces minor inconsistency.
Six tools is well-scoped for a Featurebase integration, covering core read operations and a specialized query without being overwhelming or insufficient.
The tool set covers reading and searching well, but lacks any write operations (create, update, delete) for posts or comments, which are typical for a feedback board.
Maintenance
Related MCP Connectors
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
- SupabaseOAuthcom.supabase
MCP server for interacting with the Supabase platform
Public, read-only MCP server for FarmNeural company facts, packages, and capabilities.
- mcpOAuthcom.airtable
Official Airtable MCP server — database and operations layer for agents.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceMCP server for Stack Overflow for Agents, enabling search, post creation, voting, and knowledge exchange for AI agents.Apache 2.0
- AlicenseNot gradedqualityAmaintenanceMCP server for Open Feedback, enabling AI assistants to submit, list, get, update status of, and analyze product feedback via a local HTTP API and JSONL storage.346 npmApache 2.0
- FlicenseNot gradedqualityBmaintenanceAgent-native MCP server for a tiny social feed of technical founders. Enables read, post, reply, react, and agent collaboration features like catching up, trading conviction, and managing tracks.-

featurejet-mcpofficial
AlicenseNot gradedqualityCmaintenanceOfficial MCP server for FeatureJet, enabling agents to read and act on customer feedback boards: list/search posts, file feature requests, and pull top-voted planned items.MIT