Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions .github/ISSUE_TEMPLATE/plugin-submit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ body:
- type: markdown
attributes:
value: |
A SurfSense plugin is a remote MCP server: Streamable HTTP, on HTTPS. Fill this in and a bot checks your server the way the app connects to it, then comments with the entry it makes or what to fix. Edit the issue to fix anything; the checks run again on every edit. Nothing here needs git.
Fill this in and a bot checks your server, then comments with what to fix or what happens next. To fix something, edit the issue and it checks again.

Nothing needs checking first. To see your tools yourself anyway, `npx @modelcontextprotocol/inspector` or the desktop app's **Settings → Plugins → Add custom plugin** both work.
**We support** remote MCP servers on a public HTTPS address:
- **Transport:** Streamable HTTP, or the older HTTP+SSE.
- **Sign-in:** none, a key each user pastes, or OAuth.

Local (stdio) servers can't be listed yet.

**Never put a key, token or password in this issue.** If a reviewer needs to sign in, say so below and a maintainer will arrange it with you.
- type: input
id: name
attributes:
Expand Down Expand Up @@ -39,7 +42,7 @@ body:
id: description
attributes:
label: One-line description
description: The line on your plugin's card. Up to 200 characters.
description: The line on your plugin's page. Up to 200 characters.
placeholder: Search and read Acme's public documentation.
validations:
required: true
Expand Down Expand Up @@ -72,8 +75,8 @@ body:
attributes:
label: Who can use it
options:
- Free for anyone
- Needs an account or subscription the publisher sells
- Free (a free account is fine)
- "Paid: users need a plan or subscription you sell"
validations:
required: true
- type: input
Expand All @@ -86,7 +89,7 @@ body:
id: tools
attributes:
label: Tool names
description: Every tool your server offers, one per line, as users will see them on your plugin's public page. Include the ones that appear only after sign-in.
description: The name of every tool your server has, one per line, including the ones it lists only after sign-in. The plugin's page shows them.
placeholder: |
search_docs
read_page
Expand All @@ -110,5 +113,5 @@ body:
attributes:
label: Before you send
options:
- label: I removed every key, token and password from this issue.
- label: There's no key, token or password in this issue.
required: true
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
TOOLS,
PROMPT,
)
FREE = "Free for anyone"
PAID = "Needs an account or subscription the publisher sells"
FREE = "Free (a free account is fine)"
PAID = "Paid: users need a plan or subscription you sell"

_HEADING = re.compile(r"^### (.+?)\s*$", re.MULTILINE)
_BLANK = "_No response_"
Expand Down
5 changes: 2 additions & 3 deletions plugins/registry/check/tests/submission_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"Privacy policy URL": "https://acme.example/privacy",
"Homepage": "https://acme.example",
"Icon": "https://acme.example/icon.svg",
"Who can use it": "Free for anyone",
"Who can use it": "Free (a free account is fine)",
"Tool names": "search_docs\nread_page",
"A prompt to try": "What do Acme's docs say about rate limits?",
}
Expand All @@ -30,8 +30,7 @@ def issue_body(**changes: str | None) -> str:
for label, value in answers.items()
]
sections.append(
"### Before you send\n\n"
"- [X] I removed every key, token and password from this issue."
"### Before you send\n\n- [X] There's no key, token or password in this issue."
)
return "\n\n".join(sections) + "\n"

Expand Down
7 changes: 5 additions & 2 deletions plugins/registry/check/tests/test_issue_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,8 @@ def test_every_question_the_intake_reads_is_on_the_form():

def test_both_access_choices_are_offered():
text = TEMPLATE.read_text(encoding="utf-8")
assert f"- {form.FREE}\n" in text
assert f"- {form.PAID}\n" in text
# A choice with a colon in it is quoted, or YAML reads it as a mapping.
choices = {
c.strip('"') for c in re.findall(r"^ - (.+)$", text, re.MULTILINE)
}
assert {form.FREE, form.PAID} <= choices
4 changes: 2 additions & 2 deletions plugins/registry/check/tests/test_submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def test_a_server_taking_a_key_asks_the_submitter_nothing_about_it(tmp_path):


def test_a_paid_plugin_says_what_users_must_buy(tmp_path):
paid = "Needs an account or subscription the publisher sells"
paid = "Paid: users need a plan or subscription you sell"
found = check(tmp_path, issue_body(Who_can_use_it=paid))
assert any(p.startswith("What users must buy or have: ") for p in found.problems)

Expand Down Expand Up @@ -130,7 +130,7 @@ async def fetch(url: str) -> bytes:


def test_without_the_box_ticked_nothing_is_contacted(tmp_path):
body = issue_body().replace("- [X] I removed", "- [ ] I removed")
body = issue_body().replace("- [X] There's no key", "- [ ] There's no key")

async def never(url: str):
raise AssertionError("contacted")
Expand Down
Loading