Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
Acumen-Desktop committed Feb 9, 2025
2 parents 3e9bd41 + 69ea1d3 commit 370c64c
Show file tree
Hide file tree
Showing 6 changed files with 316 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ resolver = "2"

[workspace.package]
edition = "2021"
version = "1.0.4"
version = "1.0.5"
authors = ["Block <[email protected]>"]
license = "Apache-2.0"
repository = "https://github.com/block/goose"
Expand Down
2 changes: 1 addition & 1 deletion crates/goose-cli/src/commands/configure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ pub async fn configure_provider_dialog() -> Result<bool, Box<dyn Error>> {
spin.start("Checking your configuration...");

// Use max tokens to speed up the provider test.
let model_config = goose::model::ModelConfig::new(model.clone()).with_max_tokens(Some(10));
let model_config = goose::model::ModelConfig::new(model.clone()).with_max_tokens(Some(50));
let provider = create(provider_name, model_config)?;

let messages =
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
311 changes: 311 additions & 0 deletions documentation/docs/tutorials/fetch-mcp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,311 @@
---
title: Fetch Extension
description: Add Fetch MCP Server as a Goose Extension
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';


This tutorial covers how to add the [Fetch MCP Server](https://github.com/modelcontextprotocol/servers/tree/main/src/fetch) as a Goose extension to retrieve and process content from the web.


:::tip TLDR

**Command**
```sh
uvx mcp-server-fetch
```
:::


## Configuration

<Tabs groupId="interface">
<TabItem value="cli" label="Goose CLI" default>
1. Run the `configure` command:
```sh
goose configure
```

2. Choose to add a `Command-line Extension`
```sh
┌ goose-configure
◇ What would you like to configure?
│ Add Extension
◆ What type of extension would you like to add?
│ ○ Built-in Extension
// highlight-start
│ ● Command-line Extension (Run a local command or script)
// highlight-end
│ ○ Remote Extension
```

3. Give your extension a name
```sh
┌ goose-configure
◇ What would you like to configure?
│ Add Extension
◇ What type of extension would you like to add?
│ Command-line Extension
// highlight-start
◆ What would you like to call this extension?
│ fetch
// highlight-end
```

4. Enter the command
```sh
┌ goose-configure
◇ What would you like to configure?
│ Add Extension
◇ What type of extension would you like to add?
│ Command-line Extension
◇ What would you like to call this extension?
│ fetch
// highlight-start
◆ What command should be run?
│ uvx mcp-server-fetch
// highlight-end
```

5. Choose No when asked to add environment variables

```sh
┌ goose-configure
◇ What would you like to configure?
│ Add Extension
◇ What type of extension would you like to add?
│ Command-line Extension
◇ What would you like to call this extension?
│ fetch
◇ What command should be run?
│ uvx mcp-server-fetch
// highlight-start
◇ Would you like to add environment variables?
│ No
// highlight-end
└ Added fetch extension
```

</TabItem>
<TabItem value="ui" label="Goose Desktop">
1. Go to the [Extensions Directory](https://block.github.io/goose/v1/extensions/)
2. Find the `Fetch` extension
3. Click `Install`
4. Press `Yes` to confirm the installation
</TabItem>
</Tabs>

## Example Usage

Let's use the Fetch extension to get random programming jokes from the [Official Joke API](https://official-joke-api.appspot.com/random_joke).

:::info
While this API does not require an API key, many APIs do. If you need to provide an API key, you can set it as an environment variable and tell Goose its name. Example: _"get tomorrow's weather for New Orleans from the weatherapi. Don't use the key directly but instead use a script that gets the value from the env var WEATHER_API_KEY"_
:::

### Goose Prompt
```
make a web page that tells jokes for programmers. The page should ask the user the setup of the joke, allow them to guess the punchline and then tell them if they are right or wrong. Include a button that allows them to request another joke. you can fetch the jokes from the official joke api
```

### Goose Output

```
I'll help you create a web page that uses the Official Joke API to display programming jokes. I'll break this down into steps:
First, let's verify the API endpoint and see what kind of data we get
Then create an HTML file with the necessary structure
Add JavaScript to handle the interactions
Let me check the API first:
FETCH
url: https://official-joke-api.appspot.com/jokes/programming/random
Output
Content type application/json; charset=utf-8 cannot be simplified to markdown, but here is the raw content:
Contents of https://official-joke-api.appspot.com/jokes/programming/random:
[{"type":"programming","setup":"A SQL query walks into a bar, walks up to two tables and asks...","punchline":"'Can I join you?'","id":23}]
Perfect! Now I'll create an HTML file with the necessary structure and JavaScript code:
TEXT_EDITOR
command: write
file_text:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="U...
path:
programmer_jokes.html
Output
programmer_jokes.html
[... contents of programmer_jokes.html ...]
I've created a complete web page that:
Fetches random programming jokes from the Official Joke API
Shows the setup of the joke
Provides an input field for users to guess the punchline
Shows whether they got it right or wrong
Displays the actual punchline after they guess
Includes a button to get another joke
The page also includes:
Clean, modern styling
Error handling for API failures
Responsive design that works on both desktop and mobile
Visual feedback for correct/incorrect answers
Disabled input after guessing to prevent multiple attempts
You can open the file programmer_jokes.html in your web browser to try it out. Would you like me to help you test it or make any adjustments to the design or functionality?
```

### Results

![website goose built](../assets/guides/programmer-jokes-fetch-mcp.png)

<details>
<summary>Source Code</summary>

```html title="programmer_jokes.html"

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Programmer Jokes</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
text-align: center;
}
.container {
background-color: #f5f5f5;
padding: 20px;
border-radius: 10px;
margin-top: 20px;
}
.setup {
font-size: 1.2em;
margin-bottom: 20px;
}
.guess-container {
margin-bottom: 20px;
}
#guessInput {
padding: 10px;
width: 300px;
margin-right: 10px;
}
button {
padding: 10px 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
.result {
margin-top: 20px;
font-weight: bold;
}
.correct {
color: green;
}
.incorrect {
color: red;
}
#punchline {
display: none;
margin-top: 20px;
font-style: italic;
}
</style>
</head>
<body>
<h1>Programmer Jokes</h1>
<div class="container">
<div id="setup" class="setup">Loading joke...</div>
<div class="guess-container">
<input type="text" id="guessInput" placeholder="Guess the punchline...">
<button onclick="checkGuess()">Submit Guess</button>
</div>
<div id="result" class="result"></div>
<div id="punchline"></div>
<button onclick="getNewJoke()" style="margin-top: 20px;">Get Another Joke</button>
</div>

<script>
let currentJoke = null;
async function getNewJoke() {
try {
const response = await fetch('https://official-joke-api.appspot.com/jokes/programming/random');
const jokes = await response.json();
currentJoke = jokes[0];
document.getElementById('setup').textContent = currentJoke.setup;
document.getElementById('guessInput').value = '';
document.getElementById('result').textContent = '';
document.getElementById('punchline').style.display = 'none';
document.getElementById('guessInput').disabled = false;
} catch (error) {
document.getElementById('setup').textContent = 'Error loading joke. Please try again.';
}
}
function checkGuess() {
const guess = document.getElementById('guessInput').value.trim().toLowerCase();
const punchline = currentJoke.punchline.toLowerCase();
const resultElement = document.getElementById('result');
const punchlineElement = document.getElementById('punchline');
if (guess === punchline) {
resultElement.textContent = 'Correct! You got it! 🎉';
resultElement.className = 'result correct';
} else {
resultElement.textContent = 'Not quite! Here\'s the punchline:';
resultElement.className = 'result incorrect';
}
punchlineElement.textContent = currentJoke.punchline;
punchlineElement.style.display = 'block';
document.getElementById('guessInput').disabled = true;
}
// Load first joke when page loads
getNewJoke();
</script>
</body>
</html>
```

</details>
4 changes: 2 additions & 2 deletions ui/desktop/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ui/desktop/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "goose-app",
"productName": "Goose",
"version": "1.0.4",
"version": "1.0.5",
"description": "Goose App",
"main": ".vite/build/main.js",
"scripts": {
Expand Down

0 comments on commit 370c64c

Please sign in to comment.