Skip to content
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

feat: MCP server implementation #1

Merged
merged 54 commits into from
Jan 16, 2025
Merged

feat: MCP server implementation #1

merged 54 commits into from
Jan 16, 2025

Conversation

jirispilka
Copy link
Collaborator

@jirispilka jirispilka commented Jan 10, 2025

Future work

  • document LibreChat client
  • provide examples with superinterface.ai
  • add tools dynamically

FYI: @vystrcild @MQ37

@jirispilka jirispilka self-assigned this Jan 10, 2025
@jirispilka jirispilka requested a review from fnesveda January 13, 2025 07:52
Copy link
Member

@fnesveda fnesveda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool! Very cool usage of a Standby Actor. I had a few comments, if you want, we can discuss the Standby architecture tomorrow in the office 🙂

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved

The Actor runs in [**Standby mode**](https://docs.apify.com/platform/actors/running/standby) with an HTTP web server that receives and processes requests.

Start server with default Actors. To use the Apify MCP Server with set of default Actors,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit problematic, Actor Standby doesn't have a concept of "starting a server". It just starts an Actor run when it receives the first requests to its Standby URL, the run will run until the idle timeout, and then it's shut down. So with this scenario this could happen:

  1. user "starts" the Actor with specified Actors through the ?actors=... parameter
  2. user uses the MCP server on the /sse path, everything works
  3. user waits a bit, Actor run started in 1 gets shut down
  4. user tries to use the MCP server again, but now it's not "started", and the specific Actors are not loaded

Or, if the user uses the MCP server a lot, an additional run is started to handle the requests, and that is not prepared with the specific Actors.

It also doesn't give the user an option how to load different Actors after the run is started.

What would work is one of these two options:

  • specify Actors in every request to the /sse endpoint
  • specify Actors in the Standby Actor input, and when users would want to use different Actors in the MCP server, they'd create an Actor task which would override the Actor input, and use the task's standby URL instead of the Actor standby URL

Copy link
Collaborator Author

@jirispilka jirispilka Jan 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohhh 💡, this didn't occur to me. Thanks Franto!

specify Actors in every request to the /sse endpoint

This is a bit problematic as it depends on the MCP client (e.g., Claude Desktop, LibreChat). These clients do not pass parameters to the SSE endpoint

specify Actors in the Standby Actor input, and when users would want to use different Actors in the MCP server, they'd create an Actor task which would override the Actor input, and use the task's standby URL instead of the Actor standby URL

This seems to be the easiest and quickest solution.

There is one more option.

  • The MCP server can dynamically load Actors. Basically, based on the use case, the MCP will include a tool to search for Actors and "load" them (i.e., add them as a tool). I've already experimented with this in the [feat/internal-tools]() branch. It "works", but I encountered some issues and haven’t had much time to fix them yet.

README.md Outdated Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
Comment on lines 30 to 32
// Extract default build label
const tag = actor.defaultRunOptions?.build || '';
const buildId = actor.taggedBuilds?.[tag]?.buildId || '';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default build is not necessarily tagged, you can specify any build number as default build.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, let's discuss this tomorrow

dotenv.config({ path: '../../.env' });

const SERVER_PATH = '../../dist/index.js';
const NODE_PATH = execSync('which node').toString().trim();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this work on Windows?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, I was too lazy. I'll fix it

@jirispilka
Copy link
Collaborator Author

Major changes since the last review:

  • The Standby Actor now starts with default Actors. To use a different set of Actors, a task must be created.
  • Fixed relative path for Windows.
  • Attempted to implement clientSse.ts to replace the need for Python but encountered issues with it.
  • Renamed the environment variable APIFY_API_TOKEN to APIFY_TOKEN (as used on the platform).
  • Limited the size of responses for a tool.

@jirispilka jirispilka requested a review from fnesveda January 15, 2025 15:46
Copy link
Member

@fnesveda fnesveda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool! Two small suggestions, but nothing major.

.actor/input_schema.json Outdated Show resolved Hide resolved
src/main.ts Outdated Show resolved Hide resolved
@jirispilka jirispilka merged commit 5e2c9f0 into master Jan 16, 2025
2 checks passed
@jirispilka jirispilka deleted the feat/implementation branch January 21, 2025 14:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants