-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Add inline python extension #3107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Add InlinePython variant to ExtensionConfig - Add support for Python dependencies in uvx execution - Add example recipe and test for word counting - Update documentation with inline Python examples
- Add temp_dirs field to ExtensionManager to store TempDir instances - Store temp dir when creating inline Python extension - Clean up temp dir when removing extension
|
This should work: version: "1.0.0"
title: "Word Counter"
description: "A recipe that counts words in text using an inline Python extension"
instructions: |
This recipe provides a simple word counting tool. You can:
1. Count words in a text string
2. Get statistics about the text (unique words, average word length)
3. Generate word clouds from the text
parameters:
- key: text
input_type: string
requirement: required
description: "The text to analyze"
extensions:
- type: inline_python
name: word_counter
code: |
from mcp.server.fastmcp import FastMCP
import json
from collections import Counter
import numpy as np
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import base64
from io import BytesIO
mcp = FastMCP("word_counter")
@mcp.tool()
def count_words(text: str) -> str:
"""Count the number of words in a text string and generate statistics"""
words = text.split()
word_count = len(words)
unique_words = len(set(words))
avg_length = sum(len(word) for word in words) / word_count if word_count > 0 else 0
# Generate word cloud
wordcloud = WordCloud(width=800, height=400, background_color='white').generate(text)
# Save word cloud to base64
plt.figure(figsize=(10, 5))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
# Save to bytes
buf = BytesIO()
plt.savefig(buf, format='png', bbox_inches='tight', pad_inches=0)
buf.seek(0)
img_base64 = base64.b64encode(buf.getvalue()).decode()
plt.close()
result = {
"total_words": word_count,
"unique_words": unique_words,
"average_word_length": round(avg_length, 2),
"most_common": dict(Counter(words).most_common(5)),
"wordcloud_base64": img_base64
}
return json.dumps(result, indent=2)
if __name__ == "__main__":
mcp.run()
timeout: 300
description: "Count words and provide text statistics with visualization"
dependencies:
- "mcp"
- "numpy"
- "matplotlib"
- "wordcloud"
- "beautifulsoup4"
- "html2text"
- "requests"
prompt: |
You are a helpful assistant that can analyze text using word counting tools.
The user has provided the following text to analyze: {{ text }}
Use the word_counter__count_words tool to analyze this text and provide insights about:
- Total word count
- Number of unique words
- Average word length
- Most commonly used words
- A word cloud visualization of the text |
|
diabolically good - I love it. And security reasons why this is a bad idea? |
I think this can actually pave the ways to make things more secure - if you have a recipe that refers to an MCP server that is unsigned (as they all are today) and then you accept the recipe, the author of the MCP server could change the implementation and do bad things. here are least you see what is actually happening. I don't think it makes recipes less save, but very save they are not to begin with |
|
assigned to you @michaelneale |
|
updated this to main and had to make some other changes for new typechecks and openapi. @DOsinga wasn't able to run that example, having trouble speaking ie it was trying to do python - but failing I guess once it is bootstrapping from the python-mcp side of things? |
was this with Warp on or off? we should probably do better with MCP error handling here (maybe the new version will anyway) |
|
@DOsinga with it on - with it off I got another error which was clearer (usually I can run uv things - didn't quite follow this error). Am ok with merging this though as I think it should work - just not sure how reliable in the face of dependencies/registries (but small risk) |
* main: (25 commits) fix: add maintainer, homepage and categories to DEB/RPM package config (#3096) blog: agent to agent convo (#3677) Possible to disable random thinking messages (#3304) Two VS code tutorials (#3603) small blog fixes (#3549) docs: fix installation command for YouTube Transcript MCP in servers.json (#3595) Docs for using Docker Model Runner as a local LLM provider. (#3509) Docs: VS Code Extension move to tutorials (#3601) Fix working directory when session has no messages (#3513) goose docs MCP server (#3665) Remove confusing status output when testing sharing url connection and it shows 404 (#3659) chore: use typed notifications from rmcp (#3653) feat: convert GetPromptResult from mcp_core to rmcp version (#3650) feat: Replace usage of mcp_core Tools/ToolAnnotations in openapi schema (#3649) fix: ensure execution task result is shown (#3629) docs: Quick spotlight fix (#3633) alexhancock/rmcp-tools-annotations (#3617) fix: clean up subagent (#3565) Adds the `WaitingForUserInput` state (#3620) docs: update extensions library (#3612) ...
* main: (27 commits) Add inline python extension (#3107) fix: add maintainer, homepage and categories to DEB/RPM package config (#3096) blog: agent to agent convo (#3677) Possible to disable random thinking messages (#3304) Two VS code tutorials (#3603) small blog fixes (#3549) docs: fix installation command for YouTube Transcript MCP in servers.json (#3595) Docs for using Docker Model Runner as a local LLM provider. (#3509) Docs: VS Code Extension move to tutorials (#3601) Fix working directory when session has no messages (#3513) goose docs MCP server (#3665) Remove confusing status output when testing sharing url connection and it shows 404 (#3659) chore: use typed notifications from rmcp (#3653) feat: convert GetPromptResult from mcp_core to rmcp version (#3650) feat: Replace usage of mcp_core Tools/ToolAnnotations in openapi schema (#3649) fix: ensure execution task result is shown (#3629) docs: Quick spotlight fix (#3633) alexhancock/rmcp-tools-annotations (#3617) fix: clean up subagent (#3565) Adds the `WaitingForUserInput` state (#3620) ...
* main: (69 commits) Add inline python extension (#3107) fix: add maintainer, homepage and categories to DEB/RPM package config (#3096) blog: agent to agent convo (#3677) Possible to disable random thinking messages (#3304) Two VS code tutorials (#3603) small blog fixes (#3549) docs: fix installation command for YouTube Transcript MCP in servers.json (#3595) Docs for using Docker Model Runner as a local LLM provider. (#3509) Docs: VS Code Extension move to tutorials (#3601) Fix working directory when session has no messages (#3513) goose docs MCP server (#3665) Remove confusing status output when testing sharing url connection and it shows 404 (#3659) chore: use typed notifications from rmcp (#3653) feat: convert GetPromptResult from mcp_core to rmcp version (#3650) feat: Replace usage of mcp_core Tools/ToolAnnotations in openapi schema (#3649) fix: ensure execution task result is shown (#3629) docs: Quick spotlight fix (#3633) alexhancock/rmcp-tools-annotations (#3617) fix: clean up subagent (#3565) Adds the `WaitingForUserInput` state (#3620) ...
…cn/compact2-task-tracking * 'dkatz/goose-compact2' of github.com:block/goose: (22 commits) rm stray files unused fmt fix threshold autocompact splice last message fmt Fix conversations before they hit the LLM (#3660) cli: add detailed instruction for WSL users (#3496) feat: recipe runs will now prompt for missing extension secrets (#3668) fix: pricing integration tests -> trying more runs for cache and retries (#3546) Add inline python extension (#3107) fix: add maintainer, homepage and categories to DEB/RPM package config (#3096) blog: agent to agent convo (#3677) Possible to disable random thinking messages (#3304) Two VS code tutorials (#3603) small blog fixes (#3549) docs: fix installation command for YouTube Transcript MCP in servers.json (#3595) Docs for using Docker Model Runner as a local LLM provider. (#3509) Docs: VS Code Extension move to tutorials (#3601) Fix working directory when session has no messages (#3513) ...
* dkatz/goose-compact2: (22 commits) rm stray files unused fmt fix threshold autocompact splice last message fmt Fix conversations before they hit the LLM (#3660) cli: add detailed instruction for WSL users (#3496) feat: recipe runs will now prompt for missing extension secrets (#3668) fix: pricing integration tests -> trying more runs for cache and retries (#3546) Add inline python extension (#3107) fix: add maintainer, homepage and categories to DEB/RPM package config (#3096) blog: agent to agent convo (#3677) Possible to disable random thinking messages (#3304) Two VS code tutorials (#3603) small blog fixes (#3549) docs: fix installation command for YouTube Transcript MCP in servers.json (#3595) Docs for using Docker Model Runner as a local LLM provider. (#3509) Docs: VS Code Extension move to tutorials (#3601) Fix working directory when session has no messages (#3513) ...
Co-authored-by: Douwe Osinga <[email protected]> Co-authored-by: Michael Neale <[email protected]> Signed-off-by: Adam Tarantino <[email protected]>
This makes it possible to have python code inside of a recipe