https://github.com/willitscale/streetlamp-ai
Attribute router tooling for AI solutions
https://github.com/willitscale/streetlamp-ai
ai composer composer-package http mcp php php84 router
Last synced: 7 months ago
JSON representation
Attribute router tooling for AI solutions
- Host: GitHub
- URL: https://github.com/willitscale/streetlamp-ai
- Owner: willitscale
- Created: 2025-07-17T00:31:38.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2025-09-02T00:20:57.000Z (7 months ago)
- Last Synced: 2025-09-02T02:30:52.743Z (7 months ago)
- Topics: ai, composer, composer-package, http, mcp, php, php84, router
- Language: PHP
- Homepage:
- Size: 71.3 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.MD
Awesome Lists containing this project
README
# Streetlamp AI
Attribute router tooling for AI solutions. A support framework for rapidly building MCP servers using attributes in PHP.
## Table of Contents
- [Getting Started](#getting-started)
- [Defining your MCP Server](#defining-your-mcp-server)
- [Defining Capabilities](#defining-the-mcp-capabilities-and-sub-capabilities)
- [Defining Method Actions](#defining-method-actions)
- [Usage Example](#usage-example)
## Prerequisites
- PHP 8.4 or higher
- Composer
# Getting started
To begin with you're going to need to add Streetlamp AI to your composer package with:
```bash
composer require willitscale/streetlamp-ai
```
This will include Streetlamp and Streetlamp AI into your package.
# Creating your first MCP Server
I'd advise you to read through the documentation for [Streetlamp](https://github.com/willitscale/streetlamp) and getting a Streetlamp application up and running first.
I'm going to skip what's covered in the Streetlamp documentation for getting setup.
## Defining our MCP Server
What we need to do first is to define our server, we can do this with the attribute `ModelContextProtocol` which will bootstrap an MCP server for us at the defined path provided.
The class we decorate with the `ModelContextProtocol` can have middleware applied to it as shown below.
```php
#[ModelContextProtocol('/mcp', McpVersion::LATEST, 'Streetlamp', '1.0.0', 'Client information')]
#[Middleware(AuthMiddleware::class)]
class McpController
{
}
```
Unlike a standard controller within Streetlamp the requests are passed off to a catch-all method within the `McpHandler`.
If you would like to handle all requests yourself you can do so by extending the `McpHandler` and overriding the `call` method as shown below.
```php
#[ModelContextProtocol('/mcp', McpVersion::LATEST, 'Streetlamp', '1.0.0', 'Client information')]
#[Middleware(AuthMiddleware::class)]
class McpController extends McpHandler
{
public function call(
#[BodyParameter] Request $request,
#[HeaderParameter('Accept', true)] string $accept,
#[HeaderParameter('MCP-Protocol-Version', true)] string $mcpProtocolVersion,
#[HeaderParameter('MCP-Session-Id')] ?string $mcpSessionId = null
): ResponseInterface {
...
}
}
```
## Defining the MCP Capabilities and Sub-Capabilities
With the server defined we now need to define what capabilities our server will offer.
We define capabilities by decorating a class with the `McpCapability` attribute and the corresponding capability.
Within out capabilities we can also define sub-capabilities by decorating a function with the attribute `McpSubCapability` to be used as a callback for that sub-capability.
```php
#[McpCapability(McpCapabilities::RESOURCES)]
class ResourcesCapability
{
#[McpSubCapability(McpSubCapabilities::SUBSCRIBE)]
public function subscribe(): mixed
{
...
}
}
```
I'd advise to read through the [MCP Specification](https://modelcontextprotocol.io/specification/2025-06-18) to understand how to respond correctly to MCP clients.
## Defining Method Actions
When making requests to the MCP server you do so via JsonRpc requests which require a method.
This method gets mapped to a capability and then an action within that capability.
To define an action you decorate a method within a capability with the `McpAction` attribute as shown below.
```php
#[McpCapability(McpCapabilities::RESOURCES)]
class ResourcesCapability
{
#[McpAction('list')]
public function resources(): array
{
return [
'resources' => [
...
]
];
}
#[McpAction('read')]
public function resources(): array
{
return [
'contents' => [
...
]
];
}
#[McpAction('templates/list')]
public function resources(): array
{
return [
'resourceTemplates' => [
...
]
];
}
}
```
Responses from the action function calls are wrapped in the JsonRpc `Response` object as the result.